Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
authorDavid S. Miller <davem@davemloft.net>
Wed, 19 Nov 2008 07:38:23 +0000 (23:38 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 19 Nov 2008 07:38:23 +0000 (23:38 -0800)
Conflicts:

drivers/isdn/i4l/isdn_net.c
fs/cifs/connect.c

915 files changed:
Documentation/RCU/rculist_nulls.txt [new file with mode: 0644]
Documentation/feature-removal-schedule.txt
Documentation/networking/README.ipw2200
Documentation/networking/bonding.txt
Documentation/networking/dccp.txt
Documentation/networking/ip-sysctl.txt
Documentation/networking/regulatory.txt
Documentation/rfkill.txt
MAINTAINERS
arch/arm/mach-ixp4xx/fsg-setup.c
arch/arm/mach-ixp4xx/nas100d-setup.c
arch/arm/mach-ixp4xx/nslu2-setup.c
arch/sparc64/kernel/idprom.c
arch/um/drivers/net_kern.c
arch/xtensa/platforms/iss/network.c
drivers/firmware/iscsi_ibft.c
drivers/infiniband/core/sysfs.c
drivers/infiniband/hw/mthca/mthca_mcg.c
drivers/infiniband/hw/nes/nes.c
drivers/infiniband/hw/nes/nes_cm.c
drivers/infiniband/hw/nes/nes_nic.c
drivers/infiniband/hw/nes/nes_utils.c
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/infiniband/ulp/iser/iser_verbs.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/isdn/i4l/isdn_net.c
drivers/isdn/i4l/isdn_net.h
drivers/media/dvb/b2c2/flexcop.c
drivers/media/dvb/bt8xx/dst.c
drivers/media/dvb/dm1105/dm1105.c
drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
drivers/media/dvb/pluto2/pluto2.c
drivers/message/fusion/mptlan.c
drivers/net/3c501.c
drivers/net/3c503.c
drivers/net/3c505.c
drivers/net/3c507.c
drivers/net/3c509.c
drivers/net/3c515.c
drivers/net/3c523.c
drivers/net/3c527.c
drivers/net/3c59x.c
drivers/net/7990.c
drivers/net/8139cp.c
drivers/net/8139too.c
drivers/net/82596.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/a2065.c
drivers/net/ac3200.c
drivers/net/acenic.c
drivers/net/amd8111e.c
drivers/net/apne.c
drivers/net/appletalk/cops.c
drivers/net/appletalk/ipddp.c
drivers/net/appletalk/ltpc.c
drivers/net/arcnet/arc-rawmode.c
drivers/net/arcnet/arc-rimi.c
drivers/net/arcnet/arcnet.c
drivers/net/arcnet/capmode.c
drivers/net/arcnet/com20020-isa.c
drivers/net/arcnet/com20020-pci.c
drivers/net/arcnet/com20020.c
drivers/net/arcnet/com90io.c
drivers/net/arcnet/com90xx.c
drivers/net/arcnet/rfc1051.c
drivers/net/arcnet/rfc1201.c
drivers/net/ariadne.c
drivers/net/arm/am79c961a.c
drivers/net/arm/at91_ether.c
drivers/net/arm/ep93xx_eth.c
drivers/net/arm/ether1.c
drivers/net/arm/ether3.c
drivers/net/arm/etherh.c
drivers/net/arm/ixp4xx_eth.c
drivers/net/at1700.c
drivers/net/atarilance.c
drivers/net/atl1e/atl1e_main.c
drivers/net/atlx/atl1.c
drivers/net/atlx/atl1.h
drivers/net/atlx/atl2.c
drivers/net/atlx/atl2.h
drivers/net/atlx/atlx.c
drivers/net/atp.c
drivers/net/au1000_eth.c
drivers/net/ax88796.c
drivers/net/b44.c
drivers/net/bfin_mac.c
drivers/net/bmac.c
drivers/net/bnx2.c
drivers/net/bnx2.h
drivers/net/bnx2x_main.c
drivers/net/bonding/Makefile
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_3ad.h
drivers/net/bonding/bond_alb.c
drivers/net/bonding/bond_ipv6.c [new file with mode: 0644]
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_sysfs.c
drivers/net/bonding/bonding.h
drivers/net/cassini.c
drivers/net/chelsio/cxgb2.c
drivers/net/chelsio/sge.c
drivers/net/cpmac.c
drivers/net/cris/eth_v10.c
drivers/net/cs89x0.c
drivers/net/cxgb3/cxgb3_main.c
drivers/net/cxgb3/sge.c
drivers/net/de600.c
drivers/net/de620.c
drivers/net/declance.c
drivers/net/defxx.c
drivers/net/depca.c
drivers/net/dl2k.c
drivers/net/dm9000.c
drivers/net/e100.c
drivers/net/e1000/e1000_main.c
drivers/net/e1000e/82571.c
drivers/net/e1000e/defines.h
drivers/net/e1000e/hw.h
drivers/net/e1000e/netdev.c
drivers/net/eepro.c
drivers/net/eepro100.c [deleted file]
drivers/net/eexpress.c
drivers/net/ehea/ehea.h
drivers/net/ehea/ehea_main.c
drivers/net/ehea/ehea_qmr.c
drivers/net/enc28j60.c
drivers/net/enic/enic_main.c
drivers/net/enic/enic_res.c
drivers/net/enic/vnic_dev.c
drivers/net/epic100.c
drivers/net/es3210.c
drivers/net/eth16i.c
drivers/net/ewrk3.c
drivers/net/fealnx.c
drivers/net/fec.c
drivers/net/fec_mpc52xx.c
drivers/net/forcedeth.c
drivers/net/fs_enet/fs_enet-main.c
drivers/net/gianfar.c
drivers/net/hamachi.c
drivers/net/hamradio/6pack.c
drivers/net/hamradio/baycom_epp.c
drivers/net/hamradio/bpqether.c
drivers/net/hamradio/dmascc.c
drivers/net/hamradio/hdlcdrv.c
drivers/net/hamradio/mkiss.c
drivers/net/hamradio/scc.c
drivers/net/hamradio/yam.c
drivers/net/hp-plus.c
drivers/net/hp.c
drivers/net/hp100.c
drivers/net/hydra.c
drivers/net/ibm_newemac/core.c
drivers/net/ibmlana.c
drivers/net/ibmveth.c
drivers/net/igb/igb_ethtool.c
drivers/net/igb/igb_main.c
drivers/net/ioc3-eth.c
drivers/net/ipg.c
drivers/net/irda/ali-ircc.c
drivers/net/irda/au1k_ir.c
drivers/net/irda/donauboe.c
drivers/net/irda/irda-usb.c
drivers/net/irda/kingsun-sir.c
drivers/net/irda/ks959-sir.c
drivers/net/irda/ksdazzle-sir.c
drivers/net/irda/mcs7780.c
drivers/net/irda/nsc-ircc.c
drivers/net/irda/pxaficp_ir.c
drivers/net/irda/sa1100_ir.c
drivers/net/irda/sir_dev.c
drivers/net/irda/stir4200.c
drivers/net/irda/via-ircc.c
drivers/net/irda/vlsi_ir.c
drivers/net/irda/w83977af_ir.c
drivers/net/isa-skeleton.c
drivers/net/iseries_veth.c
drivers/net/ixgb/ixgb_main.c
drivers/net/ixgbe/ixgbe.h
drivers/net/ixgbe/ixgbe_82598.c
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/ixp2000/ixpdev.c
drivers/net/jazzsonic.c
drivers/net/jme.c
drivers/net/korina.c
drivers/net/lance.c
drivers/net/lib82596.c
drivers/net/lib8390.c
drivers/net/lne390.c
drivers/net/loopback.c
drivers/net/lp486e.c
drivers/net/mac89x0.c
drivers/net/macb.c
drivers/net/mace.c
drivers/net/macmace.c
drivers/net/macsonic.c
drivers/net/macvlan.c
drivers/net/meth.c
drivers/net/mlx4/en_rx.c
drivers/net/mlx4/mcg.c
drivers/net/mlx4/mlx4_en.h
drivers/net/mv643xx_eth.c
drivers/net/mvme147.c
drivers/net/myri10ge/myri10ge.c
drivers/net/myri_sbus.c
drivers/net/natsemi.c
drivers/net/ne-h8300.c
drivers/net/ne.c
drivers/net/ne2.c
drivers/net/ne2k-pci.c
drivers/net/ne3210.c
drivers/net/netconsole.c
drivers/net/netx-eth.c
drivers/net/netxen/netxen_nic_hw.c
drivers/net/netxen/netxen_nic_init.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/netxen/netxen_nic_niu.c
drivers/net/ni5010.c
drivers/net/ni52.c
drivers/net/ni65.c
drivers/net/niu.c
drivers/net/ns83820.c
drivers/net/pasemi_mac.c
drivers/net/pasemi_mac_ethtool.c
drivers/net/pci-skeleton.c
drivers/net/pcmcia/3c574_cs.c
drivers/net/pcmcia/3c589_cs.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/com20020_cs.c
drivers/net/pcmcia/fmvj18x_cs.c
drivers/net/pcmcia/nmclan_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/pcmcia/xirc2ps_cs.c
drivers/net/pcnet32.c
drivers/net/phy/Kconfig
drivers/net/phy/Makefile
drivers/net/phy/broadcom.c
drivers/net/phy/mdio-gpio.c [new file with mode: 0644]
drivers/net/phy/mdio-ofgpio.c [deleted file]
drivers/net/phy/mdio_bus.c
drivers/net/phy/phy.c
drivers/net/phy/phy_device.c
drivers/net/phy/smsc.c
drivers/net/plip.c
drivers/net/ppp_generic.c
drivers/net/pppoe.c
drivers/net/ps3_gelic_net.c
drivers/net/ps3_gelic_wireless.c
drivers/net/ps3_gelic_wireless.h
drivers/net/qla3xxx.c
drivers/net/qlge/qlge_main.c
drivers/net/r6040.c
drivers/net/r8169.c
drivers/net/rionet.c
drivers/net/rrunner.c
drivers/net/s2io.c
drivers/net/sb1000.c
drivers/net/sb1250-mac.c
drivers/net/sc92031.c
drivers/net/seeq8005.c
drivers/net/sfc/Kconfig
drivers/net/sfc/Makefile
drivers/net/sfc/boards.c
drivers/net/sfc/efx.c
drivers/net/sfc/efx.h
drivers/net/sfc/enum.h
drivers/net/sfc/ethtool.c
drivers/net/sfc/falcon.c
drivers/net/sfc/falcon_hwdefs.h
drivers/net/sfc/mdio_10g.c
drivers/net/sfc/mdio_10g.h
drivers/net/sfc/mtd.c [new file with mode: 0644]
drivers/net/sfc/net_driver.h
drivers/net/sfc/rx.c
drivers/net/sfc/sfe4001.c
drivers/net/sfc/spi.h
drivers/net/sfc/tenxpress.c
drivers/net/sfc/workarounds.h
drivers/net/sfc/xfp_phy.c
drivers/net/sgiseeq.c
drivers/net/sh_eth.c
drivers/net/sis190.c
drivers/net/sis900.c
drivers/net/skfp/skfddi.c
drivers/net/skge.c
drivers/net/sky2.c
drivers/net/slip.c
drivers/net/smc-mca.c
drivers/net/smc-ultra.c
drivers/net/smc-ultra32.c
drivers/net/smc911x.c
drivers/net/smc9194.c
drivers/net/smc91x.c
drivers/net/smsc911x.c [new file with mode: 0644]
drivers/net/smsc911x.h [new file with mode: 0644]
drivers/net/sonic.c
drivers/net/sonic.h
drivers/net/spider_net_ethtool.c
drivers/net/starfire.c
drivers/net/sun3_82586.c
drivers/net/sun3lance.c
drivers/net/sunbmac.c
drivers/net/sundance.c
drivers/net/sungem.c
drivers/net/sunhme.c
drivers/net/sunlance.c
drivers/net/sunqe.c
drivers/net/sunvnet.c
drivers/net/tc35815.c
drivers/net/tehuti.c
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/tlan.c
drivers/net/tokenring/3c359.c
drivers/net/tokenring/abyss.c
drivers/net/tokenring/ibmtr.c
drivers/net/tokenring/lanstreamer.c
drivers/net/tokenring/madgemc.c
drivers/net/tokenring/olympic.c
drivers/net/tokenring/proteon.c
drivers/net/tokenring/skisa.c
drivers/net/tokenring/smctr.c
drivers/net/tokenring/tms380tr.c
drivers/net/tokenring/tmspci.c
drivers/net/tsi108_eth.c
drivers/net/tulip/de2104x.c
drivers/net/tulip/de4x5.c
drivers/net/tulip/dmfe.c
drivers/net/tulip/eeprom.c
drivers/net/tulip/interrupt.c
drivers/net/tulip/tulip_core.c
drivers/net/tulip/uli526x.c
drivers/net/tulip/winbond-840.c
drivers/net/tulip/xircom_cb.c
drivers/net/tun.c
drivers/net/typhoon.c
drivers/net/ucc_geth.c
drivers/net/usb/catc.c
drivers/net/usb/mcs7830.c
drivers/net/usb/pegasus.c
drivers/net/usb/smsc95xx.c
drivers/net/usb/usbnet.c
drivers/net/veth.c
drivers/net/via-rhine.c
drivers/net/via-velocity.c
drivers/net/virtio_net.c
drivers/net/wan/cosa.c
drivers/net/wan/cycx_x25.c
drivers/net/wan/dlci.c
drivers/net/wan/dscc4.c
drivers/net/wan/farsync.c
drivers/net/wan/hd6457x.c
drivers/net/wan/hostess_sv11.c
drivers/net/wan/lapbether.c
drivers/net/wan/lmc/lmc_main.c
drivers/net/wan/lmc/lmc_proto.c
drivers/net/wan/pc300too.c
drivers/net/wan/pci200syn.c
drivers/net/wan/sbni.c
drivers/net/wan/sdla.c
drivers/net/wan/sealevel.c
drivers/net/wan/syncppp.c
drivers/net/wan/wanxl.c
drivers/net/wan/x25_asy.c
drivers/net/wd.c
drivers/net/wireless/Kconfig
drivers/net/wireless/Makefile
drivers/net/wireless/adm8211.c
drivers/net/wireless/adm8211.h
drivers/net/wireless/airo.c
drivers/net/wireless/airport.c [deleted file]
drivers/net/wireless/arlan-main.c
drivers/net/wireless/ath5k/ath5k.h
drivers/net/wireless/ath5k/base.c
drivers/net/wireless/ath5k/dma.c
drivers/net/wireless/ath5k/initvals.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/Makefile
drivers/net/wireless/ath9k/ani.c [new file with mode: 0644]
drivers/net/wireless/ath9k/ath9k.h
drivers/net/wireless/ath9k/beacon.c
drivers/net/wireless/ath9k/calib.c [new file with mode: 0644]
drivers/net/wireless/ath9k/core.c
drivers/net/wireless/ath9k/core.h
drivers/net/wireless/ath9k/eeprom.c [new file with mode: 0644]
drivers/net/wireless/ath9k/hw.c
drivers/net/wireless/ath9k/hw.h
drivers/net/wireless/ath9k/mac.c [new file with mode: 0644]
drivers/net/wireless/ath9k/main.c
drivers/net/wireless/ath9k/phy.c
drivers/net/wireless/ath9k/rc.c
drivers/net/wireless/ath9k/rc.h
drivers/net/wireless/ath9k/recv.c
drivers/net/wireless/ath9k/xmit.c
drivers/net/wireless/atmel.c
drivers/net/wireless/b43/b43.h
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/pio.c
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43/xmit.h
drivers/net/wireless/b43legacy/dma.c
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/b43legacy/pio.c
drivers/net/wireless/b43legacy/xmit.c
drivers/net/wireless/b43legacy/xmit.h
drivers/net/wireless/hermes.c [deleted file]
drivers/net/wireless/hermes.h [deleted file]
drivers/net/wireless/hermes_dld.c [deleted file]
drivers/net/wireless/hermes_dld.h [deleted file]
drivers/net/wireless/hermes_rid.h [deleted file]
drivers/net/wireless/hostap/hostap_80211_rx.c
drivers/net/wireless/hostap/hostap_80211_tx.c
drivers/net/wireless/hostap/hostap_ap.c
drivers/net/wireless/hostap/hostap_common.h
drivers/net/wireless/hostap/hostap_hw.c
drivers/net/wireless/hostap/hostap_info.c
drivers/net/wireless/hostap/hostap_ioctl.c
drivers/net/wireless/hostap/hostap_main.c
drivers/net/wireless/hostap/hostap_pci.c
drivers/net/wireless/hostap/hostap_proc.c
drivers/net/wireless/hostap/hostap_wlan.h
drivers/net/wireless/ipw2100.c
drivers/net/wireless/ipw2200.c
drivers/net/wireless/ipw2200.h
drivers/net/wireless/iwlwifi/Kconfig
drivers/net/wireless/iwlwifi/iwl-3945-commands.h
drivers/net/wireless/iwlwifi/iwl-3945-io.h
drivers/net/wireless/iwlwifi/iwl-3945-rs.c
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-3945.h
drivers/net/wireless/iwlwifi/iwl-4965-hw.h
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-5000-hw.h
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.h
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-calib.c
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-csr.h
drivers/net/wireless/iwlwifi/iwl-debug.h
drivers/net/wireless/iwlwifi/iwl-debugfs.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-eeprom.c
drivers/net/wireless/iwlwifi/iwl-eeprom.h
drivers/net/wireless/iwlwifi/iwl-fh.h
drivers/net/wireless/iwlwifi/iwl-helpers.h
drivers/net/wireless/iwlwifi/iwl-io.h
drivers/net/wireless/iwlwifi/iwl-led.c
drivers/net/wireless/iwlwifi/iwl-power.c
drivers/net/wireless/iwlwifi/iwl-prph.h
drivers/net/wireless/iwlwifi/iwl-rfkill.c
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-sta.c
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/libertas/assoc.c
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/debugfs.c
drivers/net/wireless/libertas/decl.h
drivers/net/wireless/libertas/defs.h
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/ethtool.c
drivers/net/wireless/libertas/main.c
drivers/net/wireless/libertas/persistcfg.c
drivers/net/wireless/libertas/scan.c
drivers/net/wireless/libertas/scan.h
drivers/net/wireless/libertas/tx.c
drivers/net/wireless/libertas/types.h
drivers/net/wireless/libertas/wext.c
drivers/net/wireless/libertas_tf/cmd.c
drivers/net/wireless/libertas_tf/if_usb.c
drivers/net/wireless/libertas_tf/main.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/netwave_cs.c
drivers/net/wireless/orinoco.c [deleted file]
drivers/net/wireless/orinoco.h [deleted file]
drivers/net/wireless/orinoco/Makefile [new file with mode: 0644]
drivers/net/wireless/orinoco/airport.c [new file with mode: 0644]
drivers/net/wireless/orinoco/hermes.c [new file with mode: 0644]
drivers/net/wireless/orinoco/hermes.h [new file with mode: 0644]
drivers/net/wireless/orinoco/hermes_dld.c [new file with mode: 0644]
drivers/net/wireless/orinoco/hermes_dld.h [new file with mode: 0644]
drivers/net/wireless/orinoco/hermes_rid.h [new file with mode: 0644]
drivers/net/wireless/orinoco/orinoco.c [new file with mode: 0644]
drivers/net/wireless/orinoco/orinoco.h [new file with mode: 0644]
drivers/net/wireless/orinoco/orinoco_cs.c [new file with mode: 0644]
drivers/net/wireless/orinoco/orinoco_nortel.c [new file with mode: 0644]
drivers/net/wireless/orinoco/orinoco_pci.c [new file with mode: 0644]
drivers/net/wireless/orinoco/orinoco_pci.h [new file with mode: 0644]
drivers/net/wireless/orinoco/orinoco_plx.c [new file with mode: 0644]
drivers/net/wireless/orinoco/orinoco_tmd.c [new file with mode: 0644]
drivers/net/wireless/orinoco/spectrum_cs.c [new file with mode: 0644]
drivers/net/wireless/orinoco_cs.c [deleted file]
drivers/net/wireless/orinoco_nortel.c [deleted file]
drivers/net/wireless/orinoco_pci.c [deleted file]
drivers/net/wireless/orinoco_pci.h [deleted file]
drivers/net/wireless/orinoco_plx.c [deleted file]
drivers/net/wireless/orinoco_tmd.c [deleted file]
drivers/net/wireless/p54/p54.h
drivers/net/wireless/p54/p54common.c
drivers/net/wireless/p54/p54common.h
drivers/net/wireless/p54/p54pci.c
drivers/net/wireless/p54/p54usb.c
drivers/net/wireless/prism54/isl_ioctl.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/rndis_wlan.c
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2400pci.h
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500pci.h
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2500usb.h
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00config.c
drivers/net/wireless/rt2x00/rt2x00debug.c
drivers/net/wireless/rt2x00/rt2x00debug.h
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00lib.h
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/net/wireless/rt2x00/rt2x00pci.h
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rt2x00/rt2x00queue.h
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt61pci.h
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rt2x00/rt73usb.h
drivers/net/wireless/rtl8180_dev.c
drivers/net/wireless/rtl8187.h
drivers/net/wireless/rtl8187_dev.c
drivers/net/wireless/rtl8187_rtl8225.c
drivers/net/wireless/spectrum_cs.c [deleted file]
drivers/net/wireless/strip.c
drivers/net/wireless/wavelan.c
drivers/net/wireless/wavelan_cs.c
drivers/net/wireless/wl3501.h
drivers/net/wireless/wl3501_cs.c
drivers/net/wireless/zd1201.c
drivers/net/wireless/zd1211rw/zd_chip.c
drivers/net/wireless/zd1211rw/zd_mac.c
drivers/net/wireless/zd1211rw/zd_usb.c
drivers/net/xen-netfront.c
drivers/net/xtsonic.c
drivers/net/yellowfin.c
drivers/net/znet.c
drivers/net/zorro8390.c
drivers/s390/net/qeth_l2_main.c
drivers/scsi/iscsi_tcp.c
drivers/scsi/qla4xxx/ql4_os.c
drivers/usb/atm/cxacru.c
drivers/usb/atm/usbatm.c
drivers/usb/gadget/u_ether.c
drivers/uwb/wlp/eda.c
fs/afs/proc.c
fs/afs/server.c
fs/cifs/cifs_spnego.c
fs/cifs/connect.c
fs/lockd/host.c
fs/lockd/mon.c
fs/nfs/nfsroot.c
fs/nfs/super.c
fs/nfsd/nfs4state.c
fs/nfsd/nfsctl.c
fs/ocfs2/cluster/netdebug.c
fs/ocfs2/cluster/nodemanager.c
fs/ocfs2/cluster/tcp.c
include/linux/cgroup_subsys.h
include/linux/dccp.h
include/linux/ieee80211.h
include/linux/if.h
include/linux/in.h
include/linux/kernel.h
include/linux/list_nulls.h [new file with mode: 0644]
include/linux/mdio-gpio.h [new file with mode: 0644]
include/linux/netdevice.h
include/linux/nl80211.h
include/linux/pkt_cls.h
include/linux/rculist_nulls.h [new file with mode: 0644]
include/linux/skbuff.h
include/linux/smsc911x.h [new file with mode: 0644]
include/linux/sunrpc/svc_xprt.h
include/linux/virtio_net.h
include/linux/xfrm.h
include/net/cfg80211.h
include/net/dst.h
include/net/ieee80211.h
include/net/inet_hashtables.h
include/net/inet_timewait_sock.h
include/net/ip_vs.h
include/net/lib80211.h [new file with mode: 0644]
include/net/mac80211.h
include/net/ndisc.h
include/net/neighbour.h
include/net/net_namespace.h
include/net/netfilter/nf_conntrack_tuple.h
include/net/netlink.h
include/net/netns/ipv4.h
include/net/pkt_cls.h
include/net/sch_generic.h
include/net/sctp/sctp.h
include/net/sock.h
include/net/tcp.h
include/net/udp.h
include/net/udplite.h
include/net/wireless.h
include/net/xfrm.h
lib/vsprintf.c
net/802/tr.c
net/8021q/vlan.c
net/8021q/vlan.h
net/8021q/vlan_core.c
net/8021q/vlan_dev.c
net/Kconfig
net/appletalk/aarp.c
net/appletalk/ddp.c
net/appletalk/sysctl_net_atalk.c
net/atm/atm_sysfs.c
net/atm/br2684.c
net/atm/clip.c
net/atm/lec.c
net/atm/mpc.c
net/atm/mpoa_caches.c
net/ax25/sysctl_net_ax25.c
net/bluetooth/bnep/core.c
net/bluetooth/bnep/netdev.c
net/bluetooth/hci_sysfs.c
net/bridge/br_if.c
net/bridge/br_netfilter.c
net/bridge/br_sysfs_br.c
net/bridge/netfilter/ebt_log.c
net/core/datagram.c
net/core/dev.c
net/core/dst.c
net/core/fib_rules.c
net/core/flow.c
net/core/neighbour.c
net/core/net-sysfs.c
net/core/net_namespace.c
net/core/netpoll.c
net/core/pktgen.c
net/core/skbuff.c
net/core/sock.c
net/core/sysctl_net_core.c
net/dccp/ccid.c
net/dccp/ccid.h
net/dccp/ccids/ccid2.c
net/dccp/dccp.h
net/dccp/feat.c
net/dccp/feat.h
net/dccp/input.c
net/dccp/ipv4.c
net/dccp/ipv6.c
net/dccp/minisocks.c
net/dccp/options.c
net/dccp/output.c
net/dccp/probe.c
net/dccp/proto.c
net/dccp/sysctl.c
net/dccp/timer.c
net/decnet/dn_route.c
net/decnet/sysctl_net_decnet.c
net/dsa/slave.c
net/dsa/tag_dsa.c
net/dsa/tag_edsa.c
net/dsa/tag_trailer.c
net/ieee80211/Kconfig
net/ieee80211/ieee80211_crypt_ccmp.c
net/ieee80211/ieee80211_crypt_tkip.c
net/ieee80211/ieee80211_module.c
net/ieee80211/ieee80211_rx.c
net/ieee80211/ieee80211_wx.c
net/ipv4/af_inet.c
net/ipv4/ah4.c
net/ipv4/arp.c
net/ipv4/cipso_ipv4.c
net/ipv4/devinet.c
net/ipv4/esp4.c
net/ipv4/fib_frontend.c
net/ipv4/fib_hash.c
net/ipv4/fib_semantics.c
net/ipv4/fib_trie.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_diag.c
net/ipv4/inet_hashtables.c
net/ipv4/inet_timewait_sock.c
net/ipv4/inetpeer.c
net/ipv4/ip_forward.c
net/ipv4/ip_fragment.c
net/ipv4/ip_gre.c
net/ipv4/ip_input.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/ipcomp.c
net/ipv4/ipconfig.c
net/ipv4/ipip.c
net/ipv4/ipmr.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv4/netfilter/ipt_LOG.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
net/ipv4/netfilter/nf_conntrack_proto_icmp.c
net/ipv4/netfilter/nf_nat_h323.c
net/ipv4/netfilter/nf_nat_irc.c
net/ipv4/netfilter/nf_nat_rule.c
net/ipv4/netfilter/nf_nat_sip.c
net/ipv4/netfilter/nf_nat_snmp_basic.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_cubic.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_output.c
net/ipv4/tcp_probe.c
net/ipv4/tcp_timer.c
net/ipv4/tcp_yeah.c
net/ipv4/udp.c
net/ipv4/udp_impl.h
net/ipv4/udplite.c
net/ipv4/xfrm4_policy.c
net/ipv6/addrconf.c
net/ipv6/addrlabel.c
net/ipv6/ah6.c
net/ipv6/anycast.c
net/ipv6/esp6.c
net/ipv6/exthdrs.c
net/ipv6/icmp.c
net/ipv6/inet6_hashtables.c
net/ipv6/ip6_flowlabel.c
net/ipv6/ip6_output.c
net/ipv6/ip6mr.c
net/ipv6/ipcomp6.c
net/ipv6/mcast.c
net/ipv6/ndisc.c
net/ipv6/netfilter/ip6t_LOG.c
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/reassembly.c
net/ipv6/route.c
net/ipv6/sysctl_net_ipv6.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/ipv6/udp_impl.h
net/ipv6/udplite.c
net/ipv6/xfrm6_policy.c
net/ipx/sysctl_net_ipx.c
net/irda/irlan/irlan_client.c
net/irda/irlan/irlan_common.c
net/irda/irsysctl.c
net/llc/llc_proc.c
net/llc/sysctl_net_llc.c
net/mac80211/cfg.c
net/mac80211/debugfs.c
net/mac80211/debugfs_key.c
net/mac80211/debugfs_netdev.c
net/mac80211/debugfs_sta.c
net/mac80211/event.c
net/mac80211/ht.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/key.c
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mesh.h
net/mac80211/mesh_hwmp.c
net/mac80211/mesh_plink.c
net/mac80211/mlme.c
net/mac80211/rate.c
net/mac80211/rate.h
net/mac80211/rc80211_minstrel.c
net/mac80211/rc80211_minstrel.h
net/mac80211/rc80211_pid.h
net/mac80211/rc80211_pid_algo.c
net/mac80211/rc80211_pid_debugfs.c
net/mac80211/rx.c
net/mac80211/scan.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mac80211/tkip.c
net/mac80211/tx.c
net/mac80211/util.c
net/mac80211/wep.c
net/mac80211/wep.h
net/mac80211/wext.c
net/mac80211/wme.c
net/mac80211/wpa.c
net/netfilter/ipvs/ip_vs_conn.c
net/netfilter/ipvs/ip_vs_core.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/ipvs/ip_vs_dh.c
net/netfilter/ipvs/ip_vs_ftp.c
net/netfilter/ipvs/ip_vs_lblc.c
net/netfilter/ipvs/ip_vs_lblcr.c
net/netfilter/ipvs/ip_vs_lc.c
net/netfilter/ipvs/ip_vs_nq.c
net/netfilter/ipvs/ip_vs_proto.c
net/netfilter/ipvs/ip_vs_proto_ah_esp.c
net/netfilter/ipvs/ip_vs_proto_tcp.c
net/netfilter/ipvs/ip_vs_proto_udp.c
net/netfilter/ipvs/ip_vs_rr.c
net/netfilter/ipvs/ip_vs_sed.c
net/netfilter/ipvs/ip_vs_sh.c
net/netfilter/ipvs/ip_vs_sync.c
net/netfilter/ipvs/ip_vs_wlc.c
net/netfilter/ipvs/ip_vs_wrr.c
net/netfilter/ipvs/ip_vs_xmit.c
net/netfilter/nf_conntrack_acct.c
net/netfilter/nf_conntrack_ftp.c
net/netfilter/nf_conntrack_h323_main.c
net/netfilter/nf_conntrack_irc.c
net/netfilter/nf_conntrack_proto_generic.c
net/netfilter/nf_conntrack_proto_sctp.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nf_conntrack_proto_udp.c
net/netfilter/nf_conntrack_proto_udplite.c
net/netfilter/nf_conntrack_standalone.c
net/netfilter/xt_hashlimit.c
net/netfilter/xt_iprange.c
net/netfilter/xt_recent.c
net/netlabel/netlabel_addrlist.c
net/netlink/attr.c
net/netrom/sysctl_net_netrom.c
net/phonet/af_phonet.c
net/phonet/pep-gprs.c
net/phonet/sysctl.c
net/rfkill/rfkill-input.c
net/rfkill/rfkill-input.h
net/rfkill/rfkill.c
net/rose/sysctl_net_rose.c
net/rxrpc/af_rxrpc.c
net/rxrpc/ar-error.c
net/rxrpc/ar-local.c
net/rxrpc/ar-peer.c
net/rxrpc/ar-proc.c
net/rxrpc/ar-transport.c
net/rxrpc/rxkad.c
net/sched/Kconfig
net/sched/Makefile
net/sched/cls_cgroup.c [new file with mode: 0644]
net/sched/ematch.c
net/sched/sch_api.c
net/sched/sch_atm.c
net/sched/sch_blackhole.c
net/sched/sch_cbq.c
net/sched/sch_dsmark.c
net/sched/sch_fifo.c
net/sched/sch_generic.c
net/sched/sch_gred.c
net/sched/sch_hfsc.c
net/sched/sch_htb.c
net/sched/sch_multiq.c
net/sched/sch_netem.c
net/sched/sch_prio.c
net/sched/sch_red.c
net/sched/sch_sfq.c
net/sched/sch_tbf.c
net/sched/sch_teql.c
net/sctp/ipv6.c
net/sctp/protocol.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/sctp/sysctl.c
net/socket.c
net/sunrpc/clnt.c
net/sunrpc/rpcb_clnt.c
net/sunrpc/svcauth_unix.c
net/sunrpc/svcsock.c
net/sunrpc/xprtrdma/svc_rdma_transport.c
net/sunrpc/xprtrdma/transport.c
net/sunrpc/xprtrdma/verbs.c
net/sunrpc/xprtsock.c
net/tipc/eth_media.c
net/tipc/name_table.c
net/unix/af_unix.c
net/unix/garbage.c
net/unix/sysctl_net_unix.c
net/wireless/Kconfig
net/wireless/Makefile
net/wireless/core.c
net/wireless/lib80211.c [new file with mode: 0644]
net/wireless/nl80211.c
net/wireless/reg.c
net/wireless/reg.h
net/wireless/util.c
net/x25/sysctl_net_x25.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
security/selinux/avc.c
security/selinux/hooks.c

diff --git a/Documentation/RCU/rculist_nulls.txt b/Documentation/RCU/rculist_nulls.txt
new file mode 100644 (file)
index 0000000..239f542
--- /dev/null
@@ -0,0 +1,167 @@
+Using hlist_nulls to protect read-mostly linked lists and
+objects using SLAB_DESTROY_BY_RCU allocations.
+
+Please read the basics in Documentation/RCU/listRCU.txt
+
+Using special makers (called 'nulls') is a convenient way
+to solve following problem :
+
+A typical RCU linked list managing objects which are
+allocated with SLAB_DESTROY_BY_RCU kmem_cache can
+use following algos :
+
+1) Lookup algo
+--------------
+rcu_read_lock()
+begin:
+obj = lockless_lookup(key);
+if (obj) {
+  if (!try_get_ref(obj)) // might fail for free objects
+    goto begin;
+  /*
+   * Because a writer could delete object, and a writer could
+   * reuse these object before the RCU grace period, we
+   * must check key after geting the reference on object
+   */
+  if (obj->key != key) { // not the object we expected
+     put_ref(obj);
+     goto begin;
+   }
+}
+rcu_read_unlock();
+
+Beware that lockless_lookup(key) cannot use traditional hlist_for_each_entry_rcu()
+but a version with an additional memory barrier (smp_rmb())
+
+lockless_lookup(key)
+{
+   struct hlist_node *node, *next;
+   for (pos = rcu_dereference((head)->first);
+          pos && ({ next = pos->next; smp_rmb(); prefetch(next); 1; }) &&
+          ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; });
+          pos = rcu_dereference(next))
+      if (obj->key == key)
+         return obj;
+   return NULL;
+
+And note the traditional hlist_for_each_entry_rcu() misses this smp_rmb() :
+
+   struct hlist_node *node;
+   for (pos = rcu_dereference((head)->first);
+               pos && ({ prefetch(pos->next); 1; }) &&
+               ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; });
+               pos = rcu_dereference(pos->next))
+      if (obj->key == key)
+         return obj;
+   return NULL;
+}
+
+Quoting Corey Minyard :
+
+"If the object is moved from one list to another list in-between the
+ time the hash is calculated and the next field is accessed, and the
+ object has moved to the end of a new list, the traversal will not
+ complete properly on the list it should have, since the object will
+ be on the end of the new list and there's not a way to tell it's on a
+ new list and restart the list traversal.  I think that this can be
+ solved by pre-fetching the "next" field (with proper barriers) before
+ checking the key."
+
+2) Insert algo :
+----------------
+
+We need to make sure a reader cannot read the new 'obj->obj_next' value
+and previous value of 'obj->key'. Or else, an item could be deleted
+from a chain, and inserted into another chain. If new chain was empty
+before the move, 'next' pointer is NULL, and lockless reader can
+not detect it missed following items in original chain.
+
+/*
+ * Please note that new inserts are done at the head of list,
+ * not in the middle or end.
+ */
+obj = kmem_cache_alloc(...);
+lock_chain(); // typically a spin_lock()
+obj->key = key;
+atomic_inc(&obj->refcnt);
+/*
+ * we need to make sure obj->key is updated before obj->next
+ */
+smp_wmb();
+hlist_add_head_rcu(&obj->obj_node, list);
+unlock_chain(); // typically a spin_unlock()
+
+
+3) Remove algo
+--------------
+Nothing special here, we can use a standard RCU hlist deletion.
+But thanks to SLAB_DESTROY_BY_RCU, beware a deleted object can be reused
+very very fast (before the end of RCU grace period)
+
+if (put_last_reference_on(obj) {
+   lock_chain(); // typically a spin_lock()
+   hlist_del_init_rcu(&obj->obj_node);
+   unlock_chain(); // typically a spin_unlock()
+   kmem_cache_free(cachep, obj);
+}
+
+
+
+--------------------------------------------------------------------------
+With hlist_nulls we can avoid extra smp_rmb() in lockless_lookup()
+and extra smp_wmb() in insert function.
+
+For example, if we choose to store the slot number as the 'nulls'
+end-of-list marker for each slot of the hash table, we can detect
+a race (some writer did a delete and/or a move of an object
+to another chain) checking the final 'nulls' value if
+the lookup met the end of chain. If final 'nulls' value
+is not the slot number, then we must restart the lookup at
+the begining. If the object was moved to same chain,
+then the reader doesnt care : It might eventually
+scan the list again without harm.
+
+
+1) lookup algo
+
+ head = &table[slot];
+ rcu_read_lock();
+begin:
+ hlist_nulls_for_each_entry_rcu(obj, node, head, member) {
+   if (obj->key == key) {
+      if (!try_get_ref(obj)) // might fail for free objects
+         goto begin;
+      if (obj->key != key) { // not the object we expected
+         put_ref(obj);
+         goto begin;
+      }
+  goto out;
+ }
+/*
+ * if the nulls value we got at the end of this lookup is
+ * not the expected one, we must restart lookup.
+ * We probably met an item that was moved to another chain.
+ */
+ if (get_nulls_value(node) != slot)
+   goto begin;
+ obj = NULL;
+
+out:
+ rcu_read_unlock();
+
+2) Insert function :
+--------------------
+
+/*
+ * Please note that new inserts are done at the head of list,
+ * not in the middle or end.
+ */
+obj = kmem_cache_alloc(cachep);
+lock_chain(); // typically a spin_lock()
+obj->key = key;
+atomic_set(&obj->refcnt, 1);
+/*
+ * insert obj in RCU way (readers might be traversing chain)
+ */
+hlist_nulls_add_head_rcu(&obj->obj_node, list);
+unlock_chain(); // typically a spin_unlock()
index c28a2ac88f9d9ed1457ab0c04324e3cf20fe986f..77eb6b129dde3dc20227dacc09f8ffb91d6da920 100644 (file)
@@ -120,13 +120,6 @@ Who:       Christoph Hellwig <hch@lst.de>
 
 ---------------------------
 
-What:   eepro100 network driver
-When:   January 2007
-Why:    replaced by the e100 driver
-Who:    Adrian Bunk <bunk@stusta.de>
-
----------------------------
-
 What:  Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports
        (temporary transition config option provided until then)
        The transition config option will also be removed at the same time.
index 4f2a40f1dbc629837463a96695759e3848f41c68..80c728522c4c7a0482d1804689f87869d9c404c0 100644 (file)
@@ -147,7 +147,7 @@ Where the supported parameter are:
        driver.  If disabled, the driver will not attempt to scan 
        for and associate to a network until it has been configured with 
        one or more properties for the target network, for example configuring 
-       the network SSID.  Default is 1 (auto-associate)
+       the network SSID.  Default is 0 (do not auto-associate)
        
        Example: % modprobe ipw2200 associate=0
 
index 688dfe1e6b70f75a36d84f30dda2234c53664be0..5ede7473b4251e43e53c5053e144cf12f3d6032a 100644 (file)
@@ -194,6 +194,48 @@ or, for backwards compatibility, the option value.  E.g.,
 
        The parameters are as follows:
 
+ad_select
+
+       Specifies the 802.3ad aggregation selection logic to use.  The
+       possible values and their effects are:
+
+       stable or 0
+
+               The active aggregator is chosen by largest aggregate
+               bandwidth.
+
+               Reselection of the active aggregator occurs only when all
+               slaves of the active aggregator are down or the active
+               aggregator has no slaves.
+
+               This is the default value.
+
+       bandwidth or 1
+
+               The active aggregator is chosen by largest aggregate
+               bandwidth.  Reselection occurs if:
+
+               - A slave is added to or removed from the bond
+
+               - Any slave's link state changes
+
+               - Any slave's 802.3ad association state changes
+
+               - The bond's adminstrative state changes to up
+
+       count or 2
+
+               The active aggregator is chosen by the largest number of
+               ports (slaves).  Reselection occurs as described under the
+               "bandwidth" setting, above.
+
+       The bandwidth and count selection policies permit failover of
+       802.3ad aggregations when partial failure of the active aggregator
+       occurs.  This keeps the aggregator with the highest availability
+       (either in bandwidth or in number of ports) active at all times.
+
+       This option was added in bonding version 3.4.0.
+
 arp_interval
 
        Specifies the ARP link monitoring frequency in milliseconds.
@@ -551,6 +593,16 @@ num_grat_arp
        affects only the active-backup mode.  This option was added for
        bonding version 3.3.0.
 
+num_unsol_na
+
+       Specifies the number of unsolicited IPv6 Neighbor Advertisements
+       to be issued after a failover event.  One unsolicited NA is issued
+       immediately after the failover.
+
+       The valid range is 0 - 255; the default value is 1.  This option
+       affects only the active-backup mode.  This option was added for
+       bonding version 3.4.0.
+
 primary
 
        A string (eth0, eth2, etc) specifying which slave is the
@@ -922,17 +974,19 @@ USERCTL=no
 NETMASK, NETWORK and BROADCAST) to match your network configuration.
 
        For later versions of initscripts, such as that found with Fedora
-7 and Red Hat Enterprise Linux version 5 (or later), it is possible, and,
-indeed, preferable, to specify the bonding options in the ifcfg-bond0
+7 (or later) and Red Hat Enterprise Linux version 5 (or later), it is possible,
+and, indeed, preferable, to specify the bonding options in the ifcfg-bond0
 file, e.g. a line of the format:
 
-BONDING_OPTS="mode=active-backup arp_interval=60 arp_ip_target=+192.168.1.254"
+BONDING_OPTS="mode=active-backup arp_interval=60 arp_ip_target=192.168.1.254"
 
        will configure the bond with the specified options.  The options
 specified in BONDING_OPTS are identical to the bonding module parameters
-except for the arp_ip_target field.  Each target should be included as a
-separate option and should be preceded by a '+' to indicate it should be
-added to the list of queried targets, e.g.,
+except for the arp_ip_target field when using versions of initscripts older
+than and 8.57 (Fedora 8) and 8.45.19 (Red Hat Enterprise Linux 5.2).  When
+using older versions each target should be included as a separate option and
+should be preceded by a '+' to indicate it should be added to the list of
+queried targets, e.g.,
 
        arp_ip_target=+192.168.1.1 arp_ip_target=+192.168.1.2
 
@@ -940,7 +994,7 @@ added to the list of queried targets, e.g.,
 options via BONDING_OPTS, it is not necessary to edit /etc/modules.conf or
 /etc/modprobe.conf.
 
-       For older versions of initscripts that do not support
+       For even older versions of initscripts that do not support
 BONDING_OPTS, it is necessary to edit /etc/modules.conf (or
 /etc/modprobe.conf, depending upon your distro) to load the bonding module
 with your desired options when the bond0 interface is brought up.  The
index 39131a3c78f8826bb9949ddf25ff50e591904028..43df4487379be556337659302ca3791828376614 100644 (file)
@@ -57,6 +57,10 @@ can be set before calling bind().
 DCCP_SOCKOPT_GET_CUR_MPS is read-only and retrieves the current maximum packet
 size (application payload size) in bytes, see RFC 4340, section 14.
 
+DCCP_SOCKOPT_AVAILABLE_CCIDS is also read-only and returns the list of CCIDs
+supported by the endpoint (see include/linux/dccp.h for symbolic constants).
+The caller needs to provide a sufficiently large (> 2) array of type uint8_t.
+
 DCCP_SOCKOPT_SERVER_TIMEWAIT enables the server (listening socket) to hold
 timewait state when closing the connection (RFC 4340, 8.3). The usual case is
 that the closing server sends a CloseReq, whereupon the client holds timewait
@@ -121,9 +125,6 @@ send_ndp = 1
 send_ackvec = 1
        Whether or not to send Ack Vector options (sec. 11.5).
 
-ack_ratio = 2
-       The default Ack Ratio (sec. 11.3) to use.
-
 tx_ccid = 2
        Default CCID for the sender-receiver half-connection.
 
index d84932650fd3e926cc11d5fa0bcaee6cc8a8cd33..c7712787933c1734c98a0191db23d9cb2886d0f8 100644 (file)
@@ -27,6 +27,12 @@ min_adv_mss - INTEGER
        The advertised MSS depends on the first hop route MTU, but will
        never be lower than this setting.
 
+rt_cache_rebuild_count - INTEGER
+       The per net-namespace route cache emergency rebuild threshold.
+       Any net-namespace having its route cache rebuilt due to
+       a hash bucket chain being too long more than this many times
+       will have its route caching disabled
+
 IP Fragmentation:
 
 ipfrag_high_thresh - INTEGER
index a96989a8ff351c0a409187819175461cfa44f456..dcf31648414ad8423e934851bea5ee38b0d09f2f 100644 (file)
@@ -131,11 +131,13 @@ are expected to do this during initialization.
 
        r = zd_reg2alpha2(mac->regdomain, alpha2);
        if (!r)
-               regulatory_hint(hw->wiphy, alpha2, NULL);
+               regulatory_hint(hw->wiphy, alpha2);
 
 Example code - drivers providing a built in regulatory domain:
 --------------------------------------------------------------
 
+[NOTE: This API is not currently available, it can be added when required]
+
 If you have regulatory information you can obtain from your
 driver and you *need* to use this we let you build a regulatory domain
 structure and pass it to the wireless core. To do this you should
@@ -167,7 +169,6 @@ struct ieee80211_regdomain mydriver_jp_regdom = {
 
 Then in some part of your code after your wiphy has been registered:
 
-       int r;
        struct ieee80211_regdomain *rd;
        int size_of_regd;
        int num_rules = mydriver_jp_regdom.n_reg_rules;
@@ -178,17 +179,12 @@ Then in some part of your code after your wiphy has been registered:
 
        rd = kzalloc(size_of_regd, GFP_KERNEL);
        if (!rd)
-       return -ENOMEM;
+               return -ENOMEM;
 
        memcpy(rd, &mydriver_jp_regdom, sizeof(struct ieee80211_regdomain));
 
-       for (i=0; i < num_rules; i++) {
-               memcpy(&rd->reg_rules[i], &mydriver_jp_regdom.reg_rules[i],
-                       sizeof(struct ieee80211_reg_rule));
-       }
-       r = regulatory_hint(hw->wiphy, NULL, rd);
-       if (r) {
-               kfree(rd);
-               return r;
-       }
-
+       for (i=0; i < num_rules; i++)
+               memcpy(&rd->reg_rules[i],
+                      &mydriver_jp_regdom.reg_rules[i],
+                      sizeof(struct ieee80211_reg_rule));
+       regulatory_struct_hint(rd);
index b65f0799df485dfea9d0346a3d3ede5c7fc5afba..4d3ee317a4a3e84181047ab417a3e2a88c4995bc 100644 (file)
@@ -191,12 +191,20 @@ Userspace input handlers (uevents) or kernel input handlers (rfkill-input):
          to tell the devices registered with the rfkill class to change
          their state (i.e. translates the input layer event into real
          action).
+
        * rfkill-input implements EPO by handling EV_SW SW_RFKILL_ALL 0
          (power off all transmitters) in a special way: it ignores any
          overrides and local state cache and forces all transmitters to the
          RFKILL_STATE_SOFT_BLOCKED state (including those which are already
-         supposed to be BLOCKED).  Note that the opposite event (power on all
-         transmitters) is handled normally.
+         supposed to be BLOCKED).
+       * rfkill EPO will remain active until rfkill-input receives an
+         EV_SW SW_RFKILL_ALL 1 event.  While the EPO is active, transmitters
+         are locked in the blocked state (rfkill will refuse to unblock them).
+       * rfkill-input implements different policies that the user can
+         select for handling EV_SW SW_RFKILL_ALL 1.  It will unlock rfkill,
+         and either do nothing (leave transmitters blocked, but now unlocked),
+         restore the transmitters to their state before the EPO, or unblock
+         them all.
 
 Userspace uevent handler or kernel platform-specific drivers hooked to the
 rfkill notifier chain:
@@ -331,11 +339,9 @@ class to get a sysfs interface :-)
 correct event for your switch/button.  These events are emergency power-off
 events when they are trying to turn the transmitters off.  An example of an
 input device which SHOULD generate *_RFKILL_ALL events is the wireless-kill
-switch in a laptop which is NOT a hotkey, but a real switch that kills radios
-in hardware, even if the O.S. has gone to lunch.  An example of an input device
-which SHOULD NOT generate *_RFKILL_ALL events by default, is any sort of hot
-key that does nothing by itself, as well as any hot key that is type-specific
-(e.g. the one for WLAN).
+switch in a laptop which is NOT a hotkey, but a real sliding/rocker switch.
+An example of an input device which SHOULD NOT generate *_RFKILL_ALL events by
+default, is any sort of hot key that is type-specific (e.g. the one for WLAN).
 
 
 3.1 Guidelines for wireless device drivers
index 627e4c89328e1c98b0afc3cea7b52175fdac1f8a..b85cd25759a0e5fff98e38e65db283d7e3834fcd 100644 (file)
@@ -742,7 +742,7 @@ M:  jirislaby@gmail.com
 P:     Nick Kossifidis
 M:     mickflemm@gmail.com
 P:     Luis R. Rodriguez
-M:     mcgrof@gmail.com
+M:     lrodriguez@atheros.com
 P:     Bob Copeland
 M:     me@bobcopeland.com
 L:     linux-wireless@vger.kernel.org
@@ -1606,11 +1606,6 @@ L:       acpi4asus-user@lists.sourceforge.net
 W:     http://sourceforge.net/projects/acpi4asus
 S:     Maintained
 
-EEPRO100 NETWORK DRIVER
-P:     Andrey V. Savochkin
-M:     saw@saw.sw.com.sg
-S:     Maintained
-
 EFS FILESYSTEM
 W:     http://aeschi.ch.eu.org/efs/
 S:     Orphan
@@ -3903,6 +3898,12 @@ M:       mhoffman@lightlink.com
 L:     lm-sensors@lm-sensors.org
 S:     Maintained
 
+SMSC911x ETHERNET DRIVER
+P:     Steve Glendinning
+M:     steve.glendinning@smsc.com
+L:     netdev@vger.kernel.org
+S:     Supported
+
 SMX UIO Interface
 P:     Ben Nizette
 M:     bn@niasdigital.com
index e7c6386782ede189976cb4cb6b59fa2b7af97497..5add22fc98999ac57b0da0f688926b4f65c0dcfc 100644 (file)
@@ -177,7 +177,6 @@ static irqreturn_t fsg_reset_handler(int irq, void *dev_id)
 
 static void __init fsg_init(void)
 {
-       DECLARE_MAC_BUF(mac_buf);
        uint8_t __iomem *f;
 
        ixp4xx_sys_init();
@@ -256,10 +255,10 @@ static void __init fsg_init(void)
 #endif
                iounmap(f);
        }
-       printk(KERN_INFO "FSG: Using MAC address %s for port 0\n",
-              print_mac(mac_buf, fsg_plat_eth[0].hwaddr));
-       printk(KERN_INFO "FSG: Using MAC address %s for port 1\n",
-              print_mac(mac_buf, fsg_plat_eth[1].hwaddr));
+       printk(KERN_INFO "FSG: Using MAC address %pM for port 0\n",
+              fsg_plat_eth[0].hwaddr);
+       printk(KERN_INFO "FSG: Using MAC address %pM for port 1\n",
+              fsg_plat_eth[1].hwaddr);
 
 }
 
index 0acd95ecf27ef39e716a2c27cf470e30c666c640..921c947b5b6b33f170f279525cf8e87dfc0697a4 100644 (file)
@@ -231,7 +231,6 @@ static irqreturn_t nas100d_reset_handler(int irq, void *dev_id)
 
 static void __init nas100d_init(void)
 {
-       DECLARE_MAC_BUF(mac_buf);
        uint8_t __iomem *f;
        int i;
 
@@ -294,8 +293,8 @@ static void __init nas100d_init(void)
 #endif
                iounmap(f);
        }
-       printk(KERN_INFO "NAS100D: Using MAC address %s for port 0\n",
-              print_mac(mac_buf, nas100d_plat_eth[0].hwaddr));
+       printk(KERN_INFO "NAS100D: Using MAC address %pM for port 0\n",
+              nas100d_plat_eth[0].hwaddr);
 
 }
 
index bc9d920ae54f0f28a58597682abcc0e9c0c99c5e..ff6a08d02cc42e8b050c3c91eced3b490ec92877 100644 (file)
@@ -220,7 +220,6 @@ static struct sys_timer nslu2_timer = {
 
 static void __init nslu2_init(void)
 {
-       DECLARE_MAC_BUF(mac_buf);
        uint8_t __iomem *f;
        int i;
 
@@ -275,8 +274,8 @@ static void __init nslu2_init(void)
 #endif
                iounmap(f);
        }
-       printk(KERN_INFO "NSLU2: Using MAC address %s for port 0\n",
-              print_mac(mac_buf, nslu2_plat_eth[0].hwaddr));
+       printk(KERN_INFO "NSLU2: Using MAC address %pM for port 0\n",
+              nslu2_plat_eth[0].hwaddr);
 
 }
 
index 5b45a808c621da79fcb7211796277c763bbbee5c..a62ff83337cdc16bf9e83ec0d7013de556ab1351 100644 (file)
@@ -42,8 +42,5 @@ void __init idprom_init(void)
                            idprom->id_cksum, calc_idprom_cksum(idprom));
        }
 
-       printk("Ethernet address: %02x:%02x:%02x:%02x:%02x:%02x\n",
-              idprom->id_ethaddr[0], idprom->id_ethaddr[1],
-              idprom->id_ethaddr[2], idprom->id_ethaddr[3],
-              idprom->id_ethaddr[4], idprom->id_ethaddr[5]);
+       printk("Ethernet address: %pM\n", idprom->id_ethaddr);
 }
index 5b4ca8d93682cf70fe191c16c0c1180d872c8c78..74f1a1787026a3d82fc69eb7eb6615bc9b33e20e 100644 (file)
@@ -418,12 +418,7 @@ static void eth_configure(int n, void *init, char *mac,
 
        setup_etheraddr(mac, device->mac, dev->name);
 
-       printk(KERN_INFO "Netdevice %d ", n);
-       printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
-              device->mac[0], device->mac[1],
-              device->mac[2], device->mac[3],
-              device->mac[4], device->mac[5]);
-       printk(": ");
+       printk(KERN_INFO "Netdevice %d (%pM) : ", n, device->mac);
 
        lp = dev->priv;
        /* This points to the transport private data. It's still clear, but we
index 11a20adc140999b96b5b76f844c9e8fedd00c9f0..87f47cade013549d90b8966326f1134a52957fca 100644 (file)
@@ -660,10 +660,7 @@ static int iss_net_configure(int index, char *init)
 
        printk(KERN_INFO "Netdevice %d ", index);
        if (lp->have_mac)
-               printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
-                               lp->mac[0], lp->mac[1],
-                               lp->mac[2], lp->mac[3],
-                               lp->mac[4], lp->mac[5]);
+               printk("(%pM) ", lp->mac);
        printk(": ");
 
        /* sysfs register */
index 4353414a0b770c368b938760e8630f50bd065346..3ab3e4a41d670f48af0583c841dae8a6d040748f 100644 (file)
@@ -284,15 +284,12 @@ static ssize_t sprintf_ipaddr(char *buf, u8 *ip)
                /*
                 * IPV4
                 */
-               str += sprintf(buf, NIPQUAD_FMT, ip[12],
-                              ip[13], ip[14], ip[15]);
+               str += sprintf(buf, "%pI4", ip + 12);
        } else {
                /*
                 * IPv6
                 */
-               str += sprintf(str, NIP6_FMT, ntohs(ip[0]), ntohs(ip[1]),
-                              ntohs(ip[2]), ntohs(ip[3]), ntohs(ip[4]),
-                              ntohs(ip[5]), ntohs(ip[6]), ntohs(ip[7]));
+               str += sprintf(str, "%pI6", ip);
        }
        str += sprintf(str, "\n");
        return str - buf;
index 4d1042115598d39b95ccc76b12b80da0cbdf89c6..4f4d1bb9f069fa6a8f61c0027eb1f07c377d3664 100644 (file)
@@ -262,15 +262,7 @@ static ssize_t show_port_gid(struct ib_port *p, struct port_attribute *attr,
        if (ret)
                return ret;
 
-       return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
-                      be16_to_cpu(((__be16 *) gid.raw)[0]),
-                      be16_to_cpu(((__be16 *) gid.raw)[1]),
-                      be16_to_cpu(((__be16 *) gid.raw)[2]),
-                      be16_to_cpu(((__be16 *) gid.raw)[3]),
-                      be16_to_cpu(((__be16 *) gid.raw)[4]),
-                      be16_to_cpu(((__be16 *) gid.raw)[5]),
-                      be16_to_cpu(((__be16 *) gid.raw)[6]),
-                      be16_to_cpu(((__be16 *) gid.raw)[7]));
+       return sprintf(buf, "%pI6\n", gid.raw);
 }
 
 static ssize_t show_port_pkey(struct ib_port *p, struct port_attribute *attr,
index 3f5f948792089a3bf33440794f263bf35dc33d6e..d4c81053e439fe0fa46bae57e42e92738792b9e6 100644 (file)
@@ -87,17 +87,7 @@ static int find_mgm(struct mthca_dev *dev,
        }
 
        if (0)
-               mthca_dbg(dev, "Hash for %04x:%04x:%04x:%04x:"
-                         "%04x:%04x:%04x:%04x is %04x\n",
-                         be16_to_cpu(((__be16 *) gid)[0]),
-                         be16_to_cpu(((__be16 *) gid)[1]),
-                         be16_to_cpu(((__be16 *) gid)[2]),
-                         be16_to_cpu(((__be16 *) gid)[3]),
-                         be16_to_cpu(((__be16 *) gid)[4]),
-                         be16_to_cpu(((__be16 *) gid)[5]),
-                         be16_to_cpu(((__be16 *) gid)[6]),
-                         be16_to_cpu(((__be16 *) gid)[7]),
-                         *hash);
+               mthca_dbg(dev, "Hash for %pI6 is %04x\n", gid, *hash);
 
        *index = *hash;
        *prev  = -1;
@@ -264,16 +254,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
                goto out;
 
        if (index == -1) {
-               mthca_err(dev, "MGID %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x "
-                         "not found\n",
-                         be16_to_cpu(((__be16 *) gid->raw)[0]),
-                         be16_to_cpu(((__be16 *) gid->raw)[1]),
-                         be16_to_cpu(((__be16 *) gid->raw)[2]),
-                         be16_to_cpu(((__be16 *) gid->raw)[3]),
-                         be16_to_cpu(((__be16 *) gid->raw)[4]),
-                         be16_to_cpu(((__be16 *) gid->raw)[5]),
-                         be16_to_cpu(((__be16 *) gid->raw)[6]),
-                         be16_to_cpu(((__be16 *) gid->raw)[7]));
+               mthca_err(dev, "MGID %pI6 not found\n", gid->raw);
                err = -EINVAL;
                goto out;
        }
index aa1dc41f04c8fae5a8765bc9eb6853d9c28f4bf0..b9611ade9eab1aa917fcac20f0ef639404773981 100644 (file)
@@ -142,14 +142,9 @@ static int nes_inetaddr_event(struct notifier_block *notifier,
        struct nes_device *nesdev;
        struct net_device *netdev;
        struct nes_vnic *nesvnic;
-       unsigned int addr;
-       unsigned int mask;
-
-       addr = ntohl(ifa->ifa_address);
-       mask = ntohl(ifa->ifa_mask);
-       nes_debug(NES_DBG_NETDEV, "nes_inetaddr_event: ip address " NIPQUAD_FMT
-                 ", netmask " NIPQUAD_FMT ".\n",
-                 HIPQUAD(addr), HIPQUAD(mask));
+
+       nes_debug(NES_DBG_NETDEV, "nes_inetaddr_event: ip address %pI4, netmask %pI4.\n",
+                 &ifa->ifa_address, &ifa->ifa_mask);
        list_for_each_entry(nesdev, &nes_dev_list, list) {
                nes_debug(NES_DBG_NETDEV, "Nesdev list entry = 0x%p. (%s)\n",
                                nesdev, nesdev->netdev[0]->name);
@@ -360,10 +355,8 @@ struct ib_qp *nes_get_qp(struct ib_device *device, int qpn)
  */
 static void nes_print_macaddr(struct net_device *netdev)
 {
-       DECLARE_MAC_BUF(mac);
-
-       nes_debug(NES_DBG_INIT, "%s: %s, IRQ %u\n",
-                 netdev->name, print_mac(mac, netdev->dev_addr), netdev->irq);
+       nes_debug(NES_DBG_INIT, "%s: %pM, IRQ %u\n",
+                 netdev->name, netdev->dev_addr, netdev->irq);
 }
 
 /**
index 2caf9da81ad50d6db5db8bce1c24cb21c2bf46d5..2854a6f7fdfe6e6112fcd7ee7a0600ee614adb46 100644 (file)
@@ -823,8 +823,8 @@ static struct nes_cm_node *find_node(struct nes_cm_core *cm_core,
        /* get a handle on the hte */
        hte = &cm_core->connected_nodes;
 
-       nes_debug(NES_DBG_CM, "Searching for an owner node: " NIPQUAD_FMT ":%x from core %p->%p\n",
-                 HIPQUAD(loc_addr), loc_port, cm_core, hte);
+       nes_debug(NES_DBG_CM, "Searching for an owner node: %pI4:%x from core %p->%p\n",
+                 &loc_addr, loc_port, cm_core, hte);
 
        /* walk list and find cm_node associated with this session ID */
        spin_lock_irqsave(&cm_core->ht_lock, flags);
@@ -873,8 +873,8 @@ static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core,
        }
        spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
 
-       nes_debug(NES_DBG_CM, "Unable to find listener for " NIPQUAD_FMT ":%x\n",
-                 HIPQUAD(dst_addr), dst_port);
+       nes_debug(NES_DBG_CM, "Unable to find listener for %pI4:%x\n",
+                 &dst_addr, dst_port);
 
        /* no listener */
        return NULL;
@@ -1027,7 +1027,6 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
        struct flowi fl;
        struct neighbour *neigh;
        int rc = -1;
-       DECLARE_MAC_BUF(mac);
 
        memset(&fl, 0, sizeof fl);
        fl.nl_u.ip4_u.daddr = htonl(dst_ip);
@@ -1041,8 +1040,8 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
        if (neigh) {
                if (neigh->nud_state & NUD_VALID) {
                        nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X"
-                                 " is %s, Gateway is 0x%08X \n", dst_ip,
-                                 print_mac(mac, neigh->ha), ntohl(rt->rt_gateway));
+                                 " is %pM, Gateway is 0x%08X \n", dst_ip,
+                                 neigh->ha, ntohl(rt->rt_gateway));
                        nes_manage_arp_cache(nesvnic->netdev, neigh->ha,
                                             dst_ip, NES_ARP_ADD);
                        rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL,
@@ -1071,7 +1070,6 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
        int arpindex = 0;
        struct nes_device *nesdev;
        struct nes_adapter *nesadapter;
-       DECLARE_MAC_BUF(mac);
 
        /* create an hte and cm_node for this instance */
        cm_node = kzalloc(sizeof(*cm_node), GFP_ATOMIC);
@@ -1084,10 +1082,9 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
        cm_node->loc_port = cm_info->loc_port;
        cm_node->rem_port = cm_info->rem_port;
        cm_node->send_write0 = send_first;
-       nes_debug(NES_DBG_CM, "Make node addresses : loc = " NIPQUAD_FMT
-                       ":%x, rem = " NIPQUAD_FMT ":%x\n",
-                       HIPQUAD(cm_node->loc_addr), cm_node->loc_port,
-                       HIPQUAD(cm_node->rem_addr), cm_node->rem_port);
+       nes_debug(NES_DBG_CM, "Make node addresses : loc = %pI4:%x, rem = %pI4:%x\n",
+                 &cm_node->loc_addr, cm_node->loc_port,
+                 &cm_node->rem_addr, cm_node->rem_port);
        cm_node->listener = listener;
        cm_node->netdev = nesvnic->netdev;
        cm_node->cm_id = cm_info->cm_id;
@@ -1137,8 +1134,8 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
 
        /* copy the mac addr to node context */
        memcpy(cm_node->rem_mac, nesadapter->arp_table[arpindex].mac_addr, ETH_ALEN);
-       nes_debug(NES_DBG_CM, "Remote mac addr from arp table: %s\n",
-                 print_mac(mac, cm_node->rem_mac));
+       nes_debug(NES_DBG_CM, "Remote mac addr from arp table: %pM\n",
+                 cm_node->rem_mac);
 
        add_hte_node(cm_core, cm_node);
        atomic_inc(&cm_nodes_created);
@@ -2068,10 +2065,8 @@ static void mini_cm_recv_pkt(struct nes_cm_core *cm_core,
        nfo.rem_addr = ntohl(iph->saddr);
        nfo.rem_port = ntohs(tcph->source);
 
-       nes_debug(NES_DBG_CM, "Received packet: dest=" NIPQUAD_FMT
-                 ":0x%04X src=" NIPQUAD_FMT ":0x%04X\n",
-                 NIPQUAD(iph->daddr), tcph->dest,
-                 NIPQUAD(iph->saddr), tcph->source);
+       nes_debug(NES_DBG_CM, "Received packet: dest=%pI4:0x%04X src=%pI4:0x%04X\n",
+                 &iph->daddr, tcph->dest, &iph->saddr, tcph->source);
 
        do {
                cm_node = find_node(cm_core,
index 730358637bb62603111e936f02ac1ad5c336e780..3c96203e0d915ff3ffff6347bc182bfb9e89d5cb 100644 (file)
@@ -797,14 +797,13 @@ static int nes_netdev_set_mac_address(struct net_device *netdev, void *p)
        int i;
        u32 macaddr_low;
        u16 macaddr_high;
-       DECLARE_MAC_BUF(mac);
 
        if (!is_valid_ether_addr(mac_addr->sa_data))
                return -EADDRNOTAVAIL;
 
        memcpy(netdev->dev_addr, mac_addr->sa_data, netdev->addr_len);
-       printk(PFX "%s: Address length = %d, Address = %s\n",
-              __func__, netdev->addr_len, print_mac(mac, mac_addr->sa_data));
+       printk(PFX "%s: Address length = %d, Address = %pM\n",
+              __func__, netdev->addr_len, mac_addr->sa_data);
        macaddr_high  = ((u16)netdev->dev_addr[0]) << 8;
        macaddr_high += (u16)netdev->dev_addr[1];
        macaddr_low   = ((u32)netdev->dev_addr[2]) << 24;
@@ -909,9 +908,8 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
                        if (mc_index >= max_pft_entries_avaiable)
                                break;
                        if (multicast_addr) {
-                               DECLARE_MAC_BUF(mac);
-                               nes_debug(NES_DBG_NIC_RX, "Assigning MC Address %s to register 0x%04X nic_idx=%d\n",
-                                         print_mac(mac, multicast_addr->dmi_addr),
+                               nes_debug(NES_DBG_NIC_RX, "Assigning MC Address %pM to register 0x%04X nic_idx=%d\n",
+                                         multicast_addr->dmi_addr,
                                          perfect_filter_register_address+(mc_index * 8),
                                          mc_nic_index);
                                macaddr_high  = ((u16)multicast_addr->dmi_addr[0]) << 8;
index fb8cbd71a2ef86b17b98539a471e0c4d7bf7b409..9f16f7a89efc6ffaf5389012d0db8c96258dfd0f 100644 (file)
@@ -679,9 +679,8 @@ int nes_arp_table(struct nes_device *nesdev, u32 ip_addr, u8 *mac_addr, u32 acti
 
        /* DELETE or RESOLVE */
        if (arp_index == nesadapter->arp_table_size) {
-               nes_debug(NES_DBG_NETDEV, "MAC for " NIPQUAD_FMT " not in ARP table - cannot %s\n",
-                         HIPQUAD(ip_addr),
-                         action == NES_ARP_RESOLVE ? "resolve" : "delete");
+               nes_debug(NES_DBG_NETDEV, "MAC for %pI4 not in ARP table - cannot %s\n",
+                         &ip_addr, action == NES_ARP_RESOLVE ? "resolve" : "delete");
                return -1;
        }
 
index e0c7dfabf2b4e6d6f13abab65ffcc4d11dffefcb..753a983a5fdc8c85d6467e430f27bef4afc716b1 100644 (file)
@@ -732,29 +732,6 @@ extern int ipoib_debug_level;
        do { (void) (priv); } while (0)
 #endif /* CONFIG_INFINIBAND_IPOIB_DEBUG_DATA */
 
-
-#define IPOIB_GID_FMT          "%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:" \
-                               "%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x:%2.2x%2.2x"
-
-#define IPOIB_GID_RAW_ARG(gid) ((u8 *)(gid))[0], \
-                               ((u8 *)(gid))[1], \
-                               ((u8 *)(gid))[2], \
-                               ((u8 *)(gid))[3], \
-                               ((u8 *)(gid))[4], \
-                               ((u8 *)(gid))[5], \
-                               ((u8 *)(gid))[6], \
-                               ((u8 *)(gid))[7], \
-                               ((u8 *)(gid))[8], \
-                               ((u8 *)(gid))[9], \
-                               ((u8 *)(gid))[10],\
-                               ((u8 *)(gid))[11],\
-                               ((u8 *)(gid))[12],\
-                               ((u8 *)(gid))[13],\
-                               ((u8 *)(gid))[14],\
-                               ((u8 *)(gid))[15]
-
-#define IPOIB_GID_ARG(gid)     IPOIB_GID_RAW_ARG((gid).raw)
-
 #define IPOIB_QPN(ha) (be32_to_cpup((__be32 *) ha) & 0xffffff)
 
 #endif /* _IPOIB_H */
index 7b14c2c395008fc2acc3b38505c81cbeb3111929..47d588ba2a7f73e830c249b7546c441c93e26fcf 100644 (file)
@@ -1128,8 +1128,8 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn,
                goto err_send_cm;
        }
 
-       ipoib_dbg(priv, "Request connection 0x%x for gid " IPOIB_GID_FMT " qpn 0x%x\n",
-                 p->qp->qp_num, IPOIB_GID_ARG(pathrec->dgid), qpn);
+       ipoib_dbg(priv, "Request connection 0x%x for gid %pI6 qpn 0x%x\n",
+                 p->qp->qp_num, pathrec->dgid.raw, qpn);
 
        return 0;
 
@@ -1276,8 +1276,8 @@ void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx)
        if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) {
                list_move(&tx->list, &priv->cm.reap_list);
                queue_work(ipoib_workqueue, &priv->cm.reap_task);
-               ipoib_dbg(priv, "Reap connection for gid " IPOIB_GID_FMT "\n",
-                         IPOIB_GID_ARG(tx->neigh->dgid));
+               ipoib_dbg(priv, "Reap connection for gid %pI6\n",
+                         tx->neigh->dgid.raw);
                tx->neigh = NULL;
        }
 }
index 85257f6b9576f77b6a5e24820ad895267d65e50c..19e06bc38b39e88c877aa9d29e49c85bfde9c84e 100644 (file)
@@ -360,9 +360,9 @@ void ipoib_mark_paths_invalid(struct net_device *dev)
        spin_lock_irq(&priv->lock);
 
        list_for_each_entry_safe(path, tp, &priv->path_list, list) {
-               ipoib_dbg(priv, "mark path LID 0x%04x GID " IPOIB_GID_FMT " invalid\n",
+               ipoib_dbg(priv, "mark path LID 0x%04x GID %pI6 invalid\n",
                        be16_to_cpu(path->pathrec.dlid),
-                       IPOIB_GID_ARG(path->pathrec.dgid));
+                       path->pathrec.dgid.raw);
                path->valid =  0;
        }
 
@@ -414,11 +414,11 @@ static void path_rec_completion(int status,
        unsigned long flags;
 
        if (!status)
-               ipoib_dbg(priv, "PathRec LID 0x%04x for GID " IPOIB_GID_FMT "\n",
-                         be16_to_cpu(pathrec->dlid), IPOIB_GID_ARG(pathrec->dgid));
+               ipoib_dbg(priv, "PathRec LID 0x%04x for GID %pI6\n",
+                         be16_to_cpu(pathrec->dlid), pathrec->dgid.raw);
        else
-               ipoib_dbg(priv, "PathRec status %d for GID " IPOIB_GID_FMT "\n",
-                         status, IPOIB_GID_ARG(path->pathrec.dgid));
+               ipoib_dbg(priv, "PathRec status %d for GID %pI6\n",
+                         status, path->pathrec.dgid.raw);
 
        skb_queue_head_init(&skqueue);
 
@@ -528,8 +528,8 @@ static int path_rec_start(struct net_device *dev,
 {
        struct ipoib_dev_priv *priv = netdev_priv(dev);
 
-       ipoib_dbg(priv, "Start path record lookup for " IPOIB_GID_FMT "\n",
-                 IPOIB_GID_ARG(path->pathrec.dgid));
+       ipoib_dbg(priv, "Start path record lookup for %pI6\n",
+                 path->pathrec.dgid.raw);
 
        init_completion(&path->done);
 
@@ -766,12 +766,11 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
                        if ((be16_to_cpup((__be16 *) skb->data) != ETH_P_ARP) &&
                            (be16_to_cpup((__be16 *) skb->data) != ETH_P_RARP)) {
-                               ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x "
-                                          IPOIB_GID_FMT "\n",
+                               ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n",
                                           skb->dst ? "neigh" : "dst",
                                           be16_to_cpup((__be16 *) skb->data),
                                           IPOIB_QPN(phdr->hwaddr),
-                                          IPOIB_GID_RAW_ARG(phdr->hwaddr + 4));
+                                          phdr->hwaddr + 4);
                                dev_kfree_skb_any(skb);
                                ++dev->stats.tx_dropped;
                                return NETDEV_TX_OK;
@@ -847,9 +846,9 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
        else
                return;
        ipoib_dbg(priv,
-                 "neigh_cleanup for %06x " IPOIB_GID_FMT "\n",
+                 "neigh_cleanup for %06x %pI6\n",
                  IPOIB_QPN(n->ha),
-                 IPOIB_GID_RAW_ARG(n->ha + 4));
+                 n->ha + 4);
 
        spin_lock_irqsave(&priv->lock, flags);
 
index d9d1223c3fd5f7dc1609764c9a1db16e3a20018f..a2eb3b9789ebabb08f69f3b0421128900db22bd6 100644 (file)
@@ -71,9 +71,8 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
        struct ipoib_neigh *neigh, *tmp;
        int tx_dropped = 0;
 
-       ipoib_dbg_mcast(netdev_priv(dev),
-                       "deleting multicast group " IPOIB_GID_FMT "\n",
-                       IPOIB_GID_ARG(mcast->mcmember.mgid));
+       ipoib_dbg_mcast(netdev_priv(dev), "deleting multicast group %pI6\n",
+                       mcast->mcmember.mgid.raw);
 
        spin_lock_irq(&priv->lock);
 
@@ -205,9 +204,8 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
 
        if (!test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
                if (test_and_set_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) {
-                       ipoib_warn(priv, "multicast group " IPOIB_GID_FMT
-                                  " already attached\n",
-                                  IPOIB_GID_ARG(mcast->mcmember.mgid));
+                       ipoib_warn(priv, "multicast group %pI6 already attached\n",
+                                  mcast->mcmember.mgid.raw);
 
                        return 0;
                }
@@ -215,9 +213,8 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
                ret = ipoib_mcast_attach(dev, be16_to_cpu(mcast->mcmember.mlid),
                                         &mcast->mcmember.mgid, set_qkey);
                if (ret < 0) {
-                       ipoib_warn(priv, "couldn't attach QP to multicast group "
-                                  IPOIB_GID_FMT "\n",
-                                  IPOIB_GID_ARG(mcast->mcmember.mgid));
+                       ipoib_warn(priv, "couldn't attach QP to multicast group %pI6\n",
+                                  mcast->mcmember.mgid.raw);
 
                        clear_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags);
                        return ret;
@@ -248,9 +245,8 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
                        mcast->ah = ah;
                        spin_unlock_irq(&priv->lock);
 
-                       ipoib_dbg_mcast(priv, "MGID " IPOIB_GID_FMT
-                                       " AV %p, LID 0x%04x, SL %d\n",
-                                       IPOIB_GID_ARG(mcast->mcmember.mgid),
+                       ipoib_dbg_mcast(priv, "MGID %pI6 AV %p, LID 0x%04x, SL %d\n",
+                                       mcast->mcmember.mgid.raw,
                                        mcast->ah->ah,
                                        be16_to_cpu(mcast->mcmember.mlid),
                                        mcast->mcmember.sl);
@@ -295,9 +291,8 @@ ipoib_mcast_sendonly_join_complete(int status,
 
        if (status) {
                if (mcast->logcount++ < 20)
-                       ipoib_dbg_mcast(netdev_priv(dev), "multicast join failed for "
-                                       IPOIB_GID_FMT ", status %d\n",
-                                       IPOIB_GID_ARG(mcast->mcmember.mgid), status);
+                       ipoib_dbg_mcast(netdev_priv(dev), "multicast join failed for %pI6, status %d\n",
+                                       mcast->mcmember.mgid.raw, status);
 
                /* Flush out any queued packets */
                netif_tx_lock_bh(dev);
@@ -356,9 +351,8 @@ static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast)
                ipoib_warn(priv, "ib_sa_join_multicast failed (ret = %d)\n",
                           ret);
        } else {
-               ipoib_dbg_mcast(priv, "no multicast record for " IPOIB_GID_FMT
-                               ", starting join\n",
-                               IPOIB_GID_ARG(mcast->mcmember.mgid));
+               ipoib_dbg_mcast(priv, "no multicast record for %pI6, starting join\n",
+                               mcast->mcmember.mgid.raw);
        }
 
        return ret;
@@ -386,9 +380,8 @@ static int ipoib_mcast_join_complete(int status,
        struct net_device *dev = mcast->dev;
        struct ipoib_dev_priv *priv = netdev_priv(dev);
 
-       ipoib_dbg_mcast(priv, "join completion for " IPOIB_GID_FMT
-                       " (status %d)\n",
-                       IPOIB_GID_ARG(mcast->mcmember.mgid), status);
+       ipoib_dbg_mcast(priv, "join completion for %pI6 (status %d)\n",
+                       mcast->mcmember.mgid.raw, status);
 
        /* We trap for port events ourselves. */
        if (status == -ENETRESET)
@@ -417,15 +410,11 @@ static int ipoib_mcast_join_complete(int status,
 
        if (mcast->logcount++ < 20) {
                if (status == -ETIMEDOUT) {
-                       ipoib_dbg_mcast(priv, "multicast join failed for " IPOIB_GID_FMT
-                                       ", status %d\n",
-                                       IPOIB_GID_ARG(mcast->mcmember.mgid),
-                                       status);
+                       ipoib_dbg_mcast(priv, "multicast join failed for %pI6, status %d\n",
+                                       mcast->mcmember.mgid.raw, status);
                } else {
-                       ipoib_warn(priv, "multicast join failed for "
-                                  IPOIB_GID_FMT ", status %d\n",
-                                  IPOIB_GID_ARG(mcast->mcmember.mgid),
-                                  status);
+                       ipoib_warn(priv, "multicast join failed for %pI6, status %d\n",
+                                  mcast->mcmember.mgid.raw, status);
                }
        }
 
@@ -457,8 +446,7 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast,
        ib_sa_comp_mask comp_mask;
        int ret = 0;
 
-       ipoib_dbg_mcast(priv, "joining MGID " IPOIB_GID_FMT "\n",
-                       IPOIB_GID_ARG(mcast->mcmember.mgid));
+       ipoib_dbg_mcast(priv, "joining MGID %pI6\n", mcast->mcmember.mgid.raw);
 
        rec.mgid     = mcast->mcmember.mgid;
        rec.port_gid = priv->local_gid;
@@ -643,8 +631,8 @@ static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
                ib_sa_free_multicast(mcast->mc);
 
        if (test_and_clear_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) {
-               ipoib_dbg_mcast(priv, "leaving MGID " IPOIB_GID_FMT "\n",
-                               IPOIB_GID_ARG(mcast->mcmember.mgid));
+               ipoib_dbg_mcast(priv, "leaving MGID %pI6\n",
+                               mcast->mcmember.mgid.raw);
 
                /* Remove ourselves from the multicast group */
                ret = ib_detach_mcast(priv->qp, &mcast->mcmember.mgid,
@@ -675,8 +663,8 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
        mcast = __ipoib_mcast_find(dev, mgid);
        if (!mcast) {
                /* Let's create a new send only group now */
-               ipoib_dbg_mcast(priv, "setting up send only multicast group for "
-                               IPOIB_GID_FMT "\n", IPOIB_GID_RAW_ARG(mgid));
+               ipoib_dbg_mcast(priv, "setting up send only multicast group for %pI6\n",
+                               mgid);
 
                mcast = ipoib_mcast_alloc(dev, 0);
                if (!mcast) {
@@ -809,14 +797,14 @@ void ipoib_mcast_restart_task(struct work_struct *work)
                        /* ignore group which is directly joined by userspace */
                        if (test_bit(IPOIB_FLAG_UMCAST, &priv->flags) &&
                            !ib_sa_get_mcmember_rec(priv->ca, priv->port, &mgid, &rec)) {
-                               ipoib_dbg_mcast(priv, "ignoring multicast entry for mgid "
-                                               IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mgid));
+                               ipoib_dbg_mcast(priv, "ignoring multicast entry for mgid %pI6\n",
+                                               mgid.raw);
                                continue;
                        }
 
                        /* Not found or send-only group, let's add a new entry */
-                       ipoib_dbg_mcast(priv, "adding multicast entry for mgid "
-                                       IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mgid));
+                       ipoib_dbg_mcast(priv, "adding multicast entry for mgid %pI6\n",
+                                       mgid.raw);
 
                        nmcast = ipoib_mcast_alloc(dev, 0);
                        if (!nmcast) {
@@ -849,8 +837,8 @@ void ipoib_mcast_restart_task(struct work_struct *work)
        list_for_each_entry_safe(mcast, tmcast, &priv->multicast_list, list) {
                if (!test_bit(IPOIB_MCAST_FLAG_FOUND, &mcast->flags) &&
                    !test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
-                       ipoib_dbg_mcast(priv, "deleting multicast group " IPOIB_GID_FMT "\n",
-                                       IPOIB_GID_ARG(mcast->mcmember.mgid));
+                       ipoib_dbg_mcast(priv, "deleting multicast group %pI6\n",
+                                       mcast->mcmember.mgid.raw);
 
                        rb_erase(&mcast->rb_node, &priv->multicast_tree);
 
index 26ff6214a81f4b64ac2a0b406ece8febcbfbac59..e418b960e3349576ad5284dec9ed0a739ebc1b18 100644 (file)
@@ -515,14 +515,14 @@ int iser_connect(struct iser_conn   *ib_conn,
        struct sockaddr *src, *dst;
        int err = 0;
 
-       sprintf(ib_conn->name,"%d.%d.%d.%d:%d",
-               NIPQUAD(dst_addr->sin_addr.s_addr), dst_addr->sin_port);
+       sprintf(ib_conn->name, "%pI4:%d",
+               &dst_addr->sin_addr.s_addr, dst_addr->sin_port);
 
        /* the device is known only --after-- address resolution */
        ib_conn->device = NULL;
 
-       iser_err("connecting to: %d.%d.%d.%d, port 0x%x\n",
-                NIPQUAD(dst_addr->sin_addr), dst_addr->sin_port);
+       iser_err("connecting to: %pI4, port 0x%x\n",
+                &dst_addr->sin_addr, dst_addr->sin_port);
 
        ib_conn->state = ISER_CONN_PENDING;
 
index 5b8b533f29089a7ccd428abffa65136ae8cb30e0..7c13db885bf67defc836d8d60552865ff0041a62 100644 (file)
@@ -1514,15 +1514,7 @@ static ssize_t show_dgid(struct device *dev, struct device_attribute *attr,
            target->state == SRP_TARGET_REMOVED)
                return -ENODEV;
 
-       return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[0]),
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[1]),
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[2]),
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[3]),
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[4]),
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[5]),
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[6]),
-                      be16_to_cpu(((__be16 *) target->path.dgid.raw)[7]));
+       return sprintf(buf, "%pI6\n", target->path.dgid.raw);
 }
 
 static ssize_t show_orig_dgid(struct device *dev,
@@ -1534,15 +1526,7 @@ static ssize_t show_orig_dgid(struct device *dev,
            target->state == SRP_TARGET_REMOVED)
                return -ENODEV;
 
-       return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
-                      be16_to_cpu(target->orig_dgid[0]),
-                      be16_to_cpu(target->orig_dgid[1]),
-                      be16_to_cpu(target->orig_dgid[2]),
-                      be16_to_cpu(target->orig_dgid[3]),
-                      be16_to_cpu(target->orig_dgid[4]),
-                      be16_to_cpu(target->orig_dgid[5]),
-                      be16_to_cpu(target->orig_dgid[6]),
-                      be16_to_cpu(target->orig_dgid[7]));
+       return sprintf(buf, "%pI6\n", target->orig_dgid);
 }
 
 static ssize_t show_zero_req_lim(struct device *dev,
@@ -1883,19 +1867,12 @@ static ssize_t srp_create_target(struct device *dev,
 
        shost_printk(KERN_DEBUG, target->scsi_host, PFX
                     "new target: id_ext %016llx ioc_guid %016llx pkey %04x "
-                    "service_id %016llx dgid %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+                    "service_id %016llx dgid %pI6\n",
               (unsigned long long) be64_to_cpu(target->id_ext),
               (unsigned long long) be64_to_cpu(target->ioc_guid),
               be16_to_cpu(target->path.pkey),
               (unsigned long long) be64_to_cpu(target->service_id),
-              (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[0]),
-              (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[2]),
-              (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[4]),
-              (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[6]),
-              (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[8]),
-              (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[10]),
-              (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[12]),
-              (int) be16_to_cpu(*(__be16 *) &target->path.dgid.raw[14]));
+              target->path.dgid.raw);
 
        ret = srp_create_target_ib(target);
        if (ret)
index 1bfc55d7a26c745d226f840edcfd784dd6930985..ad17a47ecc060d832a4cab896e94ce653f484925 100644 (file)
@@ -890,15 +890,15 @@ isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp)
                proto = ETH_P_IP;
                switch (lp->p_encap) {
                        case ISDN_NET_ENCAP_IPTYP:
-                               proto = ntohs(*(unsigned short *) &buf[0]);
+                               proto = ntohs(*(__be16 *)&buf[0]);
                                p = &buf[2];
                                break;
                        case ISDN_NET_ENCAP_ETHER:
-                               proto = ntohs(*(unsigned short *) &buf[12]);
+                               proto = ntohs(*(__be16 *)&buf[12]);
                                p = &buf[14];
                                break;
                        case ISDN_NET_ENCAP_CISCOHDLC:
-                               proto = ntohs(*(unsigned short *) &buf[2]);
+                               proto = ntohs(*(__be16 *)&buf[2]);
                                p = &buf[4];
                                break;
 #ifdef CONFIG_ISDN_PPP
@@ -942,18 +942,12 @@ isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp)
                                        strcpy(addinfo, " IDP");
                                        break;
                        }
-                       printk(KERN_INFO
-                               "OPEN: %d.%d.%d.%d -> %d.%d.%d.%d%s\n",
-
-                              p[12], p[13], p[14], p[15],
-                              p[16], p[17], p[18], p[19],
-                              addinfo);
+                       printk(KERN_INFO "OPEN: %pI4 -> %pI4%s\n",
+                              p + 12, p + 16, addinfo);
                        break;
                case ETH_P_ARP:
-                       printk(KERN_INFO
-                               "OPEN: ARP %d.%d.%d.%d -> *.*.*.* ?%d.%d.%d.%d\n",
-                              p[14], p[15], p[16], p[17],
-                              p[24], p[25], p[26], p[27]);
+                       printk(KERN_INFO "OPEN: ARP %pI4 -> *.*.*.* ?%pI4\n",
+                              p + 14, p + 24);
                        break;
        }
 }
@@ -1539,15 +1533,16 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
        p = skb_put(skb, 4 + 14);
 
        /* cisco header */
-       p += put_u8 (p, CISCO_ADDR_UNICAST);
-       p += put_u8 (p, CISCO_CTRL);
-       p += put_u16(p, CISCO_TYPE_SLARP);
+       *(u8 *)(p + 0) = CISCO_ADDR_UNICAST;
+       *(u8 *)(p + 1) = CISCO_CTRL;
+       *(__be16 *)(p + 2) = cpu_to_be16(CISCO_TYPE_SLARP);
 
        /* slarp keepalive */
-       p += put_u32(p, CISCO_SLARP_KEEPALIVE);
-       p += put_u32(p, lp->cisco_myseq);
-       p += put_u32(p, lp->cisco_yourseq);
-       p += put_u16(p, 0xffff); // reliablity, always 0xffff
+       *(__be32 *)(p +  4) = cpu_to_be32(CISCO_SLARP_KEEPALIVE);
+       *(__be32 *)(p +  8) = cpu_to_be32(lp->cisco_myseq);
+       *(__be32 *)(p + 12) = cpu_to_be32(lp->cisco_yourseq);
+       *(__be16 *)(p + 16) = cpu_to_be16(0xffff); // reliablity, always 0xffff
+       p += 18;
 
        isdn_net_write_super(lp, skb);
 
@@ -1569,15 +1564,16 @@ isdn_net_ciscohdlck_slarp_send_request(isdn_net_local *lp)
        p = skb_put(skb, 4 + 14);
 
        /* cisco header */
-       p += put_u8 (p, CISCO_ADDR_UNICAST);
-       p += put_u8 (p, CISCO_CTRL);
-       p += put_u16(p, CISCO_TYPE_SLARP);
+       *(u8 *)(p + 0) = CISCO_ADDR_UNICAST;
+       *(u8 *)(p + 1) = CISCO_CTRL;
+       *(__be16 *)(p + 2) = cpu_to_be16(CISCO_TYPE_SLARP);
 
        /* slarp request */
-       p += put_u32(p, CISCO_SLARP_REQUEST);
-       p += put_u32(p, 0); // address
-       p += put_u32(p, 0); // netmask
-       p += put_u16(p, 0); // unused
+       *(__be32 *)(p +  4) = cpu_to_be32(CISCO_SLARP_REQUEST);
+       *(__be32 *)(p +  8) = cpu_to_be32(0); // address
+       *(__be32 *)(p + 12) = cpu_to_be32(0); // netmask
+       *(__be16 *)(p + 16) = cpu_to_be16(0); // unused
+       p += 18;
 
        isdn_net_write_super(lp, skb);
 }
@@ -1634,18 +1630,17 @@ isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp)
        p = skb_put(skb, 4 + 14);
 
        /* cisco header */
-       p += put_u8 (p, CISCO_ADDR_UNICAST);
-       p += put_u8 (p, CISCO_CTRL);
-       p += put_u16(p, CISCO_TYPE_SLARP);
+       *(u8 *)(p + 0) = CISCO_ADDR_UNICAST;
+       *(u8 *)(p + 1) = CISCO_CTRL;
+       *(__be16 *)(p + 2) = cpu_to_be16(CISCO_TYPE_SLARP);
 
        /* slarp reply, send own ip/netmask; if values are nonsense remote
         * should think we are unable to provide it with an address via SLARP */
-       p += put_u32(p, CISCO_SLARP_REPLY);
-       *(__be32 *)p = addr;    // address
-       p += 4;
-       *(__be32 *)p = mask;    // netmask
-       p += 4;
-       p += put_u16(p, 0);     // unused
+       *(__be32 *)(p +  4) = cpu_to_be32(CISCO_SLARP_REPLY);
+       *(__be32 *)(p +  8) = addr; // address
+       *(__be32 *)(p + 12) = mask; // netmask
+       *(__be16 *)(p + 16) = cpu_to_be16(0); // unused
+       p += 18;
 
        isdn_net_write_super(lp, skb);
 }
@@ -1656,44 +1651,39 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
        unsigned char *p;
        int period;
        u32 code;
-       u32 my_seq, addr;
-       u32 your_seq, mask;
-       u32 local;
+       u32 my_seq;
+       u32 your_seq;
+       __be32 local;
+       __be32 *addr, *mask;
        u16 unused;
 
        if (skb->len < 14)
                return;
 
        p = skb->data;
-       p += get_u32(p, &code);
-       
+       code = be32_to_cpup((__be32 *)p);
+       p += 4;
+
        switch (code) {
        case CISCO_SLARP_REQUEST:
                lp->cisco_yourseq = 0;
                isdn_net_ciscohdlck_slarp_send_reply(lp);
                break;
        case CISCO_SLARP_REPLY:
-               addr = ntohl(*(u32 *)p);
-               mask = ntohl(*(u32 *)(p+4));
-               if (mask != 0xfffffffc)
+               addr = (__be32 *)p;
+               mask = (__be32 *)(p + 4);
+               if (*mask != cpu_to_be32(0xfffffffc))
                        goto slarp_reply_out;
-               if ((addr & 3) == 0 || (addr & 3) == 3)
+               if ((*addr & cpu_to_be32(3)) == cpu_to_be32(0) ||
+                   (*addr & cpu_to_be32(3)) == cpu_to_be32(3))
                        goto slarp_reply_out;
-               local = addr ^ 3;
-               printk(KERN_INFO "%s: got slarp reply: "
-                       "remote ip: %d.%d.%d.%d, "
-                       "local ip: %d.%d.%d.%d "
-                       "mask: %d.%d.%d.%d\n",
-                      lp->netdev->dev->name,
-                      HIPQUAD(addr),
-                      HIPQUAD(local),
-                      HIPQUAD(mask));
+               local = *addr ^ cpu_to_be32(3);
+               printk(KERN_INFO "%s: got slarp reply: remote ip: %pI4, local ip: %pI4 mask: %pI4\n",
+                      lp->netdev->dev->name, addr, &local, mask);
                break;
   slarp_reply_out:
-                printk(KERN_INFO "%s: got invalid slarp "
-                                "reply (%d.%d.%d.%d/%d.%d.%d.%d) "
-                                "- ignored\n", lp->netdev->dev->name,
-                                HIPQUAD(addr), HIPQUAD(mask));
+               printk(KERN_INFO "%s: got invalid slarp reply (%pI4/%pI4) - ignored\n",
+                      lp->netdev->dev->name, addr, mask);
                break;
        case CISCO_SLARP_KEEPALIVE:
                period = (int)((jiffies - lp->cisco_last_slarp_in
@@ -1707,9 +1697,10 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
                                lp->cisco_keepalive_period);
                }
                lp->cisco_last_slarp_in = jiffies;
-               p += get_u32(p, &my_seq);
-               p += get_u32(p, &your_seq);
-               p += get_u16(p, &unused);
+               my_seq = be32_to_cpup((__be32 *)(p + 0));
+               your_seq = be32_to_cpup((__be32 *)(p + 4));
+               unused = be16_to_cpup((__be16 *)(p + 8));
+               p += 10;
                lp->cisco_yourseq = my_seq;
                lp->cisco_mineseen = your_seq;
                break;
@@ -1728,9 +1719,10 @@ isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb)
                goto out_free;
 
        p = skb->data;
-       p += get_u8 (p, &addr);
-       p += get_u8 (p, &ctrl);
-       p += get_u16(p, &type);
+       addr = *(u8 *)(p + 0);
+       ctrl = *(u8 *)(p + 1);
+       type = be16_to_cpup((__be16 *)(p + 2));
+       p += 4;
        skb_pull(skb, 4);
        
        if (addr != CISCO_ADDR_UNICAST && addr != CISCO_ADDR_BROADCAST) {
@@ -1918,9 +1910,10 @@ static int isdn_net_header(struct sk_buff *skb, struct net_device *dev,
                case ISDN_NET_ENCAP_CISCOHDLC:
                case ISDN_NET_ENCAP_CISCOHDLCK:
                        p = skb_push(skb, 4);
-                       p += put_u8 (p, CISCO_ADDR_UNICAST);
-                       p += put_u8 (p, CISCO_CTRL);
-                       p += put_u16(p, type);
+                       *(u8 *)(p + 0) = CISCO_ADDR_UNICAST;
+                       *(u8 *)(p + 1) = CISCO_CTRL;
+                       *(__be16 *)(p + 2) = cpu_to_be16(type);
+                       p += 4;
                        len = 4;
                        break;
 #ifdef CONFIG_ISDN_X25
index be4949715d55f605206f99e86430fe0c46ff1f1d..2a6c370ea87f6ecc1ea98d1c6ae91954675156fb 100644 (file)
@@ -145,46 +145,3 @@ static __inline__ void isdn_net_rm_from_bundle(isdn_net_local *lp)
        spin_unlock_irqrestore(&master_lp->netdev->queue_lock, flags);
 }
 
-static inline int
-put_u8(unsigned char *p, u8 x)
-{
-       *p = x;
-       return 1;
-}
-
-static inline int
-put_u16(unsigned char *p, u16 x)
-{
-       *((u16 *)p) = htons(x);
-       return 2;
-}
-
-static inline int
-put_u32(unsigned char *p, u32 x)
-{
-       *((u32 *)p) = htonl(x);
-       return 4;
-}
-
-static inline int
-get_u8(unsigned char *p, u8 *x)
-{
-       *x = *p;
-       return 1;
-}
-
-static inline int
-get_u16(unsigned char *p, u16 *x)
-{
-       *x = ntohs(*((u16 *)p));
-       return 2;
-}
-
-static inline int
-get_u32(unsigned char *p, u32 *x)
-{
-       *x = ntohl(*((u32 *)p));
-       return 4;
-}
-
-
index 5f79c8dc383651aa9349e3445f854d24947aab9a..676413a915b45c3302995dfe82d49d283843c625 100644 (file)
@@ -270,7 +270,7 @@ int flexcop_device_initialize(struct flexcop_device *fc)
        /* do the MAC address reading after initializing the dvb_adapter */
        if (fc->get_mac_addr(fc, 0) == 0) {
                u8 *b = fc->dvb_adapter.proposed_mac;
-               info("MAC address = %02x:%02x:%02x:%02x:%02x:%02x", b[0],b[1],b[2],b[3],b[4],b[5]);
+               info("MAC address = %pM", b);
                flexcop_set_mac_filter(fc,b);
                flexcop_mac_filter_ctrl(fc,1);
        } else
index aa3db57d32d94ce7ac01abb81b3ab41bbb501e2a..29e8f1546ab6d3dbafc2cd7ede40485fb771deea 100644 (file)
@@ -917,9 +917,7 @@ static int dst_get_mac(struct dst_state *state)
        }
        memset(&state->mac_address, '\0', 8);
        memcpy(&state->mac_address, &state->rxbuffer, 6);
-       dprintk(verbose, DST_ERROR, 1, "MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]",
-               state->mac_address[0], state->mac_address[1], state->mac_address[2],
-               state->mac_address[4], state->mac_address[5], state->mac_address[6]);
+       dprintk(verbose, DST_ERROR, 1, "MAC Address=[%pM]", state->mac_address);
 
        return 0;
 }
index 14e627ef6465f28dc88fc07bd5bd6c5c8e1e40af..d15984e599bce99ed03ff96ee597ebb9b921b17b 100644 (file)
@@ -697,8 +697,7 @@ static void __devinit dm1105dvb_read_mac(struct dm1105dvb *dm1105dvb, u8 *mac)
        };
 
        dm1105_i2c_xfer(&dm1105dvb->i2c_adap, msg , 2);
-       dev_info(&dm1105dvb->pdev->dev, "MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
-                       mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+       dev_info(&dm1105dvb->pdev->dev, "MAC %pM\n", mac);
 }
 
 static int __devinit dm1105_probe(struct pci_dev *pdev,
index ce8cd0c5d83120b173ad5fa4950d1f43a8c0a585..8a7d87bcd1d98b71c3bbbd6b62150ad8c9e8fba9 100644 (file)
@@ -91,10 +91,7 @@ int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums)
 
        if (adap->dev->props.read_mac_address) {
                if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0)
-                       info("MAC address: %02x:%02x:%02x:%02x:%02x:%02x",adap->dvb_adap.proposed_mac[0],
-                                       adap->dvb_adap.proposed_mac[1], adap->dvb_adap.proposed_mac[2],
-                                       adap->dvb_adap.proposed_mac[3], adap->dvb_adap.proposed_mac[4],
-                                       adap->dvb_adap.proposed_mac[5]);
+                       info("MAC address: %pM",adap->dvb_adap.proposed_mac);
                else
                        err("MAC address reading failed.");
        }
index a9653c63f4db8350b5fb66c4e184b6d44a16421f..d101b304e9b0e7348614ec4ec2c8d28e15a31317 100644 (file)
@@ -560,8 +560,7 @@ static void __devinit pluto_read_mac(struct pluto *pluto, u8 *mac)
        mac[4] = (val >> 8) & 0xff;
        mac[5] = (val >> 0) & 0xff;
 
-       dev_info(&pluto->pdev->dev, "MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
-                       mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+       dev_info(&pluto->pdev->dev, "MAC %pM\n", mac);
 }
 
 static int __devinit pluto_read_serial(struct pluto *pluto)
index 603ffd008c73fb65275e1001af623f02332163d8..eeef0bd077f4492e32461725ad3d642a0c1f7e41 100644 (file)
@@ -1427,11 +1427,9 @@ mptlan_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                printk(KERN_INFO MYNAM ": %s: Fusion MPT LAN device "
                       "registered as '%s'\n", ioc->name, dev->name);
                printk(KERN_INFO MYNAM ": %s/%s: "
-                      "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
+                      "LanAddr = %pM\n",
                       IOC_AND_NETDEV_NAMES_s_s(dev),
-                      dev->dev_addr[0], dev->dev_addr[1],
-                      dev->dev_addr[2], dev->dev_addr[3],
-                      dev->dev_addr[4], dev->dev_addr[5]);
+                      dev->dev_addr);
        
                ioc->netdev = dev;
 
@@ -1516,9 +1514,8 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev)
 
                printk (KERN_WARNING MYNAM ": %s: WARNING - Broadcast swap F/W bug detected!\n",
                                NETDEV_PTR_TO_IOC_NAME_s(dev));
-               printk (KERN_WARNING MYNAM ": Please update sender @ MAC_addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
-                               fch->saddr[0], fch->saddr[1], fch->saddr[2],
-                               fch->saddr[3], fch->saddr[4], fch->saddr[5]);
+               printk (KERN_WARNING MYNAM ": Please update sender @ MAC_addr = %pM\n",
+                               fch->saddr);
        }
 
        if (*fch->daddr & 1) {
@@ -1537,7 +1534,6 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev)
 
        fcllc = (struct fcllc *)skb->data;
 
-
        /* Strip the SNAP header from ARP packets since we don't
         * pass them through to the 802.2/SNAP layers.
         */
index 7d15e7c6bcad51f65860ff6b42e09881e8e2064a..3d1318a3e6885901a5f1e4efab65b0964a5dc48e 100644 (file)
@@ -297,8 +297,8 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
        if (el_debug)
                printk(KERN_DEBUG "%s", version);
 
-       memset(dev->priv, 0, sizeof(struct net_local));
        lp = netdev_priv(dev);
+       memset(lp, 0, sizeof(struct net_local));
        spin_lock_init(&lp->lock);
 
        /*
@@ -725,7 +725,6 @@ static void el_receive(struct net_device *dev)
                insb(DATAPORT, skb_put(skb, pkt_len), pkt_len);
                skb->protocol = eth_type_trans(skb, dev);
                netif_rx(skb);
-               dev->last_rx = jiffies;
                dev->stats.rx_packets++;
                dev->stats.rx_bytes += pkt_len;
        }
index 900b0ffdcc686c576e5eefaddd973eff7a80b018..95bd95f1f99ee6cc3764749cf09b578d05e00c10 100644 (file)
@@ -177,7 +177,6 @@ el2_probe1(struct net_device *dev, int ioaddr)
     int i, iobase_reg, membase_reg, saved_406, wordlength, retval;
     static unsigned version_printed;
     unsigned long vendor_id;
-    DECLARE_MAC_BUF(mac);
 
     if (!request_region(ioaddr, EL2_IO_EXTENT, DRV_NAME))
        return -EBUSY;
@@ -228,7 +227,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
     /* Retrieve and print the ethernet address. */
     for (i = 0; i < 6; i++)
        dev->dev_addr[i] = inb(ioaddr + i);
-    printk("%s", print_mac(mac, dev->dev_addr));
+    printk("%pM", dev->dev_addr);
 
     /* Map the 8390 back into the window. */
     outb(ECNTRL_THIN, ioaddr + 0x406);
index a424869707a5225b1f04e9d2e070a87d1987f19a..6124605bef05404bb2dee77114d5f8fcd1a1aff8 100644 (file)
@@ -203,10 +203,10 @@ static inline int inb_command(unsigned int base_addr)
 static inline void outb_control(unsigned char val, struct net_device *dev)
 {
        outb(val, dev->base_addr + PORT_CONTROL);
-       ((elp_device *)(dev->priv))->hcr_val = val;
+       ((elp_device *)(netdev_priv(dev)))->hcr_val = val;
 }
 
-#define HCR_VAL(x)   (((elp_device *)((x)->priv))->hcr_val)
+#define HCR_VAL(x)   (((elp_device *)(netdev_priv(x)))->hcr_val)
 
 static inline void outb_command(unsigned char val, unsigned int base_addr)
 {
@@ -247,7 +247,7 @@ static inline int get_status(unsigned int base_addr)
 
 static inline void set_hsf(struct net_device *dev, int hsf)
 {
-       elp_device *adapter = dev->priv;
+       elp_device *adapter = netdev_priv(dev);
        unsigned long flags;
 
        spin_lock_irqsave(&adapter->lock, flags);
@@ -260,7 +260,7 @@ static bool start_receive(struct net_device *, pcb_struct *);
 static inline void adapter_reset(struct net_device *dev)
 {
        unsigned long timeout;
-       elp_device *adapter = dev->priv;
+       elp_device *adapter = netdev_priv(dev);
        unsigned char orig_hcr = adapter->hcr_val;
 
        outb_control(0, dev);
@@ -293,7 +293,7 @@ static inline void adapter_reset(struct net_device *dev)
  */
 static inline void check_3c505_dma(struct net_device *dev)
 {
-       elp_device *adapter = dev->priv;
+       elp_device *adapter = netdev_priv(dev);
        if (adapter->dmaing && time_after(jiffies, adapter->current_dma.start_time + 10)) {
                unsigned long flags, f;
                printk(KERN_ERR "%s: DMA %s timed out, %d bytes left\n", dev->name, adapter->current_dma.direction ? "download" : "upload", get_dma_residue(dev->dma));
@@ -340,7 +340,7 @@ static inline bool send_pcb_fast(unsigned int base_addr, unsigned char byte)
 /* Check to see if the receiver needs restarting, and kick it if so */
 static inline void prime_rx(struct net_device *dev)
 {
-       elp_device *adapter = dev->priv;
+       elp_device *adapter = netdev_priv(dev);
        while (adapter->rx_active < ELP_RX_PCBS && netif_running(dev)) {
                if (!start_receive(dev, &adapter->itx_pcb))
                        break;
@@ -375,7 +375,7 @@ static bool send_pcb(struct net_device *dev, pcb_struct * pcb)
 {
        int i;
        unsigned long timeout;
-       elp_device *adapter = dev->priv;
+       elp_device *adapter = netdev_priv(dev);
        unsigned long flags;
 
        check_3c505_dma(dev);
@@ -463,7 +463,7 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
        unsigned long timeout;
        unsigned long flags;
 
-       elp_device *adapter = dev->priv;
+       elp_device *adapter = netdev_priv(dev);
 
        set_hsf(dev, 0);
 
@@ -543,7 +543,7 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
 static bool start_receive(struct net_device *dev, pcb_struct * tx_pcb)
 {
        bool status;
-       elp_device *adapter = dev->priv;
+       elp_device *adapter = netdev_priv(dev);
 
        if (elp_debug >= 3)
                printk(KERN_DEBUG "%s: restarting receiver\n", dev->name);
@@ -571,7 +571,7 @@ static bool start_receive(struct net_device *dev, pcb_struct * tx_pcb)
 static void receive_packet(struct net_device *dev, int len)
 {
        int rlen;
-       elp_device *adapter = dev->priv;
+       elp_device *adapter = netdev_priv(dev);
        void *target;
        struct sk_buff *skb;
        unsigned long flags;
@@ -638,13 +638,10 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
        int len;
        int dlen;
        int icount = 0;
-       struct net_device *dev;
-       elp_device *adapter;
+       struct net_device *dev = dev_id;
+       elp_device *adapter = netdev_priv(dev);
        unsigned long timeout;
 
-       dev = dev_id;
-       adapter = (elp_device *) dev->priv;
-
        spin_lock(&adapter->lock);
 
        do {
@@ -672,7 +669,6 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
                                        skb->protocol = eth_type_trans(skb,dev);
                                        dev->stats.rx_bytes += skb->len;
                                        netif_rx(skb);
-                                       dev->last_rx = jiffies;
                                }
                        }
                        adapter->dmaing = 0;
@@ -838,11 +834,9 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
 
 static int elp_open(struct net_device *dev)
 {
-       elp_device *adapter;
+       elp_device *adapter = netdev_priv(dev);
        int retval;
 
-       adapter = dev->priv;
-
        if (elp_debug >= 3)
                printk(KERN_DEBUG "%s: request to open device\n", dev->name);
 
@@ -971,7 +965,7 @@ static int elp_open(struct net_device *dev)
 
 static bool send_packet(struct net_device *dev, struct sk_buff *skb)
 {
-       elp_device *adapter = dev->priv;
+       elp_device *adapter = netdev_priv(dev);
        unsigned long target;
        unsigned long flags;
 
@@ -1062,7 +1056,7 @@ static void elp_timeout(struct net_device *dev)
 static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        unsigned long flags;
-       elp_device *adapter = dev->priv;
+       elp_device *adapter = netdev_priv(dev);
 
        spin_lock_irqsave(&adapter->lock, flags);
        check_3c505_dma(dev);
@@ -1104,7 +1098,7 @@ static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static struct net_device_stats *elp_get_stats(struct net_device *dev)
 {
-       elp_device *adapter = (elp_device *) dev->priv;
+       elp_device *adapter = netdev_priv(dev);
 
        if (elp_debug >= 3)
                printk(KERN_DEBUG "%s: request for stats\n", dev->name);
@@ -1166,9 +1160,7 @@ static const struct ethtool_ops netdev_ethtool_ops = {
 
 static int elp_close(struct net_device *dev)
 {
-       elp_device *adapter;
-
-       adapter = dev->priv;
+       elp_device *adapter = netdev_priv(dev);
 
        if (elp_debug >= 3)
                printk(KERN_DEBUG "%s: request to close device\n", dev->name);
@@ -1209,7 +1201,7 @@ static int elp_close(struct net_device *dev)
 
 static void elp_set_mc_list(struct net_device *dev)
 {
-       elp_device *adapter = (elp_device *) dev->priv;
+       elp_device *adapter = netdev_priv(dev);
        struct dev_mc_list *dmi = dev->mc_list;
        int i;
        unsigned long flags;
@@ -1380,12 +1372,11 @@ static int __init elp_autodetect(struct net_device *dev)
 
 static int __init elplus_setup(struct net_device *dev)
 {
-       elp_device *adapter = dev->priv;
+       elp_device *adapter = netdev_priv(dev);
        int i, tries, tries1, okay;
        unsigned long timeout;
        unsigned long cookie = 0;
        int err = -ENODEV;
-       DECLARE_MAC_BUF(mac);
 
        /*
         *  setup adapter structure
@@ -1522,9 +1513,9 @@ static int __init elplus_setup(struct net_device *dev)
         * print remainder of startup message
         */
        printk(KERN_INFO "%s: 3c505 at %#lx, irq %d, dma %d, "
-              "addr %s, ",
+              "addr %pM, ",
               dev->name, dev->base_addr, dev->irq, dev->dma,
-              print_mac(mac, dev->dev_addr));
+              dev->dev_addr);
 
        /*
         * read more information from the adapter
index 030c147211baf1184662c7d69373277cd309474c..b8585ecd1d7881703bd4a670ff60b07d96bc747e 100644 (file)
@@ -357,7 +357,6 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
        static unsigned char init_ID_done, version_printed;
        int i, irq, irqval, retval;
        struct net_local *lp;
-       DECLARE_MAC_BUF(mac);
 
        if (init_ID_done == 0) {
                ushort lrs_state = 0xff;
@@ -405,7 +404,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
        outb(0x01, ioaddr + MISC_CTRL);
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = inb(ioaddr + i);
-       printk(" %s", print_mac(mac, dev->dev_addr));
+       printk(" %pM", dev->dev_addr);
 
        if (mem_start)
                net_debug = mem_start & 7;
@@ -866,7 +865,6 @@ static void el16_rx(struct net_device *dev)
 
                        skb->protocol=eth_type_trans(skb,dev);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                        dev->stats.rx_bytes += pkt_len;
                }
index c7a4f3bcc2bc1fd31f597304c6fff13ee0aaba3b..535c234286ea80c27f8a2ca8170b88b1b9c87208 100644 (file)
@@ -541,7 +541,6 @@ static int __devinit el3_common_init(struct net_device *dev)
 {
        struct el3_private *lp = netdev_priv(dev);
        int err;
-       DECLARE_MAC_BUF(mac);
        const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
 
        spin_lock_init(&lp->lock);
@@ -575,9 +574,9 @@ static int __devinit el3_common_init(struct net_device *dev)
        }
 
        printk(KERN_INFO "%s: 3c5x9 found at %#3.3lx, %s port, "
-              "address %s, IRQ %d.\n",
+              "address %pM, IRQ %d.\n",
               dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)],
-              print_mac(mac, dev->dev_addr), dev->irq);
+              dev->dev_addr, dev->irq);
 
        if (el3_debug > 0)
                printk(KERN_INFO "%s", version);
@@ -1075,7 +1074,6 @@ el3_rx(struct net_device *dev)
                                outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
                                skb->protocol = eth_type_trans(skb,dev);
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                                dev->stats.rx_bytes += pkt_len;
                                dev->stats.rx_packets++;
                                continue;
index a0f8b6e2d0af80af13b5774fe40ec9c5ee132db7..7f995008a45cd7469d867beeafb1a70c3e802489 100644 (file)
@@ -570,7 +570,6 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
        unsigned int eeprom[0x40], checksum = 0;        /* EEPROM contents */
        int i;
        int irq;
-       DECLARE_MAC_BUF(mac);
 
 #ifdef __ISAPNP__
        if (idev) {
@@ -636,7 +635,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
        checksum = (checksum ^ (checksum >> 8)) & 0xff;
        if (checksum != 0x00)
                printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
-       printk(" %s", print_mac(mac, dev->dev_addr));
+       printk(" %pM", dev->dev_addr);
        if (eeprom[16] == 0x11c7) {     /* Corkscrew */
                if (request_dma(dev->dma, "3c515")) {
                        printk(", DMA %d allocation failed", dev->dma);
@@ -1302,7 +1301,6 @@ static int corkscrew_rx(struct net_device *dev)
                                outw(RxDiscard, ioaddr + EL3_CMD);      /* Pop top Rx packet. */
                                skb->protocol = eth_type_trans(skb, dev);
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                                dev->stats.rx_packets++;
                                dev->stats.rx_bytes += pkt_len;
                                /* Wait a limited time to go to next packet. */
@@ -1389,7 +1387,6 @@ static int boomerang_rx(struct net_device *dev)
                        }
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                }
                entry = (++vp->cur_rx) % RX_RING_SIZE;
index e2ce41d3828ed47e90b31c7e09d7cb29649a1373..59ea2910bcac01f5108d1a0737b567e671339e54 100644 (file)
@@ -308,7 +308,7 @@ static int elmc_open(struct net_device *dev)
 
 static int __init check586(struct net_device *dev, unsigned long where, unsigned size)
 {
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
        char *iscp_addrs[2];
        int i = 0;
 
@@ -349,7 +349,7 @@ static int __init check586(struct net_device *dev, unsigned long where, unsigned
 
 void alloc586(struct net_device *dev)
 {
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        elmc_id_reset586();
        DELAY(2);
@@ -383,7 +383,6 @@ static int elmc_getinfo(char *buf, int slot, void *d)
 {
        int len = 0;
        struct net_device *dev = d;
-       DECLARE_MAC_BUF(mac);
 
        if (dev == NULL)
                return len;
@@ -398,8 +397,8 @@ static int elmc_getinfo(char *buf, int slot, void *d)
        len += sprintf(buf + len, "Transceiver: %s\n", dev->if_port ?
                       "External" : "Internal");
        len += sprintf(buf + len, "Device: %s\n", dev->name);
-       len += sprintf(buf + len, "Hardware Address: %s\n",
-                      print_mac(mac, dev->dev_addr));
+       len += sprintf(buf + len, "Hardware Address: %pM\n",
+                      dev->dev_addr);
 
        return len;
 }                              /* elmc_getinfo() */
@@ -416,8 +415,7 @@ static int __init do_elmc_probe(struct net_device *dev)
        int i = 0;
        unsigned int size = 0;
        int retval;
-       struct priv *pr = dev->priv;
-       DECLARE_MAC_BUF(mac);
+       struct priv *pr = netdev_priv(dev);
 
        if (MCA_bus == 0) {
                return -ENODEV;
@@ -543,8 +541,8 @@ static int __init do_elmc_probe(struct net_device *dev)
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = inb(dev->base_addr + i);
 
-       printk(KERN_INFO "%s: hardware address %s\n",
-              dev->name, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: hardware address %pM\n",
+              dev->name, dev->dev_addr);
 
        dev->open = &elmc_open;
        dev->stop = &elmc_close;
@@ -580,7 +578,8 @@ err_out:
 
 static void cleanup_card(struct net_device *dev)
 {
-       mca_set_adapter_procfn(((struct priv *) (dev->priv))->slot, NULL, NULL);
+       mca_set_adapter_procfn(((struct priv *)netdev_priv(dev))->slot,
+                               NULL, NULL);
        release_region(dev->base_addr, ELMC_IO_EXTENT);
 }
 
@@ -616,7 +615,7 @@ static int init586(struct net_device *dev)
        void *ptr;
        unsigned long s;
        int i, result = 0;
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
        volatile struct configure_cmd_struct *cfg_cmd;
        volatile struct iasetup_cmd_struct *ias_cmd;
        volatile struct tdr_cmd_struct *tdr_cmd;
@@ -852,7 +851,7 @@ static void *alloc_rfa(struct net_device *dev, void *ptr)
        volatile struct rfd_struct *rfd = (struct rfd_struct *) ptr;
        volatile struct rbd_struct *rbd;
        int i;
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        memset((char *) rfd, 0, sizeof(struct rfd_struct) * p->num_recv_buffs);
        p->rfd_first = rfd;
@@ -913,7 +912,7 @@ elmc_interrupt(int irq, void *dev_id)
        }
        /* reading ELMC_CTRL also clears the INT bit. */
 
-       p = (struct priv *) dev->priv;
+       p = netdev_priv(dev);
 
        while ((stat = p->scb->status & STAT_MASK))
        {
@@ -969,7 +968,7 @@ static void elmc_rcv_int(struct net_device *dev)
        unsigned short totlen;
        struct sk_buff *skb;
        struct rbd_struct *rbd;
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        for (; (status = p->rfd_top->status) & STAT_COMPL;) {
                rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
@@ -985,7 +984,6 @@ static void elmc_rcv_int(struct net_device *dev)
                                        skb_copy_to_linear_data(skb, (char *) p->base+(unsigned long) rbd->buffer,totlen);
                                        skb->protocol = eth_type_trans(skb, dev);
                                        netif_rx(skb);
-                                       dev->last_rx = jiffies;
                                        dev->stats.rx_packets++;
                                        dev->stats.rx_bytes += totlen;
                                } else {
@@ -1013,7 +1011,7 @@ static void elmc_rcv_int(struct net_device *dev)
 
 static void elmc_rnr_int(struct net_device *dev)
 {
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        dev->stats.rx_errors++;
 
@@ -1036,7 +1034,7 @@ static void elmc_rnr_int(struct net_device *dev)
 static void elmc_xmt_int(struct net_device *dev)
 {
        int status;
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        status = p->xmit_cmds[p->xmit_last]->cmd_status;
        if (!(status & STAT_COMPL)) {
@@ -1079,7 +1077,7 @@ static void elmc_xmt_int(struct net_device *dev)
 
 static void startrecv586(struct net_device *dev)
 {
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        p->scb->rfa_offset = make16(p->rfd_first);
        p->scb->cmd = RUC_START;
@@ -1093,7 +1091,7 @@ static void startrecv586(struct net_device *dev)
 
 static void elmc_timeout(struct net_device *dev)
 {
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
        /* COMMAND-UNIT active? */
        if (p->scb->status & CU_ACTIVE) {
 #ifdef DEBUG
@@ -1129,7 +1127,7 @@ static int elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
 #ifndef NO_NOPCOMMANDS
        int next_nop;
 #endif
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        netif_stop_queue(dev);
 
@@ -1200,7 +1198,7 @@ static int elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
 
 static struct net_device_stats *elmc_get_stats(struct net_device *dev)
 {
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
        unsigned short crc, aln, rsc, ovrn;
 
        crc = p->scb->crc_errs; /* get error-statistic from the ni82586 */
index abc84f765973e2c30ef55b8e5c34973799dad415..2df3af3b9b20130ead927f93db05730029430d9c 100644 (file)
@@ -335,7 +335,6 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
                "82586 initialisation failure",
                "Adapter list configuration error"
        };
-       DECLARE_MAC_BUF(mac);
 
        /* Time to play MCA games */
 
@@ -405,7 +404,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
                dev->dev_addr[i] = mca_read_pos(slot,3);
        }
 
-       printk("%s: Address %s", dev->name, print_mac(mac, dev->dev_addr));
+       printk("%s: Address %pM", dev->name, dev->dev_addr);
 
        mca_write_pos(slot, 6, 0);
        mca_write_pos(slot, 7, 0);
@@ -1187,7 +1186,6 @@ static void mc32_rx_ring(struct net_device *dev)
                        }
 
                        skb->protocol=eth_type_trans(skb,dev);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                        dev->stats.rx_bytes += length;
                        netif_rx(skb);
index 9ba295d9dd973b5713f7d49150a3807899ff3a77..665e7fdf27a15707f2a7aeffae50346371ff4ec1 100644 (file)
@@ -803,7 +803,7 @@ static int vortex_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
 
-       if (dev && dev->priv) {
+       if (dev && netdev_priv(dev)) {
                if (netif_running(dev)) {
                        netif_device_detach(dev);
                        vortex_down(dev, 1);
@@ -1013,7 +1013,6 @@ static int __devinit vortex_probe1(struct device *gendev,
        const char *print_name = "3c59x";
        struct pci_dev *pdev = NULL;
        struct eisa_device *edev = NULL;
-       DECLARE_MAC_BUF(mac);
 
        if (!printed_version) {
                printk (version);
@@ -1026,7 +1025,7 @@ static int __devinit vortex_probe1(struct device *gendev,
                }
 
                if ((edev = DEVICE_EISA(gendev))) {
-                       print_name = edev->dev.bus_id;
+                       print_name = dev_name(&edev->dev);
                }
        }
 
@@ -1206,7 +1205,7 @@ static int __devinit vortex_probe1(struct device *gendev,
                ((__be16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
        memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
        if (print_info)
-               printk(" %s", print_mac(mac, dev->dev_addr));
+               printk(" %pM", dev->dev_addr);
        /* Unfortunately an all zero eeprom passes the checksum and this
           gets found in the wild in failure cases. Crypto is hard 8) */
        if (!is_valid_ether_addr(dev->dev_addr)) {
@@ -2447,7 +2446,6 @@ static int vortex_rx(struct net_device *dev)
                                iowrite16(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
                                skb->protocol = eth_type_trans(skb, dev);
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                                dev->stats.rx_packets++;
                                /* Wait a limited time to go to next packet. */
                                for (i = 200; i >= 0; i--)
@@ -2530,7 +2528,6 @@ boomerang_rx(struct net_device *dev)
                                }
                        }
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                }
                entry = (++vp->cur_rx) % RX_RING_SIZE;
@@ -2886,7 +2883,7 @@ static void vortex_get_drvinfo(struct net_device *dev,
                strcpy(info->bus_info, pci_name(VORTEX_PCI(vp)));
        } else {
                if (VORTEX_EISA(vp))
-                       sprintf(info->bus_info, vp->gendev->bus_id);
+                       sprintf(info->bus_info, dev_name(vp->gendev));
                else
                        sprintf(info->bus_info, "EISA 0x%lx %d",
                                        dev->base_addr, dev->irq);
@@ -3217,7 +3214,7 @@ static void __exit vortex_eisa_cleanup(void)
 #endif
 
        if (compaq_net_device) {
-               vp = compaq_net_device->priv;
+               vp = netdev_priv(compaq_net_device);
                ioaddr = ioport_map(compaq_net_device->base_addr,
                                    VORTEX_TOTAL_SIZE);
 
index ad6b8a5b6574b4865b327bff0bb719878316ce27..7a331acc34add0b755b92c1c4379f4292c5b14e8 100644 (file)
@@ -336,7 +336,6 @@ static int lance_rx (struct net_device *dev)
                                          len);
                         skb->protocol = eth_type_trans (skb, dev);
                        netif_rx (skb);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                        dev->stats.rx_bytes += len;
                 }
index 9ba1f0b4642950d860375768c21bdae6624c321f..664bd73645cb02d9f8df4c658dc69c59a736d8ef 100644 (file)
@@ -457,7 +457,6 @@ static inline void cp_rx_skb (struct cp_private *cp, struct sk_buff *skb,
 
        cp->dev->stats.rx_packets++;
        cp->dev->stats.rx_bytes += skb->len;
-       cp->dev->last_rx = jiffies;
 
 #if CP_VLAN_TAG_USED
        if (cp->vlgrp && (desc->opts2 & cpu_to_le32(RxVlanTagged))) {
@@ -1826,7 +1825,6 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        void __iomem *regs;
        resource_size_t pciaddr;
        unsigned int addr_len, i, pci_using_dac;
-       DECLARE_MAC_BUF(mac);
 
 #ifndef MODULE
        static int version_printed;
@@ -1967,10 +1965,10 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                goto err_out_iomap;
 
        printk (KERN_INFO "%s: RTL-8139C+ at 0x%lx, "
-               "%s, IRQ %d\n",
+               "%pM, IRQ %d\n",
                dev->name,
                dev->base_addr,
-               print_mac(mac, dev->dev_addr),
+               dev->dev_addr,
                dev->irq);
 
        pci_set_drvdata(pdev, dev);
index 63f906b04899de12271baa196bc7b424d0c067f8..37456ada44cf9b74679a187969cc19f72158668b 100644 (file)
@@ -925,7 +925,6 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
        int i, addr_len, option;
        void __iomem *ioaddr;
        static int board_idx = -1;
-       DECLARE_MAC_BUF(mac);
 
        assert (pdev != NULL);
        assert (ent != NULL);
@@ -1024,11 +1023,11 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
        pci_set_drvdata (pdev, dev);
 
        printk (KERN_INFO "%s: %s at 0x%lx, "
-               "%s, IRQ %d\n",
+               "%pM, IRQ %d\n",
                dev->name,
                board_info[ent->driver_data].name,
                dev->base_addr,
-               print_mac(mac, dev->dev_addr),
+               dev->dev_addr,
                dev->irq);
 
        printk (KERN_DEBUG "%s:  Identified 8139 chip type '%s'\n",
@@ -2026,7 +2025,6 @@ no_early_rx:
 
                        skb->protocol = eth_type_trans (skb, dev);
 
-                       dev->last_rx = jiffies;
                        dev->stats.rx_bytes += pkt_size;
                        dev->stats.rx_packets++;
 
index da292e647eb117c496e3c4c6f6108e0e8c316c94..717fe2f7c66a7920d9dab66959dfdb346e4d5dec 100644 (file)
@@ -841,7 +841,6 @@ memory_squeeze:
                                                pkt_len);
 #endif
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                                dev->stats.rx_packets++;
                                dev->stats.rx_bytes+=pkt_len;
                        }
@@ -1116,12 +1115,8 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static void print_eth(unsigned char *add, char *str)
 {
-       DECLARE_MAC_BUF(mac);
-       DECLARE_MAC_BUF(mac2);
-
-       printk(KERN_DEBUG "i596 0x%p, %s --> %s %02X%02X, %s\n",
-              add, print_mac(mac, add + 6), print_mac(mac2, add),
-              add[12], add[13], str);
+       printk(KERN_DEBUG "i596 0x%p, %pM --> %pM %02X%02X, %s\n",
+              add, add + 6, add, add[12], add[13], str);
 }
 
 static int io = 0x300;
@@ -1544,7 +1539,6 @@ static void set_multicast_list(struct net_device *dev)
                struct dev_mc_list *dmi;
                unsigned char *cp;
                struct mc_cmd *cmd;
-               DECLARE_MAC_BUF(mac);
 
                if (wait_cfg(dev, &lp->mc_cmd.cmd, 1000, "multicast list change request timed out"))
                        return;
@@ -1555,8 +1549,8 @@ static void set_multicast_list(struct net_device *dev)
                for (dmi = dev->mc_list; cnt && dmi != NULL; dmi = dmi->next, cnt--, cp += 6) {
                        memcpy(cp, dmi->dmi_addr, 6);
                        if (i596_debug > 1)
-                               DEB(DEB_MULTI,printk(KERN_INFO "%s: Adding address %s\n",
-                                               dev->name, print_mac(mac, cp)));
+                               DEB(DEB_MULTI,printk(KERN_INFO "%s: Adding address %pM\n",
+                                               dev->name, cp));
                }
                i596_add_cmd(dev, &cmd->cmd);
        }
index 11f143f4adf6d379682833679bb9ffa7cb99346c..732ea834d50d7a4a3229dddb838ad8c508b405eb 100644 (file)
@@ -61,6 +61,7 @@ config DUMMY
 config BONDING
        tristate "Bonding driver support"
        depends on INET
+       depends on IPV6 || IPV6=n
        ---help---
          Say 'Y' or 'M' if you wish to be able to 'bond' multiple Ethernet
          Channels together. This is called 'Etherchannel' by Cisco,
@@ -978,6 +979,20 @@ config SMC911X
          called smc911x.  If you want to compile it as a module, say M 
          here and read <file:Documentation/kbuild/modules.txt>
 
+config SMSC911X
+       tristate "SMSC LAN911x/LAN921x families embedded ethernet support"
+       depends on ARM || SUPERH
+       select CRC32
+       select MII
+       select PHYLIB
+       ---help---
+         Say Y here if you want support for SMSC LAN911x and LAN921x families
+         of ethernet controllers.
+
+         To compile this driver as a module, choose M here and read
+         <file:Documentation/networking/net-modules.txt>. The module
+         will be called smsc911x.
+
 config NET_VENDOR_RACAL
        bool "Racal-Interlan (Micom) NI cards"
        depends on ISA
@@ -1414,19 +1429,6 @@ config TC35815
        depends on NET_PCI && PCI && MIPS
        select PHYLIB
 
-config EEPRO100
-       tristate "EtherExpressPro/100 support (eepro100, original Becker driver)"
-       depends on NET_PCI && PCI
-       select MII
-       help
-         If you have an Intel EtherExpress PRO/100 PCI network (Ethernet)
-         card, say Y and read the Ethernet-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         To compile this driver as a module, choose M here. The module
-         will be called eepro100.
-
-
 config E100
        tristate "Intel(R) PRO/100+ support"
        depends on NET_PCI && PCI
index f19acf8b9220bf2e152ecae6fdc9727ee8e5fc19..e06829aa75b0c3033a373d6034a22bd681b1ca9f 100644 (file)
@@ -53,7 +53,6 @@ obj-$(CONFIG_VORTEX) += 3c59x.o
 obj-$(CONFIG_TYPHOON) += typhoon.o
 obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o
 obj-$(CONFIG_PCNET32) += pcnet32.o
-obj-$(CONFIG_EEPRO100) += eepro100.o
 obj-$(CONFIG_E100) += e100.o
 obj-$(CONFIG_TLAN) += tlan.o
 obj-$(CONFIG_EPIC100) += epic100.o
@@ -220,6 +219,7 @@ obj-$(CONFIG_S2IO) += s2io.o
 obj-$(CONFIG_MYRI10GE) += myri10ge/
 obj-$(CONFIG_SMC91X) += smc91x.o
 obj-$(CONFIG_SMC911X) += smc911x.o
+obj-$(CONFIG_SMSC911X) += smsc911x.o
 obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
 obj-$(CONFIG_DM9000) += dm9000.o
 obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o
index 9c0837435b68dd83b88fca7355308796c2257e2e..7a60bdd9a242f27320b23249455b794bb90bf4c8 100644 (file)
@@ -324,7 +324,6 @@ static int lance_rx (struct net_device *dev)
                                         len);
                        skb->protocol = eth_type_trans (skb, dev);
                        netif_rx (skb);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                        dev->stats.rx_bytes += len;
                }
@@ -710,7 +709,6 @@ static int __devinit a2065_init_one(struct zorro_dev *z,
        unsigned long board, base_addr, mem_start;
        struct resource *r1, *r2;
        int err;
-       DECLARE_MAC_BUF(mac);
 
        board = z->resource.start;
        base_addr = board+A2065_LANCE;
@@ -787,8 +785,7 @@ static int __devinit a2065_init_one(struct zorro_dev *z,
        zorro_set_drvdata(z, dev);
 
        printk(KERN_INFO "%s: A2065 at 0x%08lx, Ethernet Address "
-              "%s\n", dev->name, board,
-              print_mac(mac, dev->dev_addr));
+              "%pM\n", dev->name, board, dev->dev_addr);
 
        return 0;
 }
index b1448637107f3fada6f1a97536dfd6492a9d9117..071a851a2ea1d6b5a4b4db6b0c0e51625ad38222 100644 (file)
@@ -146,7 +146,6 @@ out:
 static int __init ac_probe1(int ioaddr, struct net_device *dev)
 {
        int i, retval;
-       DECLARE_MAC_BUF(mac);
 
        if (!request_region(ioaddr, AC_IO_EXTENT, DRV_NAME))
                return -EBUSY;
@@ -171,8 +170,8 @@ static int __init ac_probe1(int ioaddr, struct net_device *dev)
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i);
 
-       printk(KERN_DEBUG "AC3200 in EISA slot %d, node %s",
-              ioaddr/0x1000, print_mac(mac, dev->dev_addr));
+       printk(KERN_DEBUG "AC3200 in EISA slot %d, node %pM",
+              ioaddr/0x1000, dev->dev_addr);
 #if 0
        /* Check the vendor ID/prefix. Redundant after checking the EISA ID */
        if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0
index 66de80b64b92a3f937edf821e49ec748c6478ed3..109eb7ccff307a28a2c10d62833c9c6fa87c7a76 100644 (file)
@@ -466,7 +466,7 @@ static int __devinit acenic_probe_one(struct pci_dev *pdev,
 
        SET_NETDEV_DEV(dev, &pdev->dev);
 
-       ap = dev->priv;
+       ap = netdev_priv(dev);
        ap->pdev = pdev;
        ap->name = pci_name(pdev);
 
@@ -892,7 +892,6 @@ static int __devinit ace_init(struct net_device *dev)
        int board_idx, ecode = 0;
        short i;
        unsigned char cache_size;
-       DECLARE_MAC_BUF(mac);
 
        ap = netdev_priv(dev);
        regs = ap->regs;
@@ -1019,7 +1018,7 @@ static int __devinit ace_init(struct net_device *dev)
        dev->dev_addr[4] = (mac2 >> 8) & 0xff;
        dev->dev_addr[5] = mac2 & 0xff;
 
-       printk("MAC: %s\n", print_mac(mac, dev->dev_addr));
+       printk("MAC: %pM\n", dev->dev_addr);
 
        /*
         * Looks like this is necessary to deal with on all architectures,
@@ -2034,7 +2033,6 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm)
 #endif
                        netif_rx(skb);
 
-               dev->last_rx = jiffies;
                dev->stats.rx_packets++;
                dev->stats.rx_bytes += retdesc->size;
 
index 07a6697e3635608466a00a41d5139281d8eef686..0bc4f54d5db95861ecb6ff9cbe68b71df0bd370c 100644 (file)
@@ -809,7 +809,6 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
                        lp->coal_conf.rx_packets++;
                        lp->coal_conf.rx_bytes += pkt_len;
                        num_rx_pkt++;
-                       dev->last_rx = jiffies;
 
                err_next_pkt:
                        lp->rx_ring[rx_index].buff_phy_addr
@@ -1821,7 +1820,6 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
        unsigned long reg_addr,reg_len;
        struct amd8111e_priv* lp;
        struct net_device* dev;
-       DECLARE_MAC_BUF(mac);
 
        err = pci_enable_device(pdev);
        if(err){
@@ -1963,8 +1961,8 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
        chip_version = (readl(lp->mmio + CHIPID) & 0xf0000000)>>28;
        printk(KERN_INFO "%s: AMD-8111e Driver Version: %s\n",
               dev->name,MODULE_VERS);
-       printk(KERN_INFO "%s: [ Rev %x ] PCI 10/100BaseT Ethernet %s\n",
-              dev->name, chip_version, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: [ Rev %x ] PCI 10/100BaseT Ethernet %pM\n",
+              dev->name, chip_version, dev->dev_addr);
        if (lp->ext_phy_id)
                printk(KERN_INFO "%s: Found MII PHY ID 0x%08x at address 0x%02x\n",
                       dev->name, lp->ext_phy_id, lp->ext_phy_addr);
index 867f6fff543c848bfd95a741173c746005344017..7426f69406305821a931a1cd1566673d1f7ddcb3 100644 (file)
@@ -207,7 +207,6 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
     int neX000, ctron;
 #endif
     static unsigned version_printed;
-    DECLARE_MAC_BUF(mac);
 
     if (ei_debug  &&  version_printed++ == 0)
        printk(version);
@@ -323,7 +322,7 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
     for(i = 0; i < ETHER_ADDR_LEN; i++)
        dev->dev_addr[i] = SA_prom[i];
 
-    printk(" %s\n", print_mac(mac, dev->dev_addr));
+    printk(" %pM\n", dev->dev_addr);
 
     printk("%s: %s found.\n", dev->name, name);
 
index 735fc9476403c4df27229298af32021ddd9f1762..0c4e3c5ac49c48fc4a8b0e1749e51d8d9fff638e 100644 (file)
@@ -851,7 +851,6 @@ static void cops_rx(struct net_device *dev)
 
         /* Send packet to a higher place. */
         netif_rx(skb);
-       dev->last_rx = jiffies;
 }
 
 static void cops_timeout(struct net_device *dev)
index 1071144edd66fbdf0f594ec0104c065fdee06e82..9a0be9b2eaad66d5bec2776c54871d29b08e5e6f 100644 (file)
@@ -108,7 +108,7 @@ static struct net_device * __init ipddp_init(void)
  */
 static struct net_device_stats *ipddp_get_stats(struct net_device *dev)
 {
-        return dev->priv;
+       return netdev_priv(dev);
 }
 
 /*
@@ -170,8 +170,8 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
 
         skb->protocol = htons(ETH_P_ATALK);     /* Protocol has changed */
 
-       ((struct net_device_stats *) dev->priv)->tx_packets++;
-        ((struct net_device_stats *) dev->priv)->tx_bytes+=skb->len;
+       ((struct net_device_stats *) netdev_priv(dev))->tx_packets++;
+       ((struct net_device_stats *) netdev_priv(dev))->tx_bytes += skb->len;
 
         if(aarp_send_ddp(rt->dev, skb, &rt->at, NULL) < 0)
                 dev_kfree_skb(skb);
index fef5560bc7a2ee2d8c6aee66f6e413022fdfdca1..dc4d49605603147acc93acb476ec9aa94cc714cb 100644 (file)
@@ -726,7 +726,8 @@ static int sendup_buffer (struct net_device *dev)
        int dnode, snode, llaptype, len; 
        int sklen;
        struct sk_buff *skb;
-       struct net_device_stats *stats = &((struct ltpc_private *)dev->priv)->stats;
+       struct ltpc_private *ltpc_priv = netdev_priv(dev);
+       struct net_device_stats *stats = &ltpc_priv->stats;
        struct lt_rcvlap *ltc = (struct lt_rcvlap *) ltdmacbuf;
 
        if (ltc->command != LT_RCVLAP) {
@@ -783,7 +784,6 @@ static int sendup_buffer (struct net_device *dev)
 
        /* toss it onwards */
        netif_rx(skb);
-       dev->last_rx = jiffies;
        return 0;
 }
 
@@ -823,7 +823,8 @@ static int ltpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
        struct sockaddr_at *sa = (struct sockaddr_at *) &ifr->ifr_addr;
        /* we'll keep the localtalk node address in dev->pa_addr */
-       struct atalk_addr *aa = &((struct ltpc_private *)dev->priv)->my_addr;
+       struct ltpc_private *ltpc_priv = netdev_priv(dev);
+       struct atalk_addr *aa = &ltpc_priv->my_addr;
        struct lt_init c;
        int ltflags;
 
@@ -904,7 +905,8 @@ static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev)
         * and skb->len is the length of the ddp data + ddp header
         */
 
-       struct net_device_stats *stats = &((struct ltpc_private *)dev->priv)->stats;
+       struct ltpc_private *ltpc_priv = netdev_priv(dev);
+       struct net_device_stats *stats = &ltpc_priv->stats;
 
        int i;
        struct lt_sendlap cbuf;
@@ -943,7 +945,8 @@ static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static struct net_device_stats *ltpc_get_stats(struct net_device *dev)
 {
-       struct net_device_stats *stats = &((struct ltpc_private *) dev->priv)->stats;
+       struct ltpc_private *ltpc_priv = netdev_priv(dev);
+       struct net_device_stats *stats = &ltpc_priv->stats;
        return stats;
 }
 
index e0a18e7c73cb59d36150bc9007fb82d39819bb21..3ff9affb1a914e212de008728985598e8e724bf8 100644 (file)
@@ -87,7 +87,7 @@ MODULE_LICENSE("GPL");
 static void rx(struct net_device *dev, int bufnum,
               struct archdr *pkthdr, int length)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        struct sk_buff *skb;
        struct archdr *pkt = pkthdr;
        int ofs;
@@ -125,7 +125,6 @@ static void rx(struct net_device *dev, int bufnum,
        skb->protocol = __constant_htons(ETH_P_ARCNET);
 ;
        netif_rx(skb);
-       dev->last_rx = jiffies;
 }
 
 
@@ -168,7 +167,7 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
                      int bufnum)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        struct arc_hardware *hard = &pkt->hard;
        int ofs;
 
index 8c8d6c453c457e3b5f236d15f812dc66ede25d49..e3082a9350fcafcd2b1a90ae21cdc08a284f15b4 100644 (file)
@@ -194,7 +194,7 @@ static int __init arcrimi_found(struct net_device *dev)
 
        /* initialize the rest of the device structure. */
 
-       lp = dev->priv;
+       lp = netdev_priv(dev);
        lp->card_name = "RIM I";
        lp->hw.command = arcrimi_command;
        lp->hw.status = arcrimi_status;
@@ -260,7 +260,7 @@ err_free_irq:
  */
 static int arcrimi_reset(struct net_device *dev, int really_reset)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->mem_start + 0x800;
 
        BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS());
@@ -281,7 +281,7 @@ static int arcrimi_reset(struct net_device *dev, int really_reset)
 
 static void arcrimi_setmask(struct net_device *dev, int mask)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->mem_start + 0x800;
 
        AINTMASK(mask);
@@ -289,7 +289,7 @@ static void arcrimi_setmask(struct net_device *dev, int mask)
 
 static int arcrimi_status(struct net_device *dev)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->mem_start + 0x800;
 
        return ASTATUS();
@@ -297,7 +297,7 @@ static int arcrimi_status(struct net_device *dev)
 
 static void arcrimi_command(struct net_device *dev, int cmd)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->mem_start + 0x800;
 
        ACOMMAND(cmd);
@@ -306,7 +306,7 @@ static void arcrimi_command(struct net_device *dev, int cmd)
 static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
                                 void *buf, int count)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
        TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
 }
@@ -315,7 +315,7 @@ static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
 static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offset,
                                   void *buf, int count)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
        TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
 }
@@ -361,7 +361,7 @@ static int __init arc_rimi_init(void)
 static void __exit arc_rimi_exit(void)
 {
        struct net_device *dev = my_dev;
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
 
        unregister_netdev(dev);
        iounmap(lp->mem_start);
index a5b07691e466d6cc43b210796144eece8947d15c..6b53e5ed125cfbb10c2be5f34edca1a04fe36097 100644 (file)
@@ -181,7 +181,7 @@ EXPORT_SYMBOL(arcnet_dump_skb);
 static void arcnet_dump_packet(struct net_device *dev, int bufnum,
                               char *desc, int take_arcnet_lock)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        int i, length;
        unsigned long flags = 0;
        static uint8_t buf[512];
@@ -247,7 +247,7 @@ void arcnet_unregister_proto(struct ArcProto *proto)
  */
 static void release_arcbuf(struct net_device *dev, int bufnum)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        int i;
 
        lp->buf_queue[lp->first_free_buf++] = bufnum;
@@ -269,7 +269,7 @@ static void release_arcbuf(struct net_device *dev, int bufnum)
  */
 static int get_arcbuf(struct net_device *dev)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        int buf = -1, i;
 
        if (!atomic_dec_and_test(&lp->buf_lock)) {
@@ -357,7 +357,7 @@ struct net_device *alloc_arcdev(char *name)
        dev = alloc_netdev(sizeof(struct arcnet_local),
                           name && *name ? name : "arc%d", arcdev_setup);
        if(dev) {
-               struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+               struct arcnet_local *lp = netdev_priv(dev);
                spin_lock_init(&lp->lock);
        }
 
@@ -374,7 +374,7 @@ struct net_device *alloc_arcdev(char *name)
  */
 static int arcnet_open(struct net_device *dev)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        int count, newmtu, error;
 
        BUGMSG(D_INIT,"opened.");
@@ -474,7 +474,7 @@ static int arcnet_open(struct net_device *dev)
 /* The inverse routine to arcnet_open - shuts down the card. */
 static int arcnet_close(struct net_device *dev)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
 
        netif_stop_queue(dev);
 
@@ -556,7 +556,7 @@ static int arcnet_header(struct sk_buff *skb, struct net_device *dev,
 static int arcnet_rebuild_header(struct sk_buff *skb)
 {
        struct net_device *dev = skb->dev;
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        int status = 0;         /* default is failure */
        unsigned short type;
        uint8_t daddr=0;
@@ -603,7 +603,7 @@ static int arcnet_rebuild_header(struct sk_buff *skb)
 /* Called by the kernel in order to transmit a packet. */
 static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        struct archdr *pkt;
        struct arc_rfc1201 *soft;
        struct ArcProto *proto;
@@ -693,7 +693,7 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
  */
 static int go_tx(struct net_device *dev)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
 
        BUGMSG(D_DURING, "go_tx: status=%Xh, intmask=%Xh, next_tx=%d, cur_tx=%d\n",
               ASTATUS(), lp->intmask, lp->next_tx, lp->cur_tx);
@@ -723,7 +723,7 @@ static int go_tx(struct net_device *dev)
 static void arcnet_timeout(struct net_device *dev)
 {
        unsigned long flags;
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        int status = ASTATUS();
        char *msg;
 
@@ -771,8 +771,8 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
        BUGMSG(D_DURING, "\n");
 
        BUGMSG(D_DURING, "in arcnet_interrupt\n");
-       
-       lp = dev->priv;
+
+       lp = netdev_priv(dev);
        BUG_ON(!lp);
                
        spin_lock(&lp->lock);
@@ -1010,7 +1010,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
  */
 static void arcnet_rx(struct net_device *dev, int bufnum)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        struct archdr pkt;
        struct arc_rfc1201 *soft;
        int length, ofs;
@@ -1074,7 +1074,7 @@ static void arcnet_rx(struct net_device *dev, int bufnum)
  */
 static struct net_device_stats *arcnet_get_stats(struct net_device *dev)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        return &lp->stats;
 }
 
@@ -1091,7 +1091,7 @@ static void null_rx(struct net_device *dev, int bufnum,
 static int null_build_header(struct sk_buff *skb, struct net_device *dev,
                             unsigned short type, uint8_t daddr)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
 
        BUGMSG(D_PROTO,
               "tx: can't build header for encap %02Xh; load a protocol driver.\n",
@@ -1106,7 +1106,7 @@ static int null_build_header(struct sk_buff *skb, struct net_device *dev,
 static int null_prepare_tx(struct net_device *dev, struct archdr *pkt,
                           int length, int bufnum)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        struct arc_hardware newpkt;
 
        BUGMSG(D_PROTO, "tx: no encap for this host; load a protocol driver.\n");
index 02cb8f1c11484b23460100c85f60faec62bd3ea5..e544953d8e9a44b905800047d9195a9ce981146e 100644 (file)
@@ -103,7 +103,7 @@ MODULE_LICENSE("GPL");
 static void rx(struct net_device *dev, int bufnum,
               struct archdr *pkthdr, int length)
 {
-       struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        struct sk_buff *skb;
        struct archdr *pkt = pkthdr;
        char *pktbuf, *pkthdrbuf;
@@ -151,7 +151,6 @@ static void rx(struct net_device *dev, int bufnum,
        skb->protocol = __constant_htons(ETH_P_ARCNET);
 ;
        netif_rx(skb);
-       dev->last_rx = jiffies;
 }
 
 
@@ -198,7 +197,7 @@ static int build_header(struct sk_buff *skb,
 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
                      int bufnum)
 {
-       struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        struct arc_hardware *hard = &pkt->hard;
        int ofs;
 
@@ -250,7 +249,7 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
 
 static int ack_tx(struct net_device *dev, int acked)
 {
-  struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+  struct arcnet_local *lp = netdev_priv(dev);
   struct sk_buff *ackskb;
   struct archdr *ackpkt;
   int length=sizeof(struct arc_cap);
index 9289e6103de5ac039dbde468fe7e282254739e57..ea53a940272f1172ec4b51070d608becbf71e134 100644 (file)
@@ -52,7 +52,7 @@ static int __init com20020isa_probe(struct net_device *dev)
 {
        int ioaddr;
        unsigned long airqmask;
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        int err;
 
        BUGLVL(D_NORMAL) printk(VERSION);
@@ -151,7 +151,7 @@ static int __init com20020_init(void)
        if (node && node != 0xff)
                dev->dev_addr[0] = node;
 
-       lp = dev->priv;
+       lp = netdev_priv(dev);
        lp->backplane = backplane;
        lp->clockp = clockp & 7;
        lp->clockm = clockm & 3;
index b8c0fa6d401db146998c21c29b7928806a5fe9f3..8b51f632581d1810f2f712e2b3b63ae942b33ed3 100644 (file)
@@ -72,7 +72,7 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
        dev = alloc_arcdev(device);
        if (!dev)
                return -ENOMEM;
-       lp = dev->priv;
+       lp = netdev_priv(dev);
 
        pci_set_drvdata(pdev, dev);
 
index 70124a944e7d61f59b89fdb7544339278d7d3f40..103688358fb84721af7568c9a4f14a90ba81659c 100644 (file)
@@ -89,7 +89,7 @@ static void com20020_copy_to_card(struct net_device *dev, int bufnum,
 int com20020_check(struct net_device *dev)
 {
        int ioaddr = dev->base_addr, status;
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
 
        ARCRESET0;
        mdelay(RESETtime);
@@ -159,7 +159,7 @@ int com20020_found(struct net_device *dev, int shared)
 
        /* Initialize the rest of the device structure. */
 
-       lp = dev->priv;
+       lp = netdev_priv(dev);
 
        lp->hw.owner = THIS_MODULE;
        lp->hw.command = com20020_command;
@@ -233,7 +233,7 @@ int com20020_found(struct net_device *dev, int shared)
  */
 static int com20020_reset(struct net_device *dev, int really_reset)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        u_int ioaddr = dev->base_addr;
        u_char inbyte;
 
@@ -300,7 +300,7 @@ static int com20020_status(struct net_device *dev)
 
 static void com20020_close(struct net_device *dev)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
 
        /* disable transmitter */
@@ -317,7 +317,7 @@ static void com20020_close(struct net_device *dev)
  */
 static void com20020_set_mc_list(struct net_device *dev)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
 
        if ((dev->flags & IFF_PROMISC) && (dev->flags & IFF_UP)) {      /* Enable promiscuous mode */
index 6599f1046c7b844aec858e5456196122e67ced64..89de29b3b1dc0d09628b093fb6ac34483984716e 100644 (file)
@@ -248,7 +248,7 @@ static int __init com90io_found(struct net_device *dev)
                return -EBUSY;
        }
 
-       lp = dev->priv;
+       lp = netdev_priv(dev);
        lp->card_name = "COM90xx I/O";
        lp->hw.command = com90io_command;
        lp->hw.status = com90io_status;
@@ -290,7 +290,7 @@ static int __init com90io_found(struct net_device *dev)
  */
 static int com90io_reset(struct net_device *dev, int really_reset)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        short ioaddr = dev->base_addr;
 
        BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS());
index 0d45553ff75c8c08032c57cfa041f28d617d64be..f4113d26587a319440e99654de3379663e3bd9b4 100644 (file)
@@ -468,7 +468,7 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem
                release_mem_region(shmem, MIRROR_SIZE);
                return -ENOMEM;
        }
-       lp = dev->priv;
+       lp = netdev_priv(dev);
        /* find the real shared memory start/end points, including mirrors */
 
        /* guess the actual size of one "memory mirror" - the number of
@@ -585,7 +585,7 @@ static void com90xx_setmask(struct net_device *dev, int mask)
  */
 int com90xx_reset(struct net_device *dev, int really_reset)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        short ioaddr = dev->base_addr;
 
        BUGMSG(D_INIT, "Resetting (status=%02Xh)\n", ASTATUS());
@@ -621,7 +621,7 @@ int com90xx_reset(struct net_device *dev, int really_reset)
 static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
                                 void *buf, int count)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
        TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
 }
@@ -630,7 +630,7 @@ static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
 static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
                                   void *buf, int count)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
        TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
 }
@@ -656,7 +656,7 @@ static void __exit com90xx_exit(void)
 
        for (count = 0; count < numcards; count++) {
                dev = cards[count];
-               lp = dev->priv;
+               lp = netdev_priv(dev);
 
                unregister_netdev(dev);
                free_irq(dev->irq, dev);
index dab185bc51f1a1bc05b3c689ed7fac5834b06c96..49d39a9cb696331052f7a590cb72b71e4dab2452 100644 (file)
@@ -88,7 +88,7 @@ MODULE_LICENSE("GPL");
  */
 static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        struct archdr *pkt = (struct archdr *) skb->data;
        struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
        int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
@@ -125,7 +125,7 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
 static void rx(struct net_device *dev, int bufnum,
               struct archdr *pkthdr, int length)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        struct sk_buff *skb;
        struct archdr *pkt = pkthdr;
        int ofs;
@@ -159,7 +159,6 @@ static void rx(struct net_device *dev, int bufnum,
 
        skb->protocol = type_trans(skb, dev);
        netif_rx(skb);
-       dev->last_rx = jiffies;
 }
 
 
@@ -169,7 +168,7 @@ static void rx(struct net_device *dev, int bufnum,
 static int build_header(struct sk_buff *skb, struct net_device *dev,
                        unsigned short type, uint8_t daddr)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
        struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
        struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
@@ -220,7 +219,7 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
                      int bufnum)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        struct arc_hardware *hard = &pkt->hard;
        int ofs;
 
index 6d6d95cc4404b7a727a20f049dc8240db595351d..2303d3a1f4b63d512aea87ef1287fb39e54b10d9 100644 (file)
@@ -92,7 +92,7 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
 {
        struct archdr *pkt = (struct archdr *) skb->data;
        struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
 
        /* Pull off the arcnet header. */
@@ -134,7 +134,7 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
 static void rx(struct net_device *dev, int bufnum,
               struct archdr *pkthdr, int length)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        struct sk_buff *skb;
        struct archdr *pkt = pkthdr;
        struct arc_rfc1201 *soft = &pkthdr->soft.rfc1201;
@@ -230,7 +230,6 @@ static void rx(struct net_device *dev, int bufnum,
 
                skb->protocol = type_trans(skb, dev);
                netif_rx(skb);
-               dev->last_rx = jiffies;
        } else {                /* split packet */
                /*
                 * NOTE: MSDOS ARP packet correction should only need to apply to
@@ -366,7 +365,6 @@ static void rx(struct net_device *dev, int bufnum,
 
                        skb->protocol = type_trans(skb, dev);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                }
        }
 }
@@ -376,7 +374,7 @@ static void rx(struct net_device *dev, int bufnum,
 static int build_header(struct sk_buff *skb, struct net_device *dev,
                        unsigned short type, uint8_t daddr)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
        struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
        struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
@@ -443,7 +441,7 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
 static void load_pkt(struct net_device *dev, struct arc_hardware *hard,
                     struct arc_rfc1201 *soft, int softlen, int bufnum)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        int ofs;
 
        /* assume length <= XMTU: someone should have handled that by now. */
@@ -476,7 +474,7 @@ static void load_pkt(struct net_device *dev, struct arc_hardware *hard,
 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
                      int bufnum)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        const int maxsegsize = XMTU - RFC1201_HDR_SIZE;
        struct Outgoing *out;
 
@@ -511,7 +509,7 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
 
 static int continue_tx(struct net_device *dev, int bufnum)
 {
-       struct arcnet_local *lp = dev->priv;
+       struct arcnet_local *lp = netdev_priv(dev);
        struct Outgoing *out = &lp->outgoing;
        struct arc_hardware *hard = &out->pkt->hard;
        struct arc_rfc1201 *soft = &out->pkt->soft.rfc1201, *newsoft;
index 29e53eb71c7484c2c8f2e4c0ecef185786bbb00c..e1d72e06f3e1b07849997566dd3b3502251ba347 100644 (file)
@@ -165,7 +165,6 @@ static int __devinit ariadne_init_one(struct zorro_dev *z,
     struct net_device *dev;
     struct ariadne_private *priv;
     int err;
-    DECLARE_MAC_BUF(mac);
 
     r1 = request_mem_region(base_addr, sizeof(struct Am79C960), "Am79C960");
     if (!r1)
@@ -215,9 +214,8 @@ static int __devinit ariadne_init_one(struct zorro_dev *z,
     }
     zorro_set_drvdata(z, dev);
 
-    printk(KERN_INFO "%s: Ariadne at 0x%08lx, Ethernet Address "
-          "%s\n", dev->name, board,
-          print_mac(mac, dev->dev_addr));
+    printk(KERN_INFO "%s: Ariadne at 0x%08lx, Ethernet Address %pM\n",
+           dev->name, board, dev->dev_addr);
 
     return 0;
 }
@@ -613,14 +611,10 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 #if 0
 {
-    DECLARE_MAC_BUF(mac);
-    DECLARE_MAC_BUF(mac2);
-
-    printk(KERN_DEBUG "TX pkt type 0x%04x from %s to %s "
+    printk(KERN_DEBUG "TX pkt type 0x%04x from %pM to %pM "
           " data 0x%08x len %d\n",
           ((u_short *)skb->data)[6],
-          print_mac(mac, ((const u8 *)skb->data)+6),
-          print_mac(mac, (const u8 *)skb->data),
+          skb->data + 6, skb->data,
           (int)skb->data, (int)skb->len);
 }
 #endif
@@ -743,25 +737,22 @@ static int ariadne_rx(struct net_device *dev)
            skb->protocol=eth_type_trans(skb,dev);
 #if 0
 {
-           DECLARE_MAC_BUF(mac);
-
            printk(KERN_DEBUG "RX pkt type 0x%04x from ",
                   ((u_short *)skb->data)[6]);
            {
                u_char *ptr = &((u_char *)skb->data)[6];
-               printk("%s", print_mac(mac, ptr));
+               printk("%pM", ptr);
            }
            printk(" to ");
            {
                u_char *ptr = (u_char *)skb->data;
-               printk("%s", print_mac(mac, ptr));
+               printk("%pM", ptr);
            }
            printk(" data 0x%08x len %d\n", (int)skb->data, (int)skb->len);
 }
 #endif
 
            netif_rx(skb);
-           dev->last_rx = jiffies;
            dev->stats.rx_packets++;
            dev->stats.rx_bytes += pkt_len;
        }
index aa4a5246be534a483e6ec42a6b67ba8986e371cd..0c628a9e5339af44f5c4cee91c39a279402d3f38 100644 (file)
@@ -532,7 +532,6 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv)
                        am_writeword(dev, hdraddr + 2, RMD_OWN);
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        priv->stats.rx_bytes += len;
                        priv->stats.rx_packets ++;
                } else {
@@ -745,10 +744,8 @@ static int __init am79c961_probe(struct platform_device *pdev)
 
        ret = register_netdev(dev);
        if (ret == 0) {
-               DECLARE_MAC_BUF(mac);
-
-               printk(KERN_INFO "%s: ether address %s\n",
-                      dev->name, print_mac(mac, dev->dev_addr));
+               printk(KERN_INFO "%s: ether address %pM\n",
+                      dev->name, dev->dev_addr);
                return 0;
        }
 
index 6f431a887e7e5fb4f2b6ca27217f204a3d063291..442938d5038020dfd334100b7c3faf73e1f72c02 100644 (file)
@@ -485,7 +485,6 @@ static void update_mac_address(struct net_device *dev)
 static int set_mac_address(struct net_device *dev, void* addr)
 {
        struct sockaddr *address = addr;
-       DECLARE_MAC_BUF(mac);
 
        if (!is_valid_ether_addr(address->sa_data))
                return -EADDRNOTAVAIL;
@@ -493,8 +492,8 @@ static int set_mac_address(struct net_device *dev, void* addr)
        memcpy(dev->dev_addr, address->sa_data, dev->addr_len);
        update_mac_address(dev);
 
-       printk("%s: Setting MAC address to %s\n", dev->name,
-              print_mac(mac, dev->dev_addr));
+       printk("%s: Setting MAC address to %pM\n", dev->name,
+              dev->dev_addr);
 
        return 0;
 }
@@ -894,7 +893,6 @@ static void at91ether_rx(struct net_device *dev)
                        memcpy(skb_put(skb, pktlen), p_recv, pktlen);
 
                        skb->protocol = eth_type_trans(skb, dev);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_bytes += pktlen;
                        netif_rx(skb);
                }
@@ -978,7 +976,6 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
        struct at91_private *lp;
        unsigned int val;
        int res;
-       DECLARE_MAC_BUF(mac);
 
        dev = alloc_etherdev(sizeof(struct at91_private));
        if (!dev)
@@ -1084,11 +1081,11 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
                gpio_request(lp->board_data.phy_irq_pin, "ethernet_phy");
 
        /* Display ethernet banner */
-       printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%s)\n",
+       printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%pM)\n",
               dev->name, (uint) dev->base_addr, dev->irq,
               at91_emac_read(AT91_EMAC_CFG) & AT91_EMAC_SPD ? "100-" : "10-",
               at91_emac_read(AT91_EMAC_CFG) & AT91_EMAC_FD ? "FullDuplex" : "HalfDuplex",
-              print_mac(mac, dev->dev_addr));
+              dev->dev_addr);
        if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID))
                printk(KERN_INFO "%s: Davicom 9161 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)");
        else if (phy_type == MII_LXT971A_ID)
index 1267444d79da80d0e1fb18e12d204db06bae6efc..588c9739d13d2891ebbd0d2df7e873ecefc834db 100644 (file)
@@ -259,8 +259,6 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget)
                        skb_put(skb, length);
                        skb->protocol = eth_type_trans(skb, dev);
 
-                       dev->last_rx = jiffies;
-
                        netif_receive_skb(skb);
 
                        ep->stats.rx_packets++;
index 3bb9e293e2efea6ba066b6ad61960002f89d1675..e380de4544637629dcd3260e8b463d10af272200 100644 (file)
@@ -996,7 +996,6 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
 {
        struct net_device *dev;
        int i, ret = 0;
-       DECLARE_MAC_BUF(mac);
 
        ether1_banner();
 
@@ -1044,8 +1043,8 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
        if (ret)
                goto free;
 
-       printk(KERN_INFO "%s: ether1 in slot %d, %s\n",
-               dev->name, ec->slot_no, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: ether1 in slot %d, %pM\n",
+               dev->name, ec->slot_no, dev->dev_addr);
     
        ecard_set_drvdata(ec, dev);
        return 0;
index 67e96ae85035638ee009f2aadac0e5a7a538269b..21a7bef12d3b1c1965d166dad6db7ae9d5eecd6c 100644 (file)
@@ -776,7 +776,6 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
        const struct ether3_data *data = id->data;
        struct net_device *dev;
        int bus_type, ret;
-       DECLARE_MAC_BUF(mac);
 
        ether3_banner();
 
@@ -859,8 +858,8 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
        if (ret)
                goto free;
 
-       printk("%s: %s in slot %d, %s\n",
-              dev->name, data->name, ec->slot_no, print_mac(mac, dev->dev_addr));
+       printk("%s: %s in slot %d, %pM\n",
+              dev->name, data->name, ec->slot_no, dev->dev_addr);
 
        ecard_set_drvdata(ec, dev);
        return 0;
index 5c5f1e470d3c2d05fcc910fb97917cb487bf7533..9eb9d1bedc851920283d961eda30eb3339ea3df6 100644 (file)
@@ -648,7 +648,6 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
        struct net_device *dev;
        struct etherh_priv *eh;
        int ret;
-       DECLARE_MAC_BUF(mac);
 
        etherh_banner();
 
@@ -746,8 +745,8 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
        if (ret)
                goto free;
 
-       printk(KERN_INFO "%s: %s in slot %d, %s\n",
-               dev->name, data->name, ec->slot_no, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: %s in slot %d, %pM\n",
+               dev->name, data->name, ec->slot_no, dev->dev_addr);
 
        ecard_set_drvdata(ec, dev);
 
index e2d702b8b2e4766321824c26941074b40c950fa5..14ffa2a61890d12df652841e0f6d16b5278436a5 100644 (file)
@@ -588,7 +588,6 @@ static int eth_poll(struct napi_struct *napi, int budget)
                debug_pkt(dev, "eth_poll", skb->data, skb->len);
 
                skb->protocol = eth_type_trans(skb, dev);
-               dev->last_rx = jiffies;
                port->stat.rx_packets++;
                port->stat.rx_bytes += skb->len;
                netif_receive_skb(skb);
index 7e874d485d24a36fbab6aee652eaf44c6cf72e78..2d4b5c31652e0aae6a36cbd5459d724dba9dc55f 100644 (file)
@@ -265,7 +265,6 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr)
        unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0;
        int slot, ret = -ENODEV;
        struct net_local *lp = netdev_priv(dev);
-       DECLARE_MAC_BUF(mac);
 
        if (!request_region(ioaddr, AT1700_IO_EXTENT, DRV_NAME))
                return -EBUSY;
@@ -397,7 +396,7 @@ found:
                        dev->dev_addr[i] = val;
                }
        }
-       printk("%s", print_mac(mac, dev->dev_addr));
+       printk("%pM", dev->dev_addr);
 
        /* The EEPROM word 12 bit 0x0400 means use regular 100 ohm 10baseT signals,
           rather than 150 ohm shielded twisted pair compensation.
@@ -768,7 +767,6 @@ net_rx(struct net_device *dev)
                        insw(ioaddr + DATAPORT, skb_put(skb,pkt_len), (pkt_len + 1) >> 1);
                        skb->protocol=eth_type_trans(skb, dev);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                        dev->stats.rx_bytes += pkt_len;
                }
index 0860cc280b019c230e969c5b7efaac96ae4101f2..2d81f6afcb589075009d6e45bc0db9dcd4b40c00 100644 (file)
@@ -466,7 +466,6 @@ static unsigned long __init lance_probe1( struct net_device *dev,
        int                                     i;
        static int                              did_version;
        unsigned short                  save1, save2;
-       DECLARE_MAC_BUF(mac);
 
        PROBE_PRINT(( "Probing for Lance card at mem %#lx io %#lx\n",
                                  (long)memaddr, (long)ioaddr ));
@@ -521,7 +520,7 @@ static unsigned long __init lance_probe1( struct net_device *dev,
        return( 0 );
 
   probe_ok:
-       lp = (struct lance_private *)dev->priv;
+       lp = netdev_priv(dev);
        MEM = (struct lance_memory *)memaddr;
        IO = lp->iobase = (struct lance_ioreg *)ioaddr;
        dev->base_addr = (unsigned long)ioaddr; /* informational only */
@@ -595,7 +594,7 @@ static unsigned long __init lance_probe1( struct net_device *dev,
                i = IO->mem;
                break;
        }
-       printk("%s\n", print_mac(mac, dev->dev_addr));
+       printk("%pM\n", dev->dev_addr);
        if (lp->cardtype == OLD_RIEBL) {
                printk( "%s: Warning: This is a default ethernet address!\n",
                                dev->name );
@@ -640,8 +639,8 @@ static unsigned long __init lance_probe1( struct net_device *dev,
 
 
 static int lance_open( struct net_device *dev )
-
-{      struct lance_private *lp = (struct lance_private *)dev->priv;
+{
+       struct lance_private *lp = netdev_priv(dev);
        struct lance_ioreg       *IO = lp->iobase;
        int i;
 
@@ -681,8 +680,8 @@ static int lance_open( struct net_device *dev )
 /* Initialize the LANCE Rx and Tx rings. */
 
 static void lance_init_ring( struct net_device *dev )
-
-{      struct lance_private *lp = (struct lance_private *)dev->priv;
+{
+       struct lance_private *lp = netdev_priv(dev);
        int i;
        unsigned offset;
 
@@ -730,7 +729,7 @@ static void lance_init_ring( struct net_device *dev )
 
 static void lance_tx_timeout (struct net_device *dev)
 {
-       struct lance_private *lp = (struct lance_private *) dev->priv;
+       struct lance_private *lp = netdev_priv(dev);
        struct lance_ioreg       *IO = lp->iobase;
 
        AREG = CSR0;
@@ -772,14 +771,12 @@ static void lance_tx_timeout (struct net_device *dev)
 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
 
 static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
-
-{      struct lance_private *lp = (struct lance_private *)dev->priv;
+{
+       struct lance_private *lp = netdev_priv(dev);
        struct lance_ioreg       *IO = lp->iobase;
        int entry, len;
        struct lance_tx_head *head;
        unsigned long flags;
-       DECLARE_MAC_BUF(mac);
-       DECLARE_MAC_BUF(mac2);
 
        DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n",
                                  dev->name, DREG ));
@@ -802,12 +799,10 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
 
        /* Fill in a Tx ring entry */
        if (lance_debug >= 3) {
-               printk( "%s: TX pkt type 0x%04x from "
-                               "%s to %s"
+               printk( "%s: TX pkt type 0x%04x from %pM to %pM"
                                " data at 0x%08x len %d\n",
                                dev->name, ((u_short *)skb->data)[6],
-                               print_mac(mac, &skb->data[6]),
-                               print_mac(mac2, skb->data),
+                               &skb->data[6], skb->data,
                                (int)skb->data, (int)skb->len );
        }
 
@@ -865,7 +860,7 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id )
                return IRQ_NONE;
        }
 
-       lp = (struct lance_private *)dev->priv;
+       lp = netdev_priv(dev);
        IO = lp->iobase;
        spin_lock (&lp->devlock);
 
@@ -965,8 +960,8 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id )
 
 
 static int lance_rx( struct net_device *dev )
-
-{      struct lance_private *lp = (struct lance_private *)dev->priv;
+{
+       struct lance_private *lp = netdev_priv(dev);
        int entry = lp->cur_rx & RX_RING_MOD_MASK;
        int i;
 
@@ -1019,14 +1014,12 @@ static int lance_rx( struct net_device *dev )
 
                                if (lance_debug >= 3) {
                                        u_char *data = PKTBUF_ADDR(head);
-                                       DECLARE_MAC_BUF(mac);
-                                       DECLARE_MAC_BUF(mac2);
 
-                                       printk(KERN_DEBUG "%s: RX pkt type 0x%04x from %s to %s "
+                                       printk(KERN_DEBUG "%s: RX pkt type 0x%04x from %pM to %pM "
                                                   "data %02x %02x %02x %02x %02x %02x %02x %02x "
                                                   "len %d\n",
                                                   dev->name, ((u_short *)data)[6],
-                                                  print_mac(mac, &data[6]), print_mac(mac2, data),
+                                                  &data[6], data,
                                                   data[15], data[16], data[17], data[18],
                                                   data[19], data[20], data[21], data[22],
                                                   pkt_len);
@@ -1037,7 +1030,6 @@ static int lance_rx( struct net_device *dev )
                                lp->memcpy_f( skb->data, PKTBUF_ADDR(head), pkt_len );
                                skb->protocol = eth_type_trans( skb, dev );
                                netif_rx( skb );
-                               dev->last_rx = jiffies;
                                dev->stats.rx_packets++;
                                dev->stats.rx_bytes += pkt_len;
                        }
@@ -1057,8 +1049,8 @@ static int lance_rx( struct net_device *dev )
 
 
 static int lance_close( struct net_device *dev )
-
-{      struct lance_private *lp = (struct lance_private *)dev->priv;
+{
+       struct lance_private *lp = netdev_priv(dev);
        struct lance_ioreg       *IO = lp->iobase;
 
        netif_stop_queue (dev);
@@ -1084,8 +1076,8 @@ static int lance_close( struct net_device *dev )
  */
 
 static void set_multicast_list( struct net_device *dev )
-
-{      struct lance_private *lp = (struct lance_private *)dev->priv;
+{
+       struct lance_private *lp = netdev_priv(dev);
        struct lance_ioreg       *IO = lp->iobase;
 
        if (netif_running(dev))
@@ -1126,8 +1118,8 @@ static void set_multicast_list( struct net_device *dev )
 /* This is needed for old RieblCards and possible for new RieblCards */
 
 static int lance_set_mac_address( struct net_device *dev, void *addr )
-
-{      struct lance_private *lp = (struct lance_private *)dev->priv;
+{
+       struct lance_private *lp = netdev_priv(dev);
        struct sockaddr *saddr = addr;
        int i;
 
index 9b603528143d6dcee4da35059d74a7a0e8902964..c8b7cea4b14e0369da3eb73b5d6fb320e2da2079 100644 (file)
@@ -1460,7 +1460,6 @@ static void atl1e_clean_rx_irq(struct atl1e_adapter *adapter, u8 que,
                                netif_receive_skb(skb);
                        }
 
-                       netdev->last_rx = jiffies;
 skip_pkt:
        /* skip current packet whether it's ok or not. */
                        rx_page->read_offset +=
@@ -2488,7 +2487,7 @@ static pci_ers_result_t
 atl1e_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1e_adapter *adapter = netdev->priv;
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
 
        netif_device_detach(netdev);
 
@@ -2511,7 +2510,7 @@ atl1e_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
 static pci_ers_result_t atl1e_io_slot_reset(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1e_adapter *adapter = netdev->priv;
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
 
        if (pci_enable_device(pdev)) {
                dev_err(&pdev->dev,
@@ -2539,7 +2538,7 @@ static pci_ers_result_t atl1e_io_slot_reset(struct pci_dev *pdev)
 static void atl1e_io_resume(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct atl1e_adapter *adapter = netdev->priv;
+       struct atl1e_adapter *adapter = netdev_priv(netdev);
 
        if (netif_running(netdev)) {
                if (atl1e_up(adapter)) {
index aef403d299eef1a5b04a4218070c0e51594fa288..611a86ebe16460a3ea8775dc1da319b13b14e966 100644 (file)
@@ -1390,7 +1390,8 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
        /* auto-neg, insert timer to re-config phy */
        if (!adapter->phy_timer_pending) {
                adapter->phy_timer_pending = true;
-               mod_timer(&adapter->phy_config_timer, jiffies + 3 * HZ);
+               mod_timer(&adapter->phy_config_timer,
+                         round_jiffies(jiffies + 3 * HZ));
        }
 
        return 0;
@@ -1662,6 +1663,7 @@ static void atl1_via_workaround(struct atl1_adapter *adapter)
 
 static void atl1_inc_smb(struct atl1_adapter *adapter)
 {
+       struct net_device *netdev = adapter->netdev;
        struct stats_msg_block *smb = adapter->smb.smb;
 
        /* Fill out the OS statistics structure */
@@ -1704,30 +1706,30 @@ static void atl1_inc_smb(struct atl1_adapter *adapter)
        adapter->soft_stats.tx_trunc += smb->tx_trunc;
        adapter->soft_stats.tx_pause += smb->tx_pause;
 
-       adapter->net_stats.rx_packets = adapter->soft_stats.rx_packets;
-       adapter->net_stats.tx_packets = adapter->soft_stats.tx_packets;
-       adapter->net_stats.rx_bytes = adapter->soft_stats.rx_bytes;
-       adapter->net_stats.tx_bytes = adapter->soft_stats.tx_bytes;
-       adapter->net_stats.multicast = adapter->soft_stats.multicast;
-       adapter->net_stats.collisions = adapter->soft_stats.collisions;
-       adapter->net_stats.rx_errors = adapter->soft_stats.rx_errors;
-       adapter->net_stats.rx_over_errors =
+       netdev->stats.rx_packets = adapter->soft_stats.rx_packets;
+       netdev->stats.tx_packets = adapter->soft_stats.tx_packets;
+       netdev->stats.rx_bytes = adapter->soft_stats.rx_bytes;
+       netdev->stats.tx_bytes = adapter->soft_stats.tx_bytes;
+       netdev->stats.multicast = adapter->soft_stats.multicast;
+       netdev->stats.collisions = adapter->soft_stats.collisions;
+       netdev->stats.rx_errors = adapter->soft_stats.rx_errors;
+       netdev->stats.rx_over_errors =
                adapter->soft_stats.rx_missed_errors;
-       adapter->net_stats.rx_length_errors =
+       netdev->stats.rx_length_errors =
                adapter->soft_stats.rx_length_errors;
-       adapter->net_stats.rx_crc_errors = adapter->soft_stats.rx_crc_errors;
-       adapter->net_stats.rx_frame_errors =
+       netdev->stats.rx_crc_errors = adapter->soft_stats.rx_crc_errors;
+       netdev->stats.rx_frame_errors =
                adapter->soft_stats.rx_frame_errors;
-       adapter->net_stats.rx_fifo_errors = adapter->soft_stats.rx_fifo_errors;
-       adapter->net_stats.rx_missed_errors =
+       netdev->stats.rx_fifo_errors = adapter->soft_stats.rx_fifo_errors;
+       netdev->stats.rx_missed_errors =
                adapter->soft_stats.rx_missed_errors;
-       adapter->net_stats.tx_errors = adapter->soft_stats.tx_errors;
-       adapter->net_stats.tx_fifo_errors = adapter->soft_stats.tx_fifo_errors;
-       adapter->net_stats.tx_aborted_errors =
+       netdev->stats.tx_errors = adapter->soft_stats.tx_errors;
+       netdev->stats.tx_fifo_errors = adapter->soft_stats.tx_fifo_errors;
+       netdev->stats.tx_aborted_errors =
                adapter->soft_stats.tx_aborted_errors;
-       adapter->net_stats.tx_window_errors =
+       netdev->stats.tx_window_errors =
                adapter->soft_stats.tx_window_errors;
-       adapter->net_stats.tx_carrier_errors =
+       netdev->stats.tx_carrier_errors =
                adapter->soft_stats.tx_carrier_errors;
 }
 
@@ -1860,7 +1862,7 @@ static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter)
                                       adapter->rx_buffer_len + NET_IP_ALIGN);
                if (unlikely(!skb)) {
                        /* Better luck next round */
-                       adapter->net_stats.rx_dropped++;
+                       adapter->netdev->stats.rx_dropped++;
                        break;
                }
 
@@ -2026,8 +2028,6 @@ rrd_ok:
                buffer_info->skb = NULL;
                buffer_info->alloced = 0;
                rrd->xsz.valid = 0;
-
-               adapter->netdev->last_rx = jiffies;
        }
 
        atomic_set(&rrd_ring->next_to_clean, rrd_next_to_clean);
@@ -2524,17 +2524,6 @@ static irqreturn_t atl1_intr(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-/*
- * atl1_watchdog - Timer Call-back
- * @data: pointer to netdev cast into an unsigned long
- */
-static void atl1_watchdog(unsigned long data)
-{
-       struct atl1_adapter *adapter = (struct atl1_adapter *)data;
-
-       /* Reset the timer */
-       mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
-}
 
 /*
  * atl1_phy_config - Timer Call-back
@@ -2607,7 +2596,6 @@ static s32 atl1_up(struct atl1_adapter *adapter)
        if (unlikely(err))
                goto err_up;
 
-       mod_timer(&adapter->watchdog_timer, jiffies);
        atlx_irq_enable(adapter);
        atl1_check_link(adapter);
        netif_start_queue(netdev);
@@ -2625,7 +2613,6 @@ static void atl1_down(struct atl1_adapter *adapter)
        struct net_device *netdev = adapter->netdev;
 
        netif_stop_queue(netdev);
-       del_timer_sync(&adapter->watchdog_timer);
        del_timer_sync(&adapter->phy_config_timer);
        adapter->phy_timer_pending = false;
 
@@ -2983,7 +2970,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
        netdev->open = &atl1_open;
        netdev->stop = &atl1_close;
        netdev->hard_start_xmit = &atl1_xmit_frame;
-       netdev->get_stats = &atlx_get_stats;
+
        netdev->set_multicast_list = &atlx_set_multi;
        netdev->set_mac_address = &atl1_set_mac;
        netdev->change_mtu = &atl1_change_mtu;
@@ -3049,13 +3036,8 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
        netif_carrier_off(netdev);
        netif_stop_queue(netdev);
 
-       init_timer(&adapter->watchdog_timer);
-       adapter->watchdog_timer.function = &atl1_watchdog;
-       adapter->watchdog_timer.data = (unsigned long)adapter;
-
-       init_timer(&adapter->phy_config_timer);
-       adapter->phy_config_timer.function = &atl1_phy_config;
-       adapter->phy_config_timer.data = (unsigned long)adapter;
+       setup_timer(&adapter->phy_config_timer, &atl1_phy_config,
+                   (unsigned long)adapter);
        adapter->phy_timer_pending = false;
 
        INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task);
@@ -3173,8 +3155,6 @@ static struct atl1_stats atl1_gstrings_stats[] = {
        {"tx_bytes", ATL1_STAT(soft_stats.tx_bytes)},
        {"rx_errors", ATL1_STAT(soft_stats.rx_errors)},
        {"tx_errors", ATL1_STAT(soft_stats.tx_errors)},
-       {"rx_dropped", ATL1_STAT(net_stats.rx_dropped)},
-       {"tx_dropped", ATL1_STAT(net_stats.tx_dropped)},
        {"multicast", ATL1_STAT(soft_stats.multicast)},
        {"collisions", ATL1_STAT(soft_stats.collisions)},
        {"rx_length_errors", ATL1_STAT(soft_stats.rx_length_errors)},
index ffa73fc8d95e6eca471ee18ec73986653bb492b3..146372fd66832843996b05216dd70d1e1d612c85 100644 (file)
@@ -754,7 +754,7 @@ struct atl1_hw {
 struct atl1_adapter {
        struct net_device *netdev;
        struct pci_dev *pdev;
-       struct net_device_stats net_stats;
+
        struct atl1_sft_stats soft_stats;
        struct vlan_group *vlgrp;
        u32 rx_buffer_len;
@@ -765,7 +765,7 @@ struct atl1_adapter {
        struct work_struct tx_timeout_task;
        struct work_struct link_chg_task;
        struct work_struct pcie_dma_to_rst_task;
-       struct timer_list watchdog_timer;
+
        struct timer_list phy_config_timer;
        bool phy_timer_pending;
 
index f5bdc92c1a658932cb2de2663e8aad88478c9da6..60c9e5375eed406dd151ac38d7254616028feb88 100644 (file)
@@ -418,7 +418,7 @@ static void atl2_intr_rx(struct atl2_adapter *adapter)
                                 * Check that some rx space is free. If not,
                                 * free one and mark stats->rx_dropped++.
                                 */
-                               adapter->net_stats.rx_dropped++;
+                               netdev->stats.rx_dropped++;
                                break;
                        }
                        skb_reserve(skb, NET_IP_ALIGN);
@@ -435,20 +435,19 @@ static void atl2_intr_rx(struct atl2_adapter *adapter)
                        } else
 #endif
                        netif_rx(skb);
-                       adapter->net_stats.rx_bytes += rx_size;
-                       adapter->net_stats.rx_packets++;
-                       netdev->last_rx = jiffies;
+                       netdev->stats.rx_bytes += rx_size;
+                       netdev->stats.rx_packets++;
                } else {
-                       adapter->net_stats.rx_errors++;
+                       netdev->stats.rx_errors++;
 
                        if (rxd->status.ok && rxd->status.pkt_size <= 60)
-                               adapter->net_stats.rx_length_errors++;
+                               netdev->stats.rx_length_errors++;
                        if (rxd->status.mcast)
-                               adapter->net_stats.multicast++;
+                               netdev->stats.multicast++;
                        if (rxd->status.crc)
-                               adapter->net_stats.rx_crc_errors++;
+                               netdev->stats.rx_crc_errors++;
                        if (rxd->status.align)
-                               adapter->net_stats.rx_frame_errors++;
+                               netdev->stats.rx_frame_errors++;
                }
 
                /* advance write ptr */
@@ -463,6 +462,7 @@ static void atl2_intr_rx(struct atl2_adapter *adapter)
 
 static void atl2_intr_tx(struct atl2_adapter *adapter)
 {
+       struct net_device *netdev = adapter->netdev;
        u32 txd_read_ptr;
        u32 txs_write_ptr;
        struct tx_pkt_status *txs;
@@ -522,20 +522,20 @@ static void atl2_intr_tx(struct atl2_adapter *adapter)
 
                /* tx statistics: */
                if (txs->ok) {
-                       adapter->net_stats.tx_bytes += txs->pkt_size;
-                       adapter->net_stats.tx_packets++;
+                       netdev->stats.tx_bytes += txs->pkt_size;
+                       netdev->stats.tx_packets++;
                }
                else
-                       adapter->net_stats.tx_errors++;
+                       netdev->stats.tx_errors++;
 
                if (txs->defer)
-                       adapter->net_stats.collisions++;
+                       netdev->stats.collisions++;
                if (txs->abort_col)
-                       adapter->net_stats.tx_aborted_errors++;
+                       netdev->stats.tx_aborted_errors++;
                if (txs->late_col)
-                       adapter->net_stats.tx_window_errors++;
+                       netdev->stats.tx_window_errors++;
                if (txs->underun)
-                       adapter->net_stats.tx_fifo_errors++;
+                       netdev->stats.tx_fifo_errors++;
        } while (1);
 
        if (free_hole) {
@@ -621,7 +621,7 @@ static irqreturn_t atl2_intr(int irq, void *data)
 
        /* link event */
        if (status & (ISR_PHY | ISR_MANUAL)) {
-               adapter->net_stats.tx_carrier_errors++;
+               adapter->netdev->stats.tx_carrier_errors++;
                atl2_check_for_link(adapter);
        }
 
@@ -723,7 +723,7 @@ static int atl2_open(struct net_device *netdev)
 
        clear_bit(__ATL2_DOWN, &adapter->flags);
 
-       mod_timer(&adapter->watchdog_timer, jiffies + 4*HZ);
+       mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 4*HZ));
 
        val = ATL2_READ_REG(&adapter->hw, REG_MASTER_CTRL);
        ATL2_WRITE_REG(&adapter->hw, REG_MASTER_CTRL,
@@ -899,19 +899,6 @@ static int atl2_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        return NETDEV_TX_OK;
 }
 
-/*
- * atl2_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- *
- * Returns the address of the device statistics structure.
- * The statistics are actually updated from the timer callback.
- */
-static struct net_device_stats *atl2_get_stats(struct net_device *netdev)
-{
-       struct atl2_adapter *adapter = netdev_priv(netdev);
-       return &adapter->net_stats;
-}
-
 /*
  * atl2_change_mtu - Change the Maximum Transfer Unit
  * @netdev: network interface device structure
@@ -1050,18 +1037,21 @@ static void atl2_tx_timeout(struct net_device *netdev)
 static void atl2_watchdog(unsigned long data)
 {
        struct atl2_adapter *adapter = (struct atl2_adapter *) data;
-       u32 drop_rxd, drop_rxs;
-       unsigned long flags;
 
        if (!test_bit(__ATL2_DOWN, &adapter->flags)) {
+               u32 drop_rxd, drop_rxs;
+               unsigned long flags;
+
                spin_lock_irqsave(&adapter->stats_lock, flags);
                drop_rxd = ATL2_READ_REG(&adapter->hw, REG_STS_RXD_OV);
                drop_rxs = ATL2_READ_REG(&adapter->hw, REG_STS_RXS_OV);
-               adapter->net_stats.rx_over_errors += (drop_rxd+drop_rxs);
                spin_unlock_irqrestore(&adapter->stats_lock, flags);
 
+               adapter->netdev->stats.rx_over_errors += drop_rxd + drop_rxs;
+
                /* Reset the timer */
-               mod_timer(&adapter->watchdog_timer, jiffies + 4 * HZ);
+               mod_timer(&adapter->watchdog_timer,
+                         round_jiffies(jiffies + 4 * HZ));
        }
 }
 
@@ -1265,7 +1255,8 @@ static int atl2_check_link(struct atl2_adapter *adapter)
         * (if interval smaller than 5 seconds, something strange) */
        if (!test_bit(__ATL2_DOWN, &adapter->flags)) {
                if (!test_and_set_bit(0, &adapter->cfg_phy))
-                       mod_timer(&adapter->phy_config_timer, jiffies + 5 * HZ);
+                       mod_timer(&adapter->phy_config_timer,
+                                 round_jiffies(jiffies + 5 * HZ));
        }
 
        return 0;
@@ -1396,7 +1387,6 @@ static int __devinit atl2_probe(struct pci_dev *pdev,
        netdev->open = &atl2_open;
        netdev->stop = &atl2_close;
        netdev->hard_start_xmit = &atl2_xmit_frame;
-       netdev->get_stats = &atl2_get_stats;
        netdev->set_multicast_list = &atl2_set_multi;
        netdev->set_mac_address = &atl2_set_mac;
        netdev->change_mtu = &atl2_change_mtu;
index 09974df76b1865d138d0ebac05319e3e8d7692cd..d918bbe621eae3d9e44dc1ad141fad8019a6f7fe 100644 (file)
@@ -453,7 +453,6 @@ struct atl2_adapter {
        /* OS defined structs */
        struct net_device *netdev;
        struct pci_dev *pdev;
-       struct net_device_stats net_stats;
 #ifdef NETIF_F_HW_VLAN_TX
        struct vlan_group *vlgrp;
 #endif
index 3cc9d1089ca15b2c40ec80a88c124fe391116451..3dc01421567961450b6503f3bb2a98662bea2f07 100644 (file)
@@ -181,19 +181,6 @@ static void atlx_clear_phy_int(struct atlx_adapter *adapter)
        spin_unlock_irqrestore(&adapter->lock, flags);
 }
 
-/*
- * atlx_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- *
- * Returns the address of the device statistics structure.
- * The statistics are actually updated from the timer callback.
- */
-static struct net_device_stats *atlx_get_stats(struct net_device *netdev)
-{
-       struct atlx_adapter *adapter = netdev_priv(netdev);
-       return &adapter->net_stats;
-}
-
 /*
  * atlx_tx_timeout - Respond to a Tx Hang
  * @netdev: network interface device structure
index c10cd8058e2303da73054ce892d52878123d225c..7028b276dfd3c7d2f9db1d19e429f67f432dd371 100644 (file)
@@ -248,7 +248,6 @@ static int __init atp_probe1(long ioaddr)
        struct net_local *lp;
        int saved_ctrl_reg, status, i;
        int res;
-       DECLARE_MAC_BUF(mac);
 
        outb(0xff, ioaddr + PAR_DATA);
        /* Save the original value of the Control register, in case we guessed
@@ -324,8 +323,8 @@ static int __init atp_probe1(long ioaddr)
 #endif
 
        printk(KERN_NOTICE "%s: Pocket adapter found at %#3lx, IRQ %d, "
-              "SAPROM %s.\n",
-              dev->name, dev->base_addr, dev->irq, print_mac(mac, dev->dev_addr));
+              "SAPROM %pM.\n",
+              dev->name, dev->base_addr, dev->irq, dev->dev_addr);
 
        /* Reset the ethernet hardware and activate the printer pass-through. */
        write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX);
@@ -913,7 +912,8 @@ static void __exit atp_cleanup_module(void) {
        struct net_device *next_dev;
 
        while (root_atp_dev) {
-               next_dev = ((struct net_local *)root_atp_dev->priv)->next_module;
+               struct net_local *atp_local = netdev_priv(root_atp_dev);
+               next_dev = atp_local->next_module;
                unregister_netdev(root_atp_dev);
                /* No need to release_region(), since we never snarf it. */
                free_netdev(root_atp_dev);
index 019b13c08ae6ead71f5a0b976b1e087a3df87df7..ecc2573b3dce29d7580331b1e9339fa458872fdb 100644 (file)
@@ -193,7 +193,7 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES];
  */
 static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg)
 {
-       struct au1000_private *aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
        volatile u32 *const mii_control_reg = &aup->mac->mii_control;
        volatile u32 *const mii_data_reg = &aup->mac->mii_data;
        u32 timedout = 20;
@@ -228,7 +228,7 @@ static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg)
 static void au1000_mdio_write(struct net_device *dev, int phy_addr,
                              int reg, u16 value)
 {
-       struct au1000_private *aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
        volatile u32 *const mii_control_reg = &aup->mac->mii_control;
        volatile u32 *const mii_data_reg = &aup->mac->mii_data;
        u32 timedout = 20;
@@ -283,7 +283,7 @@ static int au1000_mdiobus_reset(struct mii_bus *bus)
 
 static int mii_probe (struct net_device *dev)
 {
-       struct au1000_private *const aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *const aup = netdev_priv(dev);
        struct phy_device *phydev = NULL;
 
 #if defined(AU1XXX_PHY_STATIC_CONFIG)
@@ -415,7 +415,7 @@ void ReleaseDB(struct au1000_private *aup, db_dest_t *pDB)
 
 static void enable_rx_tx(struct net_device *dev)
 {
-       struct au1000_private *aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
 
        if (au1000_debug > 4)
                printk(KERN_INFO "%s: enable_rx_tx\n", dev->name);
@@ -426,7 +426,7 @@ static void enable_rx_tx(struct net_device *dev)
 
 static void hard_stop(struct net_device *dev)
 {
-       struct au1000_private *aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
 
        if (au1000_debug > 4)
                printk(KERN_INFO "%s: hard stop\n", dev->name);
@@ -438,7 +438,7 @@ static void hard_stop(struct net_device *dev)
 static void enable_mac(struct net_device *dev, int force_reset)
 {
        unsigned long flags;
-       struct au1000_private *aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
 
        spin_lock_irqsave(&aup->lock, flags);
 
@@ -457,7 +457,7 @@ static void enable_mac(struct net_device *dev, int force_reset)
 
 static void reset_mac_unlocked(struct net_device *dev)
 {
-       struct au1000_private *const aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *const aup = netdev_priv(dev);
        int i;
 
        hard_stop(dev);
@@ -483,7 +483,7 @@ static void reset_mac_unlocked(struct net_device *dev)
 
 static void reset_mac(struct net_device *dev)
 {
-       struct au1000_private *const aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *const aup = netdev_priv(dev);
        unsigned long flags;
 
        if (au1000_debug > 4)
@@ -572,7 +572,7 @@ static int __init au1000_init_module(void)
 
 static int au1000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-       struct au1000_private *aup = (struct au1000_private *)dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
 
        if (aup->phy_dev)
                return phy_ethtool_gset(aup->phy_dev, cmd);
@@ -582,7 +582,7 @@ static int au1000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 static int au1000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-       struct au1000_private *aup = (struct au1000_private *)dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
 
        if (!capable(CAP_NET_ADMIN))
                return -EPERM;
@@ -596,7 +596,7 @@ static int au1000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 static void
 au1000_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-       struct au1000_private *aup = (struct au1000_private *)dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
 
        strcpy(info->driver, DRV_NAME);
        strcpy(info->version, DRV_VERSION);
@@ -652,7 +652,7 @@ static struct net_device * au1000_probe(int port_num)
        printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
                dev->name, base, irq);
 
-       aup = dev->priv;
+       aup = netdev_priv(dev);
 
        spin_lock_init(&aup->lock);
 
@@ -817,7 +817,7 @@ err_out:
  */
 static int au1000_init(struct net_device *dev)
 {
-       struct au1000_private *aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
        unsigned long flags;
        int i;
        u32 control;
@@ -868,7 +868,7 @@ static int au1000_init(struct net_device *dev)
 static void
 au1000_adjust_link(struct net_device *dev)
 {
-       struct au1000_private *aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
        struct phy_device *phydev = aup->phy_dev;
        unsigned long flags;
 
@@ -947,7 +947,7 @@ au1000_adjust_link(struct net_device *dev)
 static int au1000_open(struct net_device *dev)
 {
        int retval;
-       struct au1000_private *aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
 
        if (au1000_debug > 4)
                printk("%s: open: dev=%p\n", dev->name, dev);
@@ -982,7 +982,7 @@ static int au1000_open(struct net_device *dev)
 static int au1000_close(struct net_device *dev)
 {
        unsigned long flags;
-       struct au1000_private *const aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *const aup = netdev_priv(dev);
 
        if (au1000_debug > 4)
                printk("%s: close: dev=%p\n", dev->name, dev);
@@ -1013,7 +1013,7 @@ static void __exit au1000_cleanup_module(void)
        for (i = 0; i < num_ifs; i++) {
                dev = iflist[i].dev;
                if (dev) {
-                       aup = (struct au1000_private *) dev->priv;
+                       aup = netdev_priv(dev);
                        unregister_netdev(dev);
                        mdiobus_unregister(aup->mii_bus);
                        mdiobus_free(aup->mii_bus);
@@ -1035,7 +1035,7 @@ static void __exit au1000_cleanup_module(void)
 
 static void update_tx_stats(struct net_device *dev, u32 status)
 {
-       struct au1000_private *aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
        struct net_device_stats *ps = &dev->stats;
 
        if (status & TX_FRAME_ABORTED) {
@@ -1064,7 +1064,7 @@ static void update_tx_stats(struct net_device *dev, u32 status)
  */
 static void au1000_tx_ack(struct net_device *dev)
 {
-       struct au1000_private *aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
        volatile tx_dma_t *ptxd;
 
        ptxd = aup->tx_dma_ring[aup->tx_tail];
@@ -1091,7 +1091,7 @@ static void au1000_tx_ack(struct net_device *dev)
  */
 static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
 {
-       struct au1000_private *aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
        struct net_device_stats *ps = &dev->stats;
        volatile tx_dma_t *ptxd;
        u32 buff_stat;
@@ -1145,7 +1145,7 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
 
 static inline void update_rx_stats(struct net_device *dev, u32 status)
 {
-       struct au1000_private *aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
        struct net_device_stats *ps = &dev->stats;
 
        ps->rx_packets++;
@@ -1173,7 +1173,7 @@ static inline void update_rx_stats(struct net_device *dev, u32 status)
  */
 static int au1000_rx(struct net_device *dev)
 {
-       struct au1000_private *aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
        struct sk_buff *skb;
        volatile rx_dma_t *prxd;
        u32 buff_stat, status;
@@ -1240,7 +1240,6 @@ static int au1000_rx(struct net_device *dev)
                /* next descriptor */
                prxd = aup->rx_dma_ring[aup->rx_head];
                buff_stat = prxd->buff_stat;
-               dev->last_rx = jiffies;
        }
        return 0;
 }
@@ -1276,7 +1275,7 @@ static void au1000_tx_timeout(struct net_device *dev)
 
 static void set_rx_mode(struct net_device *dev)
 {
-       struct au1000_private *aup = (struct au1000_private *) dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
 
        if (au1000_debug > 4)
                printk("%s: set_rx_mode: flags=%x\n", dev->name, dev->flags);
@@ -1308,7 +1307,7 @@ static void set_rx_mode(struct net_device *dev)
 
 static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-       struct au1000_private *aup = (struct au1000_private *)dev->priv;
+       struct au1000_private *aup = netdev_priv(dev);
 
        if (!netif_running(dev)) return -EINVAL;
 
index 9a314d88e7b67aa16b74e60c442bc655242d9bf8..337488ec707cfc2aad6b14ae7aec63315510529c 100644 (file)
@@ -758,13 +758,10 @@ static int ax_init_dev(struct net_device *dev, int first_init)
 #endif
        ax_NS8390_init(dev, 0);
 
-       if (first_init) {
-               DECLARE_MAC_BUF(mac);
-
-               dev_info(&ax->dev->dev, "%dbit, irq %d, %lx, MAC: %s\n",
+       if (first_init)
+               dev_info(&ax->dev->dev, "%dbit, irq %d, %lx, MAC: %pM\n",
                         ei_status.word16 ? 16:8, dev->irq, dev->base_addr,
-                        print_mac(mac, dev->dev_addr));
-       }
+                        dev->dev_addr);
 
        ret = register_netdev(dev);
        if (ret)
index c3bda5ce67c488dba1fc7f51469f16522c5b1080..2c7a32eb92a5c1ffdaa33f3fd008427d47192884 100644 (file)
@@ -829,7 +829,6 @@ static int b44_rx(struct b44 *bp, int budget)
                skb->ip_summed = CHECKSUM_NONE;
                skb->protocol = eth_type_trans(skb, bp->dev);
                netif_receive_skb(skb);
-               bp->dev->last_rx = jiffies;
                received++;
                budget--;
        next_pkt:
@@ -2117,7 +2116,6 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
        struct net_device *dev;
        struct b44 *bp;
        int err;
-       DECLARE_MAC_BUF(mac);
 
        instance++;
 
@@ -2213,8 +2211,8 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
         */
        b44_chip_reset(bp, B44_CHIP_RESET_FULL);
 
-       printk(KERN_INFO "%s: Broadcom 44xx/47xx 10/100BaseT Ethernet %s\n",
-              dev->name, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: Broadcom 44xx/47xx 10/100BaseT Ethernet %pM\n",
+              dev->name, dev->dev_addr);
 
        return 0;
 
index b458d607a9c669215b48ffa831fe0c86cd4fde88..78e31aa861e020e461336e2323cea4647d7cb9c8 100644 (file)
@@ -741,7 +741,6 @@ static void bfin_mac_rx(struct net_device *dev)
        blackfin_dcache_invalidate_range((unsigned long)skb->head,
                                         (unsigned long)skb->tail);
 
-       dev->last_rx = jiffies;
        skb->protocol = eth_type_trans(skb, dev);
 #if defined(BFIN_MAC_CSUM_OFFLOAD)
        skb->csum = current_rx_ptr->status.ip_payload_csum;
index a42bd19646d371e0ce75245280e446215495258e..8a546a33d58124fb39cf67ff673e305f7a7fd418 100644 (file)
@@ -716,13 +716,11 @@ static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id)
                        skb_put(skb, nb);
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        ++dev->stats.rx_packets;
                        dev->stats.rx_bytes += nb;
                } else {
                        ++dev->stats.rx_dropped;
                }
-               dev->last_rx = jiffies;
                if ((skb = bp->rx_bufs[i]) == NULL) {
                        bp->rx_bufs[i] = skb = dev_alloc_skb(RX_BUFLEN+2);
                        if (skb != NULL)
@@ -1258,7 +1256,6 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i
        unsigned char addr[6];
        struct net_device *dev;
        int is_bmac_plus = ((int)match->data) != 0;
-       DECLARE_MAC_BUF(mac);
 
        if (macio_resource_count(mdev) != 3 || macio_irq_count(mdev) != 3) {
                printk(KERN_ERR "BMAC: can't use, need 3 addrs and 3 intrs\n");
@@ -1368,8 +1365,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i
                goto err_out_irq2;
        }
 
-       printk(KERN_INFO "%s: BMAC%s at %s",
-              dev->name, (is_bmac_plus ? "+" : ""), print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: BMAC%s at %pM",
+              dev->name, (is_bmac_plus ? "+" : ""), dev->dev_addr);
        XXDEBUG((", base_addr=%#0lx", dev->base_addr));
        printk("\n");
 
index d07e3f1489510642c0cde8b41b96875fdc115c92..fe802215214f7e09794e441a9733b0f5b0ce72fa 100644 (file)
@@ -57,8 +57,8 @@
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.8.1"
-#define DRV_MODULE_RELDATE     "Oct 7, 2008"
+#define DRV_MODULE_VERSION     "1.8.2"
+#define DRV_MODULE_RELDATE     "Nov 10, 2008"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -89,6 +89,7 @@ typedef enum {
        BCM5709,
        BCM5709S,
        BCM5716,
+       BCM5716S,
 } board_t;
 
 /* indexed by board_t, above */
@@ -105,6 +106,7 @@ static struct {
        { "Broadcom NetXtreme II BCM5709 1000Base-T" },
        { "Broadcom NetXtreme II BCM5709 1000Base-SX" },
        { "Broadcom NetXtreme II BCM5716 1000Base-T" },
+       { "Broadcom NetXtreme II BCM5716 1000Base-SX" },
        };
 
 static DEFINE_PCI_DEVICE_TABLE(bnx2_pci_tbl) = {
@@ -128,6 +130,8 @@ static DEFINE_PCI_DEVICE_TABLE(bnx2_pci_tbl) = {
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5709S },
        { PCI_VENDOR_ID_BROADCOM, 0x163b,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5716 },
+       { PCI_VENDOR_ID_BROADCOM, 0x163c,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5716 },
        { 0, }
 };
 
@@ -1652,7 +1656,7 @@ bnx2_setup_serdes_phy(struct bnx2 *bp, u8 port)
                 * exchanging base pages plus 3 next pages and
                 * normally completes in about 120 msec.
                 */
-               bp->current_interval = SERDES_AN_TIMEOUT;
+               bp->current_interval = BNX2_SERDES_AN_TIMEOUT;
                bp->serdes_an_pending = 1;
                mod_timer(&bp->timer, jiffies + bp->current_interval);
        } else {
@@ -2274,7 +2278,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int ack, int silent)
                return 0;
 
        /* wait for an acknowledgement. */
-       for (i = 0; i < (FW_ACK_TIME_OUT_MS / 10); i++) {
+       for (i = 0; i < (BNX2_FW_ACK_TIME_OUT_MS / 10); i++) {
                msleep(10);
 
                val = bnx2_shmem_rd(bp, BNX2_FW_MB);
@@ -3000,7 +3004,6 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 #endif
                        netif_receive_skb(skb);
 
-               bp->dev->last_rx = jiffies;
                rx_pkt++;
 
 next_rx:
@@ -4470,7 +4473,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
 static int
 bnx2_init_chip(struct bnx2 *bp)
 {
-       u32 val;
+       u32 val, mtu;
        int rc, i;
 
        /* Make sure the interrupt is not active. */
@@ -4562,11 +4565,19 @@ bnx2_init_chip(struct bnx2 *bp)
        REG_WR(bp, BNX2_EMAC_BACKOFF_SEED, val);
 
        /* Program the MTU.  Also include 4 bytes for CRC32. */
-       val = bp->dev->mtu + ETH_HLEN + 4;
+       mtu = bp->dev->mtu;
+       val = mtu + ETH_HLEN + ETH_FCS_LEN;
        if (val > (MAX_ETHERNET_PACKET_SIZE + 4))
                val |= BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA;
        REG_WR(bp, BNX2_EMAC_RX_MTU_SIZE, val);
 
+       if (mtu < 1500)
+               mtu = 1500;
+
+       bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG, BNX2_RBUF_CONFIG_VAL(mtu));
+       bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG2, BNX2_RBUF_CONFIG2_VAL(mtu));
+       bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG3, BNX2_RBUF_CONFIG3_VAL(mtu));
+
        for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
                bp->bnx2_napi[i].last_status_idx = 0;
 
@@ -5694,7 +5705,7 @@ bnx2_5708_serdes_timer(struct bnx2 *bp)
                bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
                if (bmcr & BMCR_ANENABLE) {
                        bnx2_enable_forced_2g5(bp);
-                       bp->current_interval = SERDES_FORCED_TIMEOUT;
+                       bp->current_interval = BNX2_SERDES_FORCED_TIMEOUT;
                } else {
                        bnx2_disable_forced_2g5(bp);
                        bp->serdes_an_pending = 2;
@@ -6511,7 +6522,7 @@ bnx2_nway_reset(struct net_device *dev)
 
                spin_lock_bh(&bp->phy_lock);
 
-               bp->current_interval = SERDES_AN_TIMEOUT;
+               bp->current_interval = BNX2_SERDES_AN_TIMEOUT;
                bp->serdes_an_pending = 1;
                mod_timer(&bp->timer, jiffies + bp->current_interval);
        }
@@ -7586,7 +7597,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
 
        if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
            (CHIP_ID(bp) == CHIP_ID_5708_B0) ||
-           (CHIP_ID(bp) == CHIP_ID_5708_B1)) {
+           (CHIP_ID(bp) == CHIP_ID_5708_B1) ||
+           !(REG_RD(bp, BNX2_PCI_CONFIG_3) & BNX2_PCI_CONFIG_3_VAUX_PRESET)) {
                bp->flags |= BNX2_FLAG_NO_WOL;
                bp->wol = 0;
        }
@@ -7703,7 +7715,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        struct bnx2 *bp;
        int rc;
        char str[40];
-       DECLARE_MAC_BUF(mac);
 
        if (version_printed++ == 0)
                printk(KERN_INFO "%s", version);
@@ -7770,14 +7781,14 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
 
        printk(KERN_INFO "%s: %s (%c%d) %s found at mem %lx, "
-               "IRQ %d, node addr %s\n",
+               "IRQ %d, node addr %pM\n",
                dev->name,
                board_info[ent->driver_data].name,
                ((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
                ((CHIP_ID(bp) & 0x0ff0) >> 4),
                bnx2_bus_string(bp, str),
                dev->base_addr,
-               bp->pdev->irq, print_mac(mac, dev->dev_addr));
+               bp->pdev->irq, dev->dev_addr);
 
        return 0;
 }
index 617d953401607e884873cf41a32fdf6dd73c1024..34ca47812af43440777a457a95eeececaa27ca02 100644 (file)
@@ -4199,7 +4199,14 @@ struct l2_fhdr {
 
 #define BNX2_RBUF_CONFIG                               0x0020000c
 #define BNX2_RBUF_CONFIG_XOFF_TRIP                      (0x3ffL<<0)
+#define BNX2_RBUF_CONFIG_XOFF_TRIP_VAL(mtu)             \
+       ((((mtu) - 1500) * 31 / 1000) + 54)
 #define BNX2_RBUF_CONFIG_XON_TRIP                       (0x3ffL<<16)
+#define BNX2_RBUF_CONFIG_XON_TRIP_VAL(mtu)              \
+       ((((mtu) - 1500) * 39 / 1000) + 66)
+#define BNX2_RBUF_CONFIG_VAL(mtu)                       \
+       (BNX2_RBUF_CONFIG_XOFF_TRIP_VAL(mtu) |           \
+       (BNX2_RBUF_CONFIG_XON_TRIP_VAL(mtu) << 16))
 
 #define BNX2_RBUF_FW_BUF_ALLOC                         0x00200010
 #define BNX2_RBUF_FW_BUF_ALLOC_VALUE                    (0x1ffL<<7)
@@ -4221,11 +4228,25 @@ struct l2_fhdr {
 
 #define BNX2_RBUF_CONFIG2                              0x0020001c
 #define BNX2_RBUF_CONFIG2_MAC_DROP_TRIP                         (0x3ffL<<0)
+#define BNX2_RBUF_CONFIG2_MAC_DROP_TRIP_VAL(mtu)        \
+       ((((mtu) - 1500) * 4 / 1000) + 5)
 #define BNX2_RBUF_CONFIG2_MAC_KEEP_TRIP                         (0x3ffL<<16)
+#define BNX2_RBUF_CONFIG2_MAC_KEEP_TRIP_VAL(mtu)        \
+       ((((mtu) - 1500) * 2 / 100) + 30)
+#define BNX2_RBUF_CONFIG2_VAL(mtu)                      \
+       (BNX2_RBUF_CONFIG2_MAC_DROP_TRIP_VAL(mtu) |      \
+       (BNX2_RBUF_CONFIG2_MAC_KEEP_TRIP_VAL(mtu) << 16))
 
 #define BNX2_RBUF_CONFIG3                              0x00200020
 #define BNX2_RBUF_CONFIG3_CU_DROP_TRIP                  (0x3ffL<<0)
+#define BNX2_RBUF_CONFIG3_CU_DROP_TRIP_VAL(mtu)                 \
+       ((((mtu) - 1500) * 12 / 1000) + 18)
 #define BNX2_RBUF_CONFIG3_CU_KEEP_TRIP                  (0x3ffL<<16)
+#define BNX2_RBUF_CONFIG3_CU_KEEP_TRIP_VAL(mtu)                 \
+       ((((mtu) - 1500) * 2 / 100) + 30)
+#define BNX2_RBUF_CONFIG3_VAL(mtu)                      \
+       (BNX2_RBUF_CONFIG3_CU_DROP_TRIP_VAL(mtu) |       \
+       (BNX2_RBUF_CONFIG3_CU_KEEP_TRIP_VAL(mtu) << 16))
 
 #define BNX2_RBUF_PKT_DATA                             0x00208000
 #define BNX2_RBUF_CLIST_DATA                           0x00210000
@@ -6658,8 +6679,6 @@ struct bnx2_napi {
        struct bnx2_tx_ring_info        tx_ring;
 };
 
-#define BNX2_TIMER_INTERVAL                    HZ
-
 struct bnx2 {
        /* Fields used in the tx and intr/napi performance paths are grouped */
        /* together in the beginning of the structure. */
@@ -6707,7 +6726,11 @@ struct bnx2 {
 
        /* End of fields used in the performance code paths. */
 
-       int                     current_interval;
+       unsigned int            current_interval;
+#define BNX2_TIMER_INTERVAL            HZ
+#define BNX2_SERDES_AN_TIMEOUT         (HZ / 3)
+#define BNX2_SERDES_FORCED_TIMEOUT     (HZ / 10)
+
        struct                  timer_list timer;
        struct work_struct      reset_task;
 
@@ -6839,8 +6862,6 @@ struct bnx2 {
 #define PHY_LOOPBACK           2
 
        u8                      serdes_an_pending;
-#define SERDES_AN_TIMEOUT      (HZ / 3)
-#define SERDES_FORCED_TIMEOUT  (HZ / 10)
 
        u8                      mac_addr[8];
 
@@ -6938,14 +6959,14 @@ struct fw_info {
 /* This value (in milliseconds) determines the frequency of the driver
  * issuing the PULSE message code.  The firmware monitors this periodic
  * pulse to determine when to switch to an OS-absent mode. */
-#define DRV_PULSE_PERIOD_MS                 250
+#define BNX2_DRV_PULSE_PERIOD_MS                 250
 
 /* This value (in milliseconds) determines how long the driver should
  * wait for an acknowledgement from the firmware before timing out.  Once
  * the firmware has timed out, the driver will assume there is no firmware
  * running and there won't be any firmware-driver synchronization during a
  * driver reset. */
-#define FW_ACK_TIME_OUT_MS                  1000
+#define BNX2_FW_ACK_TIME_OUT_MS                  1000
 
 
 #define BNX2_DRV_RESET_SIGNATURE               0x00000000
index 600210d7eff95da4f60840b530f149cec8259e45..49f8e7891626e9f906a2532b3502328796bc81af 100644 (file)
@@ -1328,7 +1328,6 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
                        dev_kfree_skb(skb);
                }
 
-               bp->dev->last_rx = jiffies;
 
                /* put new skb in bin */
                fp->tpa_pool[queue].skb = new_skb;
@@ -1557,7 +1556,6 @@ reuse_rx:
 #endif
                        netif_receive_skb(skb);
 
-               bp->dev->last_rx = jiffies;
 
 next_rx:
                rx_buf->skb = NULL;
@@ -8769,7 +8767,6 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
        rc = 0;
 
 test_loopback_rx_exit:
-       bp->dev->last_rx = jiffies;
 
        fp->rx_bd_cons = NEXT_RX_IDX(fp->rx_bd_cons);
        fp->rx_bd_prod = NEXT_RX_IDX(fp->rx_bd_prod);
@@ -9853,11 +9850,8 @@ static void bnx2x_set_rx_mode(struct net_device *dev)
                             mclist && (i < dev->mc_count);
                             i++, mclist = mclist->next) {
 
-                               DP(NETIF_MSG_IFUP, "Adding mcast MAC: "
-                                  "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                                  mclist->dmi_addr[0], mclist->dmi_addr[1],
-                                  mclist->dmi_addr[2], mclist->dmi_addr[3],
-                                  mclist->dmi_addr[4], mclist->dmi_addr[5]);
+                               DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n",
+                                  mclist->dmi_addr);
 
                                crc = crc32c_le(0, mclist->dmi_addr, ETH_ALEN);
                                bit = (crc >> 24) & 0xff;
@@ -10092,8 +10086,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
 
        dev->irq = pdev->irq;
 
-       bp->regview = ioremap_nocache(dev->base_addr,
-                                     pci_resource_len(pdev, 0));
+       bp->regview = pci_ioremap_bar(pdev, 0);
        if (!bp->regview) {
                printk(KERN_ERR PFX "Cannot map register space, aborting\n");
                rc = -ENOMEM;
@@ -10194,7 +10187,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
        struct net_device *dev = NULL;
        struct bnx2x *bp;
        int rc;
-       DECLARE_MAC_BUF(mac);
 
        if (version_printed++ == 0)
                printk(KERN_INFO "%s", version);
@@ -10238,7 +10230,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
               bnx2x_get_pcie_width(bp),
               (bnx2x_get_pcie_speed(bp) == 2) ? "5GHz (Gen2)" : "2.5GHz",
               dev->base_addr, bp->pdev->irq);
-       printk(KERN_CONT "node addr %s\n", print_mac(mac, dev->dev_addr));
+       printk(KERN_CONT "node addr %pM\n", dev->dev_addr);
        return 0;
 
 init_one_exit:
index 5cdae2bc055a9c27d679af0793d97bce459c0fd1..6f9c6faef24c4079741128e2e88f18c2cea3f979 100644 (file)
@@ -6,3 +6,6 @@ obj-$(CONFIG_BONDING) += bonding.o
 
 bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o
 
+ipv6-$(subst m,y,$(CONFIG_IPV6)) += bond_ipv6.o
+bonding-objs += $(ipv6-y)
+
index 6106660a4a44b9a68f7a5b9a9c9c26a5b45ee689..78f645d6471a15ccd4206fba93e9ad18fc611ead 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/netdevice.h>
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
+#include <linux/etherdevice.h>
 #include <linux/if_bonding.h>
 #include <linux/pkt_sched.h>
 #include <net/net_namespace.h>
@@ -236,6 +237,17 @@ static inline struct aggregator *__get_next_agg(struct aggregator *aggregator)
        return &(SLAVE_AD_INFO(slave->next).aggregator);
 }
 
+/*
+ * __agg_has_partner
+ *
+ * Return nonzero if aggregator has a partner (denoted by a non-zero ether
+ * address for the partner).  Return 0 if not.
+ */
+static inline int __agg_has_partner(struct aggregator *agg)
+{
+       return !is_zero_ether_addr(agg->partner_system.mac_addr_value);
+}
+
 /**
  * __disable_port - disable the port's slave
  * @port: the port we're looking at
@@ -274,14 +286,14 @@ static inline int __port_is_enabled(struct port *port)
  * __get_agg_selection_mode - get the aggregator selection mode
  * @port: the port we're looking at
  *
- * Get the aggregator selection mode. Can be %BANDWIDTH or %COUNT.
+ * Get the aggregator selection mode. Can be %STABLE, %BANDWIDTH or %COUNT.
  */
 static inline u32 __get_agg_selection_mode(struct port *port)
 {
        struct bonding *bond = __get_bond_by_port(port);
 
        if (bond == NULL) {
-               return AD_BANDWIDTH;
+               return BOND_AD_STABLE;
        }
 
        return BOND_AD_INFO(bond).agg_select_mode;
@@ -1414,9 +1426,82 @@ static void ad_port_selection_logic(struct port *port)
        // else set ready=FALSE in all aggregator's ports
        __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator));
 
-       if (!__check_agg_selection_timer(port) && (aggregator = __get_first_agg(port))) {
-               ad_agg_selection_logic(aggregator);
+       aggregator = __get_first_agg(port);
+       ad_agg_selection_logic(aggregator);
+}
+
+/*
+ * Decide if "agg" is a better choice for the new active aggregator that
+ * the current best, according to the ad_select policy.
+ */
+static struct aggregator *ad_agg_selection_test(struct aggregator *best,
+                                               struct aggregator *curr)
+{
+       /*
+        * 0. If no best, select current.
+        *
+        * 1. If the current agg is not individual, and the best is
+        *    individual, select current.
+        *
+        * 2. If current agg is individual and the best is not, keep best.
+        *
+        * 3. Therefore, current and best are both individual or both not
+        *    individual, so:
+        *
+        * 3a. If current agg partner replied, and best agg partner did not,
+        *     select current.
+        *
+        * 3b. If current agg partner did not reply and best agg partner
+        *     did reply, keep best.
+        *
+        * 4.  Therefore, current and best both have partner replies or
+        *     both do not, so perform selection policy:
+        *
+        * BOND_AD_COUNT: Select by count of ports.  If count is equal,
+        *     select by bandwidth.
+        *
+        * BOND_AD_STABLE, BOND_AD_BANDWIDTH: Select by bandwidth.
+        */
+       if (!best)
+               return curr;
+
+       if (!curr->is_individual && best->is_individual)
+               return curr;
+
+       if (curr->is_individual && !best->is_individual)
+               return best;
+
+       if (__agg_has_partner(curr) && !__agg_has_partner(best))
+               return curr;
+
+       if (!__agg_has_partner(curr) && __agg_has_partner(best))
+               return best;
+
+       switch (__get_agg_selection_mode(curr->lag_ports)) {
+       case BOND_AD_COUNT:
+               if (curr->num_of_ports > best->num_of_ports)
+                       return curr;
+
+               if (curr->num_of_ports < best->num_of_ports)
+                       return best;
+
+               /*FALLTHROUGH*/
+       case BOND_AD_STABLE:
+       case BOND_AD_BANDWIDTH:
+               if (__get_agg_bandwidth(curr) > __get_agg_bandwidth(best))
+                       return curr;
+
+               break;
+
+       default:
+               printk(KERN_WARNING DRV_NAME
+                      ": %s: Impossible agg select mode %d\n",
+                      curr->slave->dev->master->name,
+                      __get_agg_selection_mode(curr->lag_ports));
+               break;
        }
+
+       return best;
 }
 
 /**
@@ -1424,156 +1509,138 @@ static void ad_port_selection_logic(struct port *port)
  * @aggregator: the aggregator we're looking at
  *
  * It is assumed that only one aggregator may be selected for a team.
- * The logic of this function is to select (at first time) the aggregator with
- * the most ports attached to it, and to reselect the active aggregator only if
- * the previous aggregator has no more ports related to it.
+ *
+ * The logic of this function is to select the aggregator according to
+ * the ad_select policy:
+ *
+ * BOND_AD_STABLE: select the aggregator with the most ports attached to
+ * it, and to reselect the active aggregator only if the previous
+ * aggregator has no more ports related to it.
+ *
+ * BOND_AD_BANDWIDTH: select the aggregator with the highest total
+ * bandwidth, and reselect whenever a link state change takes place or the
+ * set of slaves in the bond changes.
+ *
+ * BOND_AD_COUNT: select the aggregator with largest number of ports
+ * (slaves), and reselect whenever a link state change takes place or the
+ * set of slaves in the bond changes.
  *
  * FIXME: this function MUST be called with the first agg in the bond, or
  * __get_active_agg() won't work correctly. This function should be better
  * called with the bond itself, and retrieve the first agg from it.
  */
-static void ad_agg_selection_logic(struct aggregator *aggregator)
+static void ad_agg_selection_logic(struct aggregator *agg)
 {
-       struct aggregator *best_aggregator = NULL, *active_aggregator = NULL;
-       struct aggregator *last_active_aggregator = NULL, *origin_aggregator;
+       struct aggregator *best, *active, *origin;
        struct port *port;
-       u16 num_of_aggs=0;
 
-       origin_aggregator = aggregator;
+       origin = agg;
 
-       //get current active aggregator
-       last_active_aggregator = __get_active_agg(aggregator);
+       active = __get_active_agg(agg);
+       best = active;
 
-       // search for the aggregator with the most ports attached to it.
        do {
-               // count how many candidate lag's we have
-               if (aggregator->lag_ports) {
-                       num_of_aggs++;
-               }
-               if (aggregator->is_active && !aggregator->is_individual &&   // if current aggregator is the active aggregator
-                   MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(null_mac_addr))) {   // and partner answers to 802.3ad PDUs
-                       if (aggregator->num_of_ports) { // if any ports attached to the current aggregator
-                               best_aggregator=NULL;    // disregard the best aggregator that was chosen by now
-                               break;           // stop the selection of other aggregator if there are any ports attached to this active aggregator
-                       } else { // no ports attached to this active aggregator
-                               aggregator->is_active = 0; // mark this aggregator as not active anymore
+               agg->is_active = 0;
+
+               if (agg->num_of_ports)
+                       best = ad_agg_selection_test(best, agg);
+
+       } while ((agg = __get_next_agg(agg)));
+
+       if (best &&
+           __get_agg_selection_mode(best->lag_ports) == BOND_AD_STABLE) {
+               /*
+                * For the STABLE policy, don't replace the old active
+                * aggregator if it's still active (it has an answering
+                * partner) or if both the best and active don't have an
+                * answering partner.
+                */
+               if (active && active->lag_ports &&
+                   active->lag_ports->is_enabled &&
+                   (__agg_has_partner(active) ||
+                    (!__agg_has_partner(active) && !__agg_has_partner(best)))) {
+                       if (!(!active->actor_oper_aggregator_key &&
+                             best->actor_oper_aggregator_key)) {
+                               best = NULL;
+                               active->is_active = 1;
                        }
                }
-               if (aggregator->num_of_ports) { // if any ports attached
-                       if (best_aggregator) {  // if there is a candidte aggregator
-                               //The reasons for choosing new best aggregator:
-                               // 1. if current agg is NOT individual and the best agg chosen so far is individual OR
-                               // current and best aggs are both individual or both not individual, AND
-                               // 2a.  current agg partner reply but best agg partner do not reply OR
-                               // 2b.  current agg partner reply OR current agg partner do not reply AND best agg partner also do not reply AND
-                               //      current has more ports/bandwidth, or same amount of ports but current has faster ports, THEN
-                               //      current agg become best agg so far
-
-                               //if current agg is NOT individual and the best agg chosen so far is individual change best_aggregator
-                               if (!aggregator->is_individual && best_aggregator->is_individual) {
-                                       best_aggregator=aggregator;
-                               }
-                               // current and best aggs are both individual or both not individual
-                               else if ((aggregator->is_individual && best_aggregator->is_individual) ||
-                                        (!aggregator->is_individual && !best_aggregator->is_individual)) {
-                                       //  current and best aggs are both individual or both not individual AND
-                                       //  current agg partner reply but best agg partner do not reply
-                                       if ((MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(null_mac_addr)) &&
-                                            !MAC_ADDRESS_COMPARE(&(best_aggregator->partner_system), &(null_mac_addr)))) {
-                                               best_aggregator=aggregator;
-                                       }
-                                       //  current agg partner reply OR current agg partner do not reply AND best agg partner also do not reply
-                                       else if (! (!MAC_ADDRESS_COMPARE(&(aggregator->partner_system), &(null_mac_addr)) &&
-                                                   MAC_ADDRESS_COMPARE(&(best_aggregator->partner_system), &(null_mac_addr)))) {
-                                               if ((__get_agg_selection_mode(aggregator->lag_ports) == AD_BANDWIDTH)&&
-                                                   (__get_agg_bandwidth(aggregator) > __get_agg_bandwidth(best_aggregator))) {
-                                                       best_aggregator=aggregator;
-                                               } else if (__get_agg_selection_mode(aggregator->lag_ports) == AD_COUNT) {
-                                                       if (((aggregator->num_of_ports > best_aggregator->num_of_ports) &&
-                                                            (aggregator->actor_oper_aggregator_key & AD_SPEED_KEY_BITS))||
-                                                           ((aggregator->num_of_ports == best_aggregator->num_of_ports) &&
-                                                            ((u16)(aggregator->actor_oper_aggregator_key & AD_SPEED_KEY_BITS) >
-                                                             (u16)(best_aggregator->actor_oper_aggregator_key & AD_SPEED_KEY_BITS)))) {
-                                                               best_aggregator=aggregator;
-                                                       }
-                                               }
-                                       }
-                               }
-                       } else {
-                               best_aggregator=aggregator;
-                       }
-               }
-               aggregator->is_active = 0; // mark all aggregators as not active anymore
-       } while ((aggregator = __get_next_agg(aggregator)));
-
-       // if we have new aggregator selected, don't replace the old aggregator if it has an answering partner,
-       // or if both old aggregator and new aggregator don't have answering partner
-       if (best_aggregator) {
-               if (last_active_aggregator && last_active_aggregator->lag_ports && last_active_aggregator->lag_ports->is_enabled &&
-                   (MAC_ADDRESS_COMPARE(&(last_active_aggregator->partner_system), &(null_mac_addr)) ||   // partner answers OR
-                    (!MAC_ADDRESS_COMPARE(&(last_active_aggregator->partner_system), &(null_mac_addr)) &&      // both old and new
-                     !MAC_ADDRESS_COMPARE(&(best_aggregator->partner_system), &(null_mac_addr))))     // partner do not answer
-                  ) {
-                       // if new aggregator has link, and old aggregator does not, replace old aggregator.(do nothing)
-                       // -> don't replace otherwise.
-                       if (!(!last_active_aggregator->actor_oper_aggregator_key && best_aggregator->actor_oper_aggregator_key)) {
-                               best_aggregator=NULL;
-                               last_active_aggregator->is_active = 1; // don't replace good old aggregator
+       }
 
-                       }
-               }
+       if (best && (best == active)) {
+               best = NULL;
+               active->is_active = 1;
        }
 
        // if there is new best aggregator, activate it
-       if (best_aggregator) {
-               for (aggregator = __get_first_agg(best_aggregator->lag_ports);
-                   aggregator;
-                   aggregator = __get_next_agg(aggregator)) {
-
-                       dprintk("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d\n",
-                                       aggregator->aggregator_identifier, aggregator->num_of_ports,
-                                       aggregator->actor_oper_aggregator_key, aggregator->partner_oper_aggregator_key,
-                                       aggregator->is_individual, aggregator->is_active);
+       if (best) {
+               dprintk("best Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
+                      best->aggregator_identifier, best->num_of_ports,
+                      best->actor_oper_aggregator_key,
+                      best->partner_oper_aggregator_key,
+                      best->is_individual, best->is_active);
+               dprintk("best ports %p slave %p %s\n",
+                      best->lag_ports, best->slave,
+                      best->slave ? best->slave->dev->name : "NULL");
+
+               for (agg = __get_first_agg(best->lag_ports); agg;
+                    agg = __get_next_agg(agg)) {
+
+                       dprintk("Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
+                               agg->aggregator_identifier, agg->num_of_ports,
+                               agg->actor_oper_aggregator_key,
+                               agg->partner_oper_aggregator_key,
+                               agg->is_individual, agg->is_active);
                }
 
                // check if any partner replys
-               if (best_aggregator->is_individual) {
-                       printk(KERN_WARNING DRV_NAME ": %s: Warning: No 802.3ad response from "
-                              "the link partner for any adapters in the bond\n",
-                              best_aggregator->slave->dev->master->name);
-               }
-
-               // check if there are more than one aggregator
-               if (num_of_aggs > 1) {
-                       dprintk("Warning: More than one Link Aggregation Group was "
-                               "found in the bond. Only one group will function in the bond\n");
+               if (best->is_individual) {
+                       printk(KERN_WARNING DRV_NAME ": %s: Warning: No 802.3ad"
+                              " response from the link partner for any"
+                              " adapters in the bond\n",
+                              best->slave->dev->master->name);
                }
 
-               best_aggregator->is_active = 1;
-               dprintk("LAG %d choosed as the active LAG\n", best_aggregator->aggregator_identifier);
-               dprintk("Agg=%d; Ports=%d; a key=%d; p key=%d; Indiv=%d; Active=%d\n",
-                               best_aggregator->aggregator_identifier, best_aggregator->num_of_ports,
-                               best_aggregator->actor_oper_aggregator_key, best_aggregator->partner_oper_aggregator_key,
-                               best_aggregator->is_individual, best_aggregator->is_active);
+               best->is_active = 1;
+               dprintk("LAG %d chosen as the active LAG\n",
+                       best->aggregator_identifier);
+               dprintk("Agg=%d; P=%d; a k=%d; p k=%d; Ind=%d; Act=%d\n",
+                       best->aggregator_identifier, best->num_of_ports,
+                       best->actor_oper_aggregator_key,
+                       best->partner_oper_aggregator_key,
+                       best->is_individual, best->is_active);
 
                // disable the ports that were related to the former active_aggregator
-               if (last_active_aggregator) {
-                       for (port=last_active_aggregator->lag_ports; port; port=port->next_port_in_aggregator) {
+               if (active) {
+                       for (port = active->lag_ports; port;
+                            port = port->next_port_in_aggregator) {
                                __disable_port(port);
                        }
                }
        }
 
-       // if the selected aggregator is of join individuals(partner_system is NULL), enable their ports
-       active_aggregator = __get_active_agg(origin_aggregator);
+       /*
+        * if the selected aggregator is of join individuals
+        * (partner_system is NULL), enable their ports
+        */
+       active = __get_active_agg(origin);
 
-       if (active_aggregator) {
-               if (!MAC_ADDRESS_COMPARE(&(active_aggregator->partner_system), &(null_mac_addr))) {
-                       for (port=active_aggregator->lag_ports; port; port=port->next_port_in_aggregator) {
+       if (active) {
+               if (!__agg_has_partner(active)) {
+                       for (port = active->lag_ports; port;
+                            port = port->next_port_in_aggregator) {
                                __enable_port(port);
                        }
                }
        }
+
+       if (origin->slave) {
+               struct bonding *bond;
+
+               bond = bond_get_bond_by_slave(origin->slave);
+               if (bond)
+                       bond_3ad_set_carrier(bond);
+       }
 }
 
 /**
@@ -1830,6 +1897,19 @@ static void ad_initialize_lacpdu(struct lacpdu *lacpdu)
 // Check aggregators status in team every T seconds
 #define AD_AGGREGATOR_SELECTION_TIMER  8
 
+/*
+ * bond_3ad_initiate_agg_selection(struct bonding *bond)
+ *
+ * Set the aggregation selection timer, to initiate an agg selection in
+ * the very near future.  Called during first initialization, and during
+ * any down to up transitions of the bond.
+ */
+void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout)
+{
+       BOND_AD_INFO(bond).agg_select_timer = timeout;
+       BOND_AD_INFO(bond).agg_select_mode = bond->params.ad_select;
+}
+
 static u16 aggregator_identifier;
 
 /**
@@ -1854,9 +1934,9 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fas
                // initialize how many times this module is called in one second(should be about every 100ms)
                ad_ticks_per_sec = tick_resolution;
 
-               // initialize the aggregator selection timer(to activate an aggregation selection after initialize)
-               BOND_AD_INFO(bond).agg_select_timer = (AD_AGGREGATOR_SELECTION_TIMER * ad_ticks_per_sec);
-               BOND_AD_INFO(bond).agg_select_mode = AD_BANDWIDTH;
+               bond_3ad_initiate_agg_selection(bond,
+                                               AD_AGGREGATOR_SELECTION_TIMER *
+                                               ad_ticks_per_sec);
        }
 }
 
@@ -2346,7 +2426,7 @@ int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info)
 int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
 {
        struct slave *slave, *start_at;
-       struct bonding *bond = dev->priv;
+       struct bonding *bond = netdev_priv(dev);
        int slave_agg_no;
        int slaves_in_agg;
        int agg_id;
@@ -2426,7 +2506,7 @@ out:
 
 int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev)
 {
-       struct bonding *bond = dev->priv;
+       struct bonding *bond = netdev_priv(dev);
        struct slave *slave = NULL;
        int ret = NET_RX_DROP;
 
@@ -2437,7 +2517,8 @@ int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct pac
                goto out;
 
        read_lock(&bond->lock);
-       slave = bond_get_slave_by_dev((struct bonding *)dev->priv, orig_dev);
+       slave = bond_get_slave_by_dev((struct bonding *)netdev_priv(dev),
+                                       orig_dev);
        if (!slave)
                goto out_unlock;
 
index b5ee45f6d55a41fec6bd93c890c75415d04e6de3..a803fe05f63ecb4b2db1fc8082e142ee341339fe 100644 (file)
@@ -42,10 +42,11 @@ typedef struct mac_addr {
        u8 mac_addr_value[ETH_ALEN];
 } mac_addr_t;
 
-typedef enum {
-       AD_BANDWIDTH = 0,
-       AD_COUNT
-} agg_selection_t;
+enum {
+       BOND_AD_STABLE = 0,
+       BOND_AD_BANDWIDTH = 1,
+       BOND_AD_COUNT = 2,
+};
 
 // rx machine states(43.4.11 in the 802.3ad standard)
 typedef enum {
@@ -277,6 +278,7 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fas
 int  bond_3ad_bind_slave(struct slave *slave);
 void bond_3ad_unbind_slave(struct slave *slave);
 void bond_3ad_state_machine_handler(struct work_struct *);
+void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout);
 void bond_3ad_adapter_speed_changed(struct slave *slave);
 void bond_3ad_adapter_duplex_changed(struct slave *slave);
 void bond_3ad_handle_link_change(struct slave *slave, char link);
index 87437c788476ab8a05df31a0f7fd1887ffeef497..073d25f357bb63d2e7488564a54f1353bb0bab7a 100644 (file)
@@ -346,14 +346,18 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
 
 static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype, struct net_device *orig_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond;
        struct arp_pkt *arp = (struct arp_pkt *)skb->data;
        int res = NET_RX_DROP;
 
        if (dev_net(bond_dev) != &init_net)
                goto out;
 
-       if (!(bond_dev->flags & IFF_MASTER))
+       while (bond_dev->priv_flags & IFF_802_1Q_VLAN)
+               bond_dev = vlan_dev_real_dev(bond_dev);
+
+       if (!(bond_dev->priv_flags & IFF_BONDING) ||
+           !(bond_dev->flags & IFF_MASTER))
                goto out;
 
        if (!arp) {
@@ -368,6 +372,9 @@ static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct
 
        if (arp->op_code == htons(ARPOP_REPLY)) {
                /* update rx hash table for this ARP */
+               printk("rar: update orig %s bond_dev %s\n", orig_dev->name,
+                      bond_dev->name);
+               bond = netdev_priv(bond_dev);
                rlb_update_entry_from_arp(bond, arp);
                dprintk("Server received an ARP Reply from client\n");
        }
@@ -818,7 +825,7 @@ static int rlb_initialize(struct bonding *bond)
 
        /*initialize packet type*/
        pk_type->type = __constant_htons(ETH_P_ARP);
-       pk_type->dev = bond->dev;
+       pk_type->dev = NULL;
        pk_type->func = rlb_arp_recv;
 
        /* register to receive ARPs */
@@ -1285,7 +1292,7 @@ void bond_alb_deinitialize(struct bonding *bond)
 
 int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct ethhdr *eth_data;
        struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
        struct slave *tx_slave = NULL;
@@ -1706,7 +1713,7 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
  */
 int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct sockaddr *sa = addr;
        struct slave *slave, *swap_slave;
        int res;
diff --git a/drivers/net/bonding/bond_ipv6.c b/drivers/net/bonding/bond_ipv6.c
new file mode 100644 (file)
index 0000000..7c78b7b
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * Copyright(c) 2008 Hewlett-Packard Development Company, L.P.
+ *
+ * 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 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.,
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ */
+
+//#define BONDING_DEBUG 1
+
+#include <linux/types.h>
+#include <linux/if_vlan.h>
+#include <net/ipv6.h>
+#include <net/ndisc.h>
+#include <net/addrconf.h>
+#include "bonding.h"
+
+/*
+ * Assign bond->master_ipv6 to the next IPv6 address in the list, or
+ * zero it out if there are none.
+ */
+static void bond_glean_dev_ipv6(struct net_device *dev, struct in6_addr *addr)
+{
+       struct inet6_dev *idev;
+       struct inet6_ifaddr *ifa;
+
+       if (!dev)
+               return;
+
+       idev = in6_dev_get(dev);
+       if (!idev)
+               return;
+
+       read_lock_bh(&idev->lock);
+       ifa = idev->addr_list;
+       if (ifa)
+               ipv6_addr_copy(addr, &ifa->addr);
+       else
+               ipv6_addr_set(addr, 0, 0, 0, 0);
+
+       read_unlock_bh(&idev->lock);
+
+       in6_dev_put(idev);
+}
+
+static void bond_na_send(struct net_device *slave_dev,
+                        struct in6_addr *daddr,
+                        int router,
+                        unsigned short vlan_id)
+{
+       struct in6_addr mcaddr;
+       struct icmp6hdr icmp6h = {
+               .icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT,
+       };
+       struct sk_buff *skb;
+
+       icmp6h.icmp6_router = router;
+       icmp6h.icmp6_solicited = 0;
+       icmp6h.icmp6_override = 1;
+
+       addrconf_addr_solict_mult(daddr, &mcaddr);
+
+       dprintk("ipv6 na on slave %s: dest %pI6, src %pI6\n",
+              slave->name, &mcaddr, daddr);
+
+       skb = ndisc_build_skb(slave_dev, &mcaddr, daddr, &icmp6h, daddr,
+                             ND_OPT_TARGET_LL_ADDR);
+
+       if (!skb) {
+               printk(KERN_ERR DRV_NAME ": NA packet allocation failed\n");
+               return;
+       }
+
+       if (vlan_id) {
+               skb = vlan_put_tag(skb, vlan_id);
+               if (!skb) {
+                       printk(KERN_ERR DRV_NAME ": failed to insert VLAN tag\n");
+                       return;
+               }
+       }
+
+       ndisc_send_skb(skb, slave_dev, NULL, &mcaddr, daddr, &icmp6h);
+}
+
+/*
+ * Kick out an unsolicited Neighbor Advertisement for an IPv6 address on
+ * the bonding master.  This will help the switch learn our address
+ * if in active-backup mode.
+ *
+ * Caller must hold curr_slave_lock for read or better
+ */
+void bond_send_unsolicited_na(struct bonding *bond)
+{
+       struct slave *slave = bond->curr_active_slave;
+       struct vlan_entry *vlan;
+       struct inet6_dev *idev;
+       int is_router;
+
+       dprintk("bond_send_unsol_na: bond %s slave %s\n", bond->dev->name,
+                               slave ? slave->dev->name : "NULL");
+
+       if (!slave || !bond->send_unsol_na ||
+           test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
+               return;
+
+       bond->send_unsol_na--;
+
+       idev = in6_dev_get(bond->dev);
+       if (!idev)
+               return;
+
+       is_router = !!idev->cnf.forwarding;
+
+       in6_dev_put(idev);
+
+       if (!ipv6_addr_any(&bond->master_ipv6))
+               bond_na_send(slave->dev, &bond->master_ipv6, is_router, 0);
+
+       list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
+               if (!ipv6_addr_any(&vlan->vlan_ipv6)) {
+                       bond_na_send(slave->dev, &vlan->vlan_ipv6, is_router,
+                                    vlan->vlan_id);
+               }
+       }
+}
+
+/*
+ * bond_inet6addr_event: handle inet6addr notifier chain events.
+ *
+ * We keep track of device IPv6 addresses primarily to use as source
+ * addresses in NS probes.
+ *
+ * We track one IPv6 for the main device (if it has one).
+ */
+static int bond_inet6addr_event(struct notifier_block *this,
+                               unsigned long event,
+                               void *ptr)
+{
+       struct inet6_ifaddr *ifa = ptr;
+       struct net_device *vlan_dev, *event_dev = ifa->idev->dev;
+       struct bonding *bond;
+       struct vlan_entry *vlan;
+
+       if (dev_net(event_dev) != &init_net)
+               return NOTIFY_DONE;
+
+       list_for_each_entry(bond, &bond_dev_list, bond_list) {
+               if (bond->dev == event_dev) {
+                       switch (event) {
+                       case NETDEV_UP:
+                               if (ipv6_addr_any(&bond->master_ipv6))
+                                       ipv6_addr_copy(&bond->master_ipv6,
+                                                      &ifa->addr);
+                               return NOTIFY_OK;
+                       case NETDEV_DOWN:
+                               if (ipv6_addr_equal(&bond->master_ipv6,
+                                                   &ifa->addr))
+                                       bond_glean_dev_ipv6(bond->dev,
+                                                           &bond->master_ipv6);
+                               return NOTIFY_OK;
+                       default:
+                               return NOTIFY_DONE;
+                       }
+               }
+
+               list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
+                       vlan_dev = vlan_group_get_device(bond->vlgrp,
+                                                        vlan->vlan_id);
+                       if (vlan_dev == event_dev) {
+                               switch (event) {
+                               case NETDEV_UP:
+                                       if (ipv6_addr_any(&vlan->vlan_ipv6))
+                                               ipv6_addr_copy(&vlan->vlan_ipv6,
+                                                              &ifa->addr);
+                                       return NOTIFY_OK;
+                               case NETDEV_DOWN:
+                                       if (ipv6_addr_equal(&vlan->vlan_ipv6,
+                                                           &ifa->addr))
+                                               bond_glean_dev_ipv6(vlan_dev,
+                                                                   &vlan->vlan_ipv6);
+                                       return NOTIFY_OK;
+                               default:
+                                       return NOTIFY_DONE;
+                               }
+                       }
+               }
+       }
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block bond_inet6addr_notifier = {
+       .notifier_call = bond_inet6addr_event,
+};
+
+void bond_register_ipv6_notifier(void)
+{
+       register_inet6addr_notifier(&bond_inet6addr_notifier);
+}
+
+void bond_unregister_ipv6_notifier(void)
+{
+       unregister_inet6addr_notifier(&bond_inet6addr_notifier);
+}
+
index a3efba59eee98daa96aeae7dd1278865a31c6db6..a08ea4808056bbb25a12f44b5ccbd27014411aa6 100644 (file)
@@ -89,6 +89,7 @@
 
 static int max_bonds   = BOND_DEFAULT_MAX_BONDS;
 static int num_grat_arp = 1;
+static int num_unsol_na = 1;
 static int miimon      = BOND_LINK_MON_INTERV;
 static int updelay     = 0;
 static int downdelay   = 0;
@@ -96,6 +97,7 @@ static int use_carrier        = 1;
 static char *mode      = NULL;
 static char *primary   = NULL;
 static char *lacp_rate = NULL;
+static char *ad_select  = NULL;
 static char *xmit_hash_policy = NULL;
 static int arp_interval = BOND_LINK_ARP_INTERV;
 static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
@@ -107,6 +109,8 @@ module_param(max_bonds, int, 0);
 MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
 module_param(num_grat_arp, int, 0644);
 MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event");
+module_param(num_unsol_na, int, 0644);
+MODULE_PARM_DESC(num_unsol_na, "Number of unsolicited IPv6 Neighbor Advertisements packets to send on failover event");
 module_param(miimon, int, 0);
 MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
 module_param(updelay, int, 0);
@@ -127,6 +131,8 @@ MODULE_PARM_DESC(primary, "Primary network device to use");
 module_param(lacp_rate, charp, 0);
 MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner "
                            "(slow/fast)");
+module_param(ad_select, charp, 0);
+MODULE_PARM_DESC(ad_select, "803.ad aggregation selection logic: stable (0, default), bandwidth (1), count (2)");
 module_param(xmit_hash_policy, charp, 0);
 MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method: 0 for layer 2 (default)"
                                   ", 1 for layer 3+4");
@@ -197,6 +203,13 @@ struct bond_parm_tbl fail_over_mac_tbl[] = {
 {      NULL,                   -1},
 };
 
+struct bond_parm_tbl ad_select_tbl[] = {
+{      "stable",       BOND_AD_STABLE},
+{      "bandwidth",    BOND_AD_BANDWIDTH},
+{      "count",        BOND_AD_COUNT},
+{      NULL,           -1},
+};
+
 /*-------------------------- Forward declarations ---------------------------*/
 
 static void bond_send_gratuitous_arp(struct bonding *bond);
@@ -242,14 +255,13 @@ static int bond_add_vlan(struct bonding *bond, unsigned short vlan_id)
        dprintk("bond: %s, vlan id %d\n",
                (bond ? bond->dev->name: "None"), vlan_id);
 
-       vlan = kmalloc(sizeof(struct vlan_entry), GFP_KERNEL);
+       vlan = kzalloc(sizeof(struct vlan_entry), GFP_KERNEL);
        if (!vlan) {
                return -ENOMEM;
        }
 
        INIT_LIST_HEAD(&vlan->vlan_list);
        vlan->vlan_id = vlan_id;
-       vlan->vlan_ip = 0;
 
        write_lock_bh(&bond->lock);
 
@@ -442,7 +454,7 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_de
  */
 static void bond_vlan_rx_register(struct net_device *bond_dev, struct vlan_group *grp)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave;
        int i;
 
@@ -465,7 +477,7 @@ static void bond_vlan_rx_register(struct net_device *bond_dev, struct vlan_group
  */
 static void bond_vlan_rx_add_vid(struct net_device *bond_dev, uint16_t vid)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave;
        int i, res;
 
@@ -493,7 +505,7 @@ static void bond_vlan_rx_add_vid(struct net_device *bond_dev, uint16_t vid)
  */
 static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave;
        struct net_device *vlan_dev;
        int i, res;
@@ -927,7 +939,7 @@ static int bond_mc_list_copy(struct dev_mc_list *mc_list, struct bonding *bond,
  */
 static void bond_mc_list_flush(struct net_device *bond_dev, struct net_device *slave_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct dev_mc_list *dmi;
 
        for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
@@ -1208,6 +1220,9 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
                        bond->send_grat_arp = bond->params.num_grat_arp;
                        bond_send_gratuitous_arp(bond);
 
+                       bond->send_unsol_na = bond->params.num_unsol_na;
+                       bond_send_unsolicited_na(bond);
+
                        write_unlock_bh(&bond->curr_slave_lock);
                        read_unlock(&bond->lock);
 
@@ -1368,7 +1383,7 @@ done:
 static void bond_setup_by_slave(struct net_device *bond_dev,
                                struct net_device *slave_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
 
        bond_dev->neigh_setup           = slave_dev->neigh_setup;
        bond_dev->header_ops            = slave_dev->header_ops;
@@ -1385,7 +1400,7 @@ static void bond_setup_by_slave(struct net_device *bond_dev,
 /* enslave device <slave> to bond device <master> */
 int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct slave *new_slave = NULL;
        struct dev_mc_list *dmi;
        struct sockaddr addr;
@@ -1787,11 +1802,10 @@ err_undo_flags:
  */
 int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave, *oldcurrent;
        struct sockaddr addr;
        int mac_addr_differ;
-       DECLARE_MAC_BUF(mac);
 
        /* slave is not a slave or master is not master of this slave */
        if (!(slave_dev->flags & IFF_SLAVE) ||
@@ -1820,11 +1834,11 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
                if (!mac_addr_differ && (bond->slave_cnt > 1))
                        printk(KERN_WARNING DRV_NAME
                               ": %s: Warning: the permanent HWaddr of %s - "
-                              "%s - is still in use by %s. "
+                              "%pM - is still in use by %s. "
                               "Set the HWaddr of %s to a different address "
                               "to avoid conflicts.\n",
                               bond_dev->name, slave_dev->name,
-                              print_mac(mac, slave->perm_hwaddr),
+                              slave->perm_hwaddr,
                               bond_dev->name, slave_dev->name);
        }
 
@@ -1999,7 +2013,7 @@ static void bond_destructor(struct net_device *bond_dev)
 */
 int  bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        int ret;
 
        ret = bond_release(bond_dev, slave_dev);
@@ -2016,7 +2030,7 @@ int  bond_release_and_destroy(struct net_device *bond_dev, struct net_device *sl
  */
 static int bond_release_all(struct net_device *bond_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave;
        struct net_device *slave_dev;
        struct sockaddr addr;
@@ -2147,7 +2161,7 @@ out:
  */
 static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_device *slave_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct slave *old_active = NULL;
        struct slave *new_active = NULL;
        int res = 0;
@@ -2196,7 +2210,7 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
 
 static int bond_info_query(struct net_device *bond_dev, struct ifbond *info)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
 
        info->bond_mode = bond->params.mode;
        info->miimon = bond->params.miimon;
@@ -2210,7 +2224,7 @@ static int bond_info_query(struct net_device *bond_dev, struct ifbond *info)
 
 static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *info)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave;
        int i, found = 0;
 
@@ -2464,6 +2478,12 @@ void bond_mii_monitor(struct work_struct *work)
                read_unlock(&bond->curr_slave_lock);
        }
 
+       if (bond->send_unsol_na) {
+               read_lock(&bond->curr_slave_lock);
+               bond_send_unsolicited_na(bond);
+               read_unlock(&bond->curr_slave_lock);
+       }
+
        if (bond_miimon_inspect(bond)) {
                read_unlock(&bond->lock);
                rtnl_lock();
@@ -2586,8 +2606,8 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
                if (rv) {
                        if (net_ratelimit()) {
                                printk(KERN_WARNING DRV_NAME
-                            ": %s: no route to arp_ip_target %u.%u.%u.%u\n",
-                                      bond->dev->name, NIPQUAD(fl.fl4_dst));
+                            ": %s: no route to arp_ip_target %pI4\n",
+                                      bond->dev->name, &fl.fl4_dst);
                        }
                        continue;
                }
@@ -2623,8 +2643,8 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
 
                if (net_ratelimit()) {
                        printk(KERN_WARNING DRV_NAME
-              ": %s: no path to arp_ip_target %u.%u.%u.%u via rt.dev %s\n",
-                              bond->dev->name, NIPQUAD(fl.fl4_dst),
+              ": %s: no path to arp_ip_target %pI4 via rt.dev %s\n",
+                              bond->dev->name, &fl.fl4_dst,
                               rt->u.dst.dev ? rt->u.dst.dev->name : "NULL");
                }
                ip_rt_put(rt);
@@ -2673,10 +2693,8 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32
 
        targets = bond->params.arp_targets;
        for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) {
-               dprintk("bva: sip %u.%u.%u.%u tip %u.%u.%u.%u t[%d] "
-                       "%u.%u.%u.%u bhti(tip) %d\n",
-                      NIPQUAD(sip), NIPQUAD(tip), i, NIPQUAD(targets[i]),
-                      bond_has_this_ip(bond, tip));
+               dprintk("bva: sip %pI4 tip %pI4 t[%d] %pI4 bhti(tip) %d\n",
+                       &sip, &tip, i, &targets[i], bond_has_this_ip(bond, tip));
                if (sip == targets[i]) {
                        if (bond_has_this_ip(bond, tip))
                                slave->last_arp_rx = jiffies;
@@ -2699,7 +2717,7 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack
        if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER))
                goto out;
 
-       bond = dev->priv;
+       bond = netdev_priv(dev);
        read_lock(&bond->lock);
 
        dprintk("bond_arp_rcv: bond %s skb->dev %s orig_dev %s\n",
@@ -2728,10 +2746,10 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack
        arp_ptr += 4 + dev->addr_len;
        memcpy(&tip, arp_ptr, 4);
 
-       dprintk("bond_arp_rcv: %s %s/%d av %d sv %d sip %u.%u.%u.%u"
-               " tip %u.%u.%u.%u\n", bond->dev->name, slave->dev->name,
-               slave->state, bond->params.arp_validate,
-               slave_do_arp_validate(bond, slave), NIPQUAD(sip), NIPQUAD(tip));
+       dprintk("bond_arp_rcv: %s %s/%d av %d sv %d sip %pI4 tip %pI4\n",
+               bond->dev->name, slave->dev->name, slave->state,
+               bond->params.arp_validate, slave_do_arp_validate(bond, slave),
+               &sip, &tip);
 
        /*
         * Backup slaves won't see the ARP reply, but do come through
@@ -3161,6 +3179,12 @@ void bond_activebackup_arp_mon(struct work_struct *work)
                read_unlock(&bond->curr_slave_lock);
        }
 
+       if (bond->send_unsol_na) {
+               read_lock(&bond->curr_slave_lock);
+               bond_send_unsolicited_na(bond);
+               read_unlock(&bond->curr_slave_lock);
+       }
+
        if (bond_ab_arp_inspect(bond, delta_in_ticks)) {
                read_unlock(&bond->lock);
                rtnl_lock();
@@ -3239,7 +3263,6 @@ static void bond_info_show_master(struct seq_file *seq)
        struct bonding *bond = seq->private;
        struct slave *curr;
        int i;
-       u32 target;
 
        read_lock(&bond->curr_slave_lock);
        curr = bond->curr_active_slave;
@@ -3293,8 +3316,7 @@ static void bond_info_show_master(struct seq_file *seq)
                                continue;
                        if (printed)
                                seq_printf(seq, ",");
-                       target = ntohl(bond->params.arp_targets[i]);
-                       seq_printf(seq, " %d.%d.%d.%d", HIPQUAD(target));
+                       seq_printf(seq, " %pI4", &bond->params.arp_targets[i]);
                        printed = 1;
                }
                seq_printf(seq, "\n");
@@ -3302,11 +3324,12 @@ static void bond_info_show_master(struct seq_file *seq)
 
        if (bond->params.mode == BOND_MODE_8023AD) {
                struct ad_info ad_info;
-               DECLARE_MAC_BUF(mac);
 
                seq_puts(seq, "\n802.3ad info\n");
                seq_printf(seq, "LACP rate: %s\n",
                           (bond->params.lacp_fast) ? "fast" : "slow");
+               seq_printf(seq, "Aggregator selection policy (ad_select): %s\n",
+                          ad_select_tbl[bond->params.ad_select].modename);
 
                if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
                        seq_printf(seq, "bond %s has no active aggregator\n",
@@ -3322,8 +3345,8 @@ static void bond_info_show_master(struct seq_file *seq)
                                   ad_info.actor_key);
                        seq_printf(seq, "\tPartner Key: %d\n",
                                   ad_info.partner_key);
-                       seq_printf(seq, "\tPartner Mac Address: %s\n",
-                                  print_mac(mac, ad_info.partner_system));
+                       seq_printf(seq, "\tPartner Mac Address: %pM\n",
+                                  ad_info.partner_system);
                }
        }
 }
@@ -3331,7 +3354,6 @@ static void bond_info_show_master(struct seq_file *seq)
 static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave)
 {
        struct bonding *bond = seq->private;
-       DECLARE_MAC_BUF(mac);
 
        seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
        seq_printf(seq, "MII Status: %s\n",
@@ -3339,9 +3361,7 @@ static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave
        seq_printf(seq, "Link Failure Count: %u\n",
                   slave->link_failure_count);
 
-       seq_printf(seq,
-                  "Permanent HW addr: %s\n",
-                  print_mac(mac, slave->perm_hwaddr));
+       seq_printf(seq, "Permanent HW addr: %pM\n", slave->perm_hwaddr);
 
        if (bond->params.mode == BOND_MODE_8023AD) {
                const struct aggregator *agg
@@ -3506,7 +3526,7 @@ static int bond_event_changename(struct bonding *bond)
 
 static int bond_master_netdev_event(unsigned long event, struct net_device *bond_dev)
 {
-       struct bonding *event_bond = bond_dev->priv;
+       struct bonding *event_bond = netdev_priv(bond_dev);
 
        switch (event) {
        case NETDEV_CHANGENAME:
@@ -3524,7 +3544,7 @@ static int bond_master_netdev_event(unsigned long event, struct net_device *bond
 static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev)
 {
        struct net_device *bond_dev = slave_dev->master;
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
 
        switch (event) {
        case NETDEV_UNREGISTER:
@@ -3775,7 +3795,7 @@ static int bond_xmit_hash_policy_l2(struct sk_buff *skb,
 
 static int bond_open(struct net_device *bond_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
 
        bond->kill_timers = 0;
 
@@ -3816,6 +3836,7 @@ static int bond_open(struct net_device *bond_dev)
                queue_delayed_work(bond->wq, &bond->ad_work, 0);
                /* register to receive LACPDUs */
                bond_register_lacpdu(bond);
+               bond_3ad_initiate_agg_selection(bond, 1);
        }
 
        return 0;
@@ -3823,7 +3844,7 @@ static int bond_open(struct net_device *bond_dev)
 
 static int bond_close(struct net_device *bond_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
 
        if (bond->params.mode == BOND_MODE_8023AD) {
                /* Unregister the receive of LACPDUs */
@@ -3836,6 +3857,7 @@ static int bond_close(struct net_device *bond_dev)
        write_lock_bh(&bond->lock);
 
        bond->send_grat_arp = 0;
+       bond->send_unsol_na = 0;
 
        /* signal timers not to re-arm */
        bond->kill_timers = 1;
@@ -3876,7 +3898,7 @@ static int bond_close(struct net_device *bond_dev)
 
 static struct net_device_stats *bond_get_stats(struct net_device *bond_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct net_device_stats *stats = &(bond->stats), *sstats;
        struct net_device_stats local_stats;
        struct slave *slave;
@@ -3954,7 +3976,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
                }
 
                if (mii->reg_num == 1) {
-                       struct bonding *bond = bond_dev->priv;
+                       struct bonding *bond = netdev_priv(bond_dev);
                        mii->val_out = 0;
                        read_lock(&bond->lock);
                        read_lock(&bond->curr_slave_lock);
@@ -4046,7 +4068,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
 
 static void bond_set_multicast_list(struct net_device *bond_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct dev_mc_list *dmi;
 
        /*
@@ -4107,7 +4129,7 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
  */
 static int bond_change_mtu(struct net_device *bond_dev, int new_mtu)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave, *stop_at;
        int res = 0;
        int i;
@@ -4179,7 +4201,7 @@ unwind:
  */
 static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct sockaddr *sa = addr, tmp_sa;
        struct slave *slave, *stop_at;
        int res = 0;
@@ -4260,7 +4282,7 @@ unwind:
 
 static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave, *start_at;
        int i, slave_no, res = 1;
 
@@ -4309,7 +4331,7 @@ out:
  */
 static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        int res = 1;
 
        read_lock(&bond->lock);
@@ -4341,7 +4363,7 @@ out:
  */
 static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave, *start_at;
        int slave_no;
        int i;
@@ -4387,7 +4409,7 @@ out:
  */
 static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave, *start_at;
        struct net_device *tx_dev = NULL;
        int i;
@@ -4530,7 +4552,7 @@ static const struct ethtool_ops bond_ethtool_ops = {
  */
 static int bond_init(struct net_device *bond_dev, struct bond_params *params)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
 
        dprintk("Begin bond_init for %s\n", bond_dev->name);
 
@@ -4551,6 +4573,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
        bond->primary_slave = NULL;
        bond->dev = bond_dev;
        bond->send_grat_arp = 0;
+       bond->send_unsol_na = 0;
        bond->setup_by_slave = 0;
        INIT_LIST_HEAD(&bond->vlan_list);
 
@@ -4573,6 +4596,8 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
        bond_dev->tx_queue_len = 0;
        bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
        bond_dev->priv_flags |= IFF_BONDING;
+       if (bond->params.arp_interval)
+               bond_dev->priv_flags |= IFF_MASTER_ARPMON;
 
        /* At first, we block adding VLANs. That's the only way to
         * prevent problems that occur when adding VLANs over an
@@ -4632,7 +4657,7 @@ static void bond_work_cancel_all(struct bonding *bond)
  */
 static void bond_deinit(struct net_device *bond_dev)
 {
-       struct bonding *bond = bond_dev->priv;
+       struct bonding *bond = netdev_priv(bond_dev);
 
        list_del(&bond->bond_list);
 
@@ -4751,6 +4776,23 @@ static int bond_check_params(struct bond_params *params)
                }
        }
 
+       if (ad_select) {
+               params->ad_select = bond_parse_parm(ad_select, ad_select_tbl);
+               if (params->ad_select == -1) {
+                       printk(KERN_ERR DRV_NAME
+                              ": Error: Invalid ad_select \"%s\"\n",
+                              ad_select == NULL ? "NULL" : ad_select);
+                       return -EINVAL;
+               }
+
+               if (bond_mode != BOND_MODE_8023AD) {
+                       printk(KERN_WARNING DRV_NAME
+                              ": ad_select param only affects 802.3ad mode\n");
+               }
+       } else {
+               params->ad_select = BOND_AD_STABLE;
+       }
+
        if (max_bonds < 0 || max_bonds > INT_MAX) {
                printk(KERN_WARNING DRV_NAME
                       ": Warning: max_bonds (%d) not in range %d-%d, so it "
@@ -4798,6 +4840,13 @@ static int bond_check_params(struct bond_params *params)
                num_grat_arp = 1;
        }
 
+       if (num_unsol_na < 0 || num_unsol_na > 255) {
+               printk(KERN_WARNING DRV_NAME
+                      ": Warning: num_unsol_na (%d) not in range 0-255 so it "
+                      "was reset to 1 \n", num_unsol_na);
+               num_unsol_na = 1;
+       }
+
        /* reset values for 802.3ad */
        if (bond_mode == BOND_MODE_8023AD) {
                if (!miimon) {
@@ -4999,6 +5048,7 @@ static int bond_check_params(struct bond_params *params)
        params->xmit_policy = xmit_hashtype;
        params->miimon = miimon;
        params->num_grat_arp = num_grat_arp;
+       params->num_unsol_na = num_unsol_na;
        params->arp_interval = arp_interval;
        params->arp_validate = arp_validate_value;
        params->updelay = updelay;
@@ -5099,7 +5149,7 @@ int bond_create(char *name, struct bond_params *params)
 
        up_write(&bonding_rwsem);
        rtnl_unlock(); /* allows sysfs registration of net device */
-       res = bond_create_sysfs_entry(bond_dev->priv);
+       res = bond_create_sysfs_entry(netdev_priv(bond_dev));
        if (res < 0) {
                rtnl_lock();
                down_write(&bonding_rwsem);
@@ -5151,6 +5201,7 @@ static int __init bonding_init(void)
 
        register_netdevice_notifier(&bond_netdev_notifier);
        register_inetaddr_notifier(&bond_inetaddr_notifier);
+       bond_register_ipv6_notifier();
 
        goto out;
 err:
@@ -5173,6 +5224,7 @@ static void __exit bonding_exit(void)
 {
        unregister_netdevice_notifier(&bond_netdev_notifier);
        unregister_inetaddr_notifier(&bond_inetaddr_notifier);
+       bond_unregister_ipv6_notifier();
 
        bond_destroy_sysfs();
 
index 3bdb47382521149010c7e478039fd190cb6b3868..fc490d89d4afc87e06b52bc2a0b082f717ec4148 100644 (file)
@@ -39,7 +39,7 @@
 /* #define BONDING_DEBUG 1 */
 #include "bonding.h"
 #define to_dev(obj)    container_of(obj,struct device,kobj)
-#define to_bond(cd)    ((struct bonding *)(to_net_dev(cd)->priv))
+#define to_bond(cd)    ((struct bonding *)(netdev_priv(to_net_dev(cd))))
 
 /*---------------------------- Declarations -------------------------------*/
 
@@ -48,6 +48,7 @@ extern struct list_head bond_dev_list;
 extern struct bond_params bonding_defaults;
 extern struct bond_parm_tbl bond_mode_tbl[];
 extern struct bond_parm_tbl bond_lacp_tbl[];
+extern struct bond_parm_tbl ad_select_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[];
@@ -620,6 +621,8 @@ static ssize_t bonding_store_arp_interval(struct device *d,
               ": %s: Setting ARP monitoring interval to %d.\n",
               bond->dev->name, new_value);
        bond->params.arp_interval = new_value;
+       if (bond->params.arp_interval)
+               bond->dev->priv_flags |= IFF_MASTER_ARPMON;
        if (bond->params.miimon) {
                printk(KERN_INFO DRV_NAME
                       ": %s: ARP monitoring cannot be used with MII monitoring. "
@@ -672,8 +675,8 @@ static ssize_t bonding_show_arp_targets(struct device *d,
 
        for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
                if (bond->params.arp_targets[i])
-                       res += sprintf(buf + res, "%u.%u.%u.%u ",
-                              NIPQUAD(bond->params.arp_targets[i]));
+                       res += sprintf(buf + res, "%pI4 ",
+                                      &bond->params.arp_targets[i]);
        }
        if (res)
                buf[res-1] = '\n'; /* eat the leftover space */
@@ -695,8 +698,8 @@ static ssize_t bonding_store_arp_targets(struct device *d,
        if (buf[0] == '+') {
                if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
                        printk(KERN_ERR DRV_NAME
-                              ": %s: invalid ARP target %u.%u.%u.%u specified for addition\n",
-                              bond->dev->name, NIPQUAD(newtarget));
+                              ": %s: invalid ARP target %pI4 specified for addition\n",
+                              bond->dev->name, &newtarget);
                        ret = -EINVAL;
                        goto out;
                }
@@ -704,8 +707,8 @@ static ssize_t bonding_store_arp_targets(struct device *d,
                for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
                        if (targets[i] == newtarget) { /* duplicate */
                                printk(KERN_ERR DRV_NAME
-                                      ": %s: ARP target %u.%u.%u.%u is already present\n",
-                                      bond->dev->name, NIPQUAD(newtarget));
+                                      ": %s: ARP target %pI4 is already present\n",
+                                      bond->dev->name, &newtarget);
                                if (done)
                                        targets[i] = 0;
                                ret = -EINVAL;
@@ -713,8 +716,8 @@ static ssize_t bonding_store_arp_targets(struct device *d,
                        }
                        if (targets[i] == 0 && !done) {
                                printk(KERN_INFO DRV_NAME
-                                      ": %s: adding ARP target %d.%d.%d.%d.\n",
-                                      bond->dev->name, NIPQUAD(newtarget));
+                                      ": %s: adding ARP target %pI4.\n",
+                                      bond->dev->name, &newtarget);
                                done = 1;
                                targets[i] = newtarget;
                        }
@@ -731,8 +734,8 @@ static ssize_t bonding_store_arp_targets(struct device *d,
        else if (buf[0] == '-') {
                if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
                        printk(KERN_ERR DRV_NAME
-                              ": %s: invalid ARP target %d.%d.%d.%d specified for removal\n",
-                              bond->dev->name, NIPQUAD(newtarget));
+                              ": %s: invalid ARP target %pI4 specified for removal\n",
+                              bond->dev->name, &newtarget);
                        ret = -EINVAL;
                        goto out;
                }
@@ -740,16 +743,16 @@ static ssize_t bonding_store_arp_targets(struct device *d,
                for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
                        if (targets[i] == newtarget) {
                                printk(KERN_INFO DRV_NAME
-                                      ": %s: removing ARP target %d.%d.%d.%d.\n",
-                                      bond->dev->name, NIPQUAD(newtarget));
+                                      ": %s: removing ARP target %pI4.\n",
+                                      bond->dev->name, &newtarget);
                                targets[i] = 0;
                                done = 1;
                        }
                }
                if (!done) {
                        printk(KERN_INFO DRV_NAME
-                              ": %s: unable to remove nonexistent ARP target %d.%d.%d.%d.\n",
-                              bond->dev->name, NIPQUAD(newtarget));
+                              ": %s: unable to remove nonexistent ARP target %pI4.\n",
+                              bond->dev->name, &newtarget);
                        ret = -EINVAL;
                        goto out;
                }
@@ -942,6 +945,53 @@ out:
 }
 static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp);
 
+static ssize_t bonding_show_ad_select(struct device *d,
+                                     struct device_attribute *attr,
+                                     char *buf)
+{
+       struct bonding *bond = to_bond(d);
+
+       return sprintf(buf, "%s %d\n",
+               ad_select_tbl[bond->params.ad_select].modename,
+               bond->params.ad_select);
+}
+
+
+static ssize_t bonding_store_ad_select(struct device *d,
+                                      struct device_attribute *attr,
+                                      const char *buf, size_t count)
+{
+       int new_value, ret = count;
+       struct bonding *bond = to_bond(d);
+
+       if (bond->dev->flags & IFF_UP) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Unable to update ad_select because interface "
+                      "is up.\n", bond->dev->name);
+               ret = -EPERM;
+               goto out;
+       }
+
+       new_value = bond_parse_parm(buf, ad_select_tbl);
+
+       if (new_value != -1) {
+               bond->params.ad_select = new_value;
+               printk(KERN_INFO DRV_NAME
+                      ": %s: Setting ad_select to %s (%d).\n",
+                      bond->dev->name, ad_select_tbl[new_value].modename,
+                      new_value);
+       } else {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Ignoring invalid ad_select value %.*s.\n",
+                      bond->dev->name, (int)strlen(buf) - 1, buf);
+               ret = -EINVAL;
+       }
+out:
+       return ret;
+}
+
+static DEVICE_ATTR(ad_select, S_IRUGO | S_IWUSR, bonding_show_ad_select, bonding_store_ad_select);
+
 /*
  * Show and set the number of grat ARP to send after a failover event.
  */
@@ -981,6 +1031,47 @@ out:
        return ret;
 }
 static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR, bonding_show_n_grat_arp, bonding_store_n_grat_arp);
+
+/*
+ * Show and set the number of unsolicted NA's to send after a failover event.
+ */
+static ssize_t bonding_show_n_unsol_na(struct device *d,
+                                      struct device_attribute *attr,
+                                      char *buf)
+{
+       struct bonding *bond = to_bond(d);
+
+       return sprintf(buf, "%d\n", bond->params.num_unsol_na);
+}
+
+static ssize_t bonding_store_n_unsol_na(struct device *d,
+                                       struct device_attribute *attr,
+                                       const char *buf, size_t count)
+{
+       int new_value, ret = count;
+       struct bonding *bond = to_bond(d);
+
+       if (sscanf(buf, "%d", &new_value) != 1) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: no num_unsol_na value specified.\n",
+                      bond->dev->name);
+               ret = -EINVAL;
+               goto out;
+       }
+       if (new_value < 0 || new_value > 255) {
+               printk(KERN_ERR DRV_NAME
+                      ": %s: Invalid num_unsol_na value %d not in range 0-255; rejected.\n",
+                      bond->dev->name, new_value);
+               ret = -EINVAL;
+               goto out;
+       } else {
+               bond->params.num_unsol_na = new_value;
+       }
+out:
+       return ret;
+}
+static DEVICE_ATTR(num_unsol_na, S_IRUGO | S_IWUSR, bonding_show_n_unsol_na, bonding_store_n_unsol_na);
+
 /*
  * Show and set the MII monitor interval.  There are two tricky bits
  * here.  First, if MII monitoring is activated, then we must disable
@@ -1039,6 +1130,7 @@ static ssize_t bonding_store_miimon(struct device *d,
                               "ARP monitoring. Disabling ARP monitoring...\n",
                               bond->dev->name);
                        bond->params.arp_interval = 0;
+                       bond->dev->priv_flags &= ~IFF_MASTER_ARPMON;
                        if (bond->params.arp_validate) {
                                bond_unregister_arp(bond);
                                bond->params.arp_validate =
@@ -1391,13 +1483,11 @@ static ssize_t bonding_show_ad_partner_mac(struct device *d,
 {
        int count = 0;
        struct bonding *bond = to_bond(d);
-       DECLARE_MAC_BUF(mac);
 
        if (bond->params.mode == BOND_MODE_8023AD) {
                struct ad_info ad_info;
                if (!bond_3ad_get_active_agg_info(bond, &ad_info)) {
-                       count = sprintf(buf,"%s\n",
-                                       print_mac(mac, ad_info.partner_system));
+                       count = sprintf(buf, "%pM\n", ad_info.partner_system);
                }
        }
 
@@ -1417,8 +1507,10 @@ static struct attribute *per_bond_attrs[] = {
        &dev_attr_downdelay.attr,
        &dev_attr_updelay.attr,
        &dev_attr_lacp_rate.attr,
+       &dev_attr_ad_select.attr,
        &dev_attr_xmit_hash_policy.attr,
        &dev_attr_num_grat_arp.attr,
+       &dev_attr_num_unsol_na.attr,
        &dev_attr_miimon.attr,
        &dev_attr_primary.attr,
        &dev_attr_use_carrier.attr,
index ffb668dd6d3b00eddbc328513b785e42c31d492d..921abacc6074ef7c62f0132ad183b58a997595d3 100644 (file)
 #include <linux/proc_fs.h>
 #include <linux/if_bonding.h>
 #include <linux/kobject.h>
+#include <linux/in6.h>
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
-#define DRV_VERSION    "3.3.0"
-#define DRV_RELDATE    "June 10, 2008"
+#define DRV_VERSION    "3.5.0"
+#define DRV_RELDATE    "November 4, 2008"
 #define DRV_NAME       "bonding"
 #define DRV_DESCRIPTION        "Ethernet Channel Bonding Driver"
 
 #define BOND_MAX_ARP_TARGETS   16
 
+extern struct list_head bond_dev_list;
+
 #ifdef BONDING_DEBUG
 #define dprintk(fmt, args...) \
        printk(KERN_DEBUG     \
@@ -126,6 +129,7 @@ struct bond_params {
        int xmit_policy;
        int miimon;
        int num_grat_arp;
+       int num_unsol_na;
        int arp_interval;
        int arp_validate;
        int use_carrier;
@@ -133,6 +137,7 @@ struct bond_params {
        int updelay;
        int downdelay;
        int lacp_fast;
+       int ad_select;
        char primary[IFNAMSIZ];
        __be32 arp_targets[BOND_MAX_ARP_TARGETS];
 };
@@ -148,6 +153,9 @@ struct vlan_entry {
        struct list_head vlan_list;
        __be32 vlan_ip;
        unsigned short vlan_id;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+       struct in6_addr vlan_ipv6;
+#endif
 };
 
 struct slave {
@@ -195,6 +203,7 @@ struct bonding {
        rwlock_t curr_slave_lock;
        s8       kill_timers;
        s8       send_grat_arp;
+       s8       send_unsol_na;
        s8       setup_by_slave;
        struct   net_device_stats stats;
 #ifdef CONFIG_PROC_FS
@@ -218,6 +227,9 @@ struct bonding {
        struct   delayed_work arp_work;
        struct   delayed_work alb_work;
        struct   delayed_work ad_work;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+       struct   in6_addr master_ipv6;
+#endif
 };
 
 /**
@@ -245,7 +257,7 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
                return NULL;
        }
 
-       return (struct bonding *)slave->dev->master->priv;
+       return (struct bonding *)netdev_priv(slave->dev->master);
 }
 
 #define BOND_FOM_NONE                  0
@@ -275,7 +287,7 @@ static inline unsigned long slave_last_rx(struct bonding *bond,
 
 static inline void bond_set_slave_inactive_flags(struct slave *slave)
 {
-       struct bonding *bond = slave->dev->master->priv;
+       struct bonding *bond = netdev_priv(slave->dev->master);
        if (bond->params.mode != BOND_MODE_TLB &&
            bond->params.mode != BOND_MODE_ALB)
                slave->state = BOND_STATE_BACKUP;
@@ -341,5 +353,24 @@ 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[];
 
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+void bond_send_unsolicited_na(struct bonding *bond);
+void bond_register_ipv6_notifier(void);
+void bond_unregister_ipv6_notifier(void);
+#else
+static inline void bond_send_unsolicited_na(struct bonding *bond)
+{
+       return;
+}
+static inline void bond_register_ipv6_notifier(void)
+{
+       return;
+}
+static inline void bond_unregister_ipv6_notifier(void)
+{
+       return;
+}
+#endif
+
 #endif /* _LINUX_BONDING_H */
 
index 86909cfb14de77b458131940110d290e76c6197f..bc84c4ca898eb9ed9040a0ff0a9cc93357069fad 100644 (file)
@@ -2405,7 +2405,6 @@ static int cas_rx_ringN(struct cas *cp, int ring, int budget)
                cp->net_stats[ring].rx_packets++;
                cp->net_stats[ring].rx_bytes += len;
                spin_unlock(&cp->stat_lock[ring]);
-               cp->dev->last_rx = jiffies;
 
        next:
                npackets++;
@@ -4988,7 +4987,6 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
        int i, err, pci_using_dac;
        u16 pci_cmd;
        u8 orig_cacheline_size = 0, cas_cacheline_size = 0;
-       DECLARE_MAC_BUF(mac);
 
        if (cas_version_printed++ == 0)
                printk(KERN_INFO "%s", version);
@@ -5201,12 +5199,12 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
 
        i = readl(cp->regs + REG_BIM_CFG);
        printk(KERN_INFO "%s: Sun Cassini%s (%sbit/%sMHz PCI/%s) "
-              "Ethernet[%d] %s\n",  dev->name,
+              "Ethernet[%d] %pM\n",  dev->name,
               (cp->cas_flags & CAS_FLAG_REG_PLUS) ? "+" : "",
               (i & BIM_CFG_32BIT) ? "32" : "64",
               (i & BIM_CFG_66MHZ) ? "66" : "33",
               (cp->phy_type == CAS_PHY_SERDES) ? "Fi" : "Cu", pdev->irq,
-              print_mac(mac, dev->dev_addr));
+              dev->dev_addr);
 
        pci_set_drvdata(pdev, dev);
        cp->hw_running = 1;
index 638c9a27a7a64902f00dd2251382ed4ff8b1de55..5fb0038b8549b14ac6dd607e0a4668724b8d03e4 100644 (file)
@@ -120,7 +120,7 @@ static const char pci_speed[][4] = {
  */
 static void t1_set_rxmode(struct net_device *dev)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        struct cmac *mac = adapter->port[dev->if_port].mac;
        struct t1_rx_mode rm;
 
@@ -252,7 +252,7 @@ static void cxgb_down(struct adapter *adapter)
 static int cxgb_open(struct net_device *dev)
 {
        int err;
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        int other_ports = adapter->open_device_map & PORT_MASK;
 
        napi_enable(&adapter->napi);
@@ -272,7 +272,7 @@ static int cxgb_open(struct net_device *dev)
 
 static int cxgb_close(struct net_device *dev)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        struct port_info *p = &adapter->port[dev->if_port];
        struct cmac *mac = p->mac;
 
@@ -298,7 +298,7 @@ static int cxgb_close(struct net_device *dev)
 
 static struct net_device_stats *t1_get_stats(struct net_device *dev)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        struct port_info *p = &adapter->port[dev->if_port];
        struct net_device_stats *ns = &p->netstats;
        const struct cmac_statistics *pstats;
@@ -346,14 +346,14 @@ static struct net_device_stats *t1_get_stats(struct net_device *dev)
 
 static u32 get_msglevel(struct net_device *dev)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
 
        return adapter->msg_enable;
 }
 
 static void set_msglevel(struct net_device *dev, u32 val)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
 
        adapter->msg_enable = val;
 }
@@ -434,7 +434,7 @@ static int get_regs_len(struct net_device *dev)
 
 static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
 
        strcpy(info->driver, DRV_NAME);
        strcpy(info->version, DRV_VERSION);
@@ -461,7 +461,7 @@ static void get_strings(struct net_device *dev, u32 stringset, u8 *data)
 static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
                      u64 *data)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        struct cmac *mac = adapter->port[dev->if_port].mac;
        const struct cmac_statistics *s;
        const struct sge_intr_counts *t;
@@ -552,7 +552,7 @@ static inline void reg_block_dump(struct adapter *ap, void *buf,
 static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
                     void *buf)
 {
-       struct adapter *ap = dev->priv;
+       struct adapter *ap = dev->ml_priv;
 
        /*
         * Version scheme: bits 0..9: chip version, bits 10..15: chip revision
@@ -574,7 +574,7 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
 
 static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        struct port_info *p = &adapter->port[dev->if_port];
 
        cmd->supported = p->link_config.supported;
@@ -634,7 +634,7 @@ static int speed_duplex_to_caps(int speed, int duplex)
 
 static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        struct port_info *p = &adapter->port[dev->if_port];
        struct link_config *lc = &p->link_config;
 
@@ -669,7 +669,7 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 static void get_pauseparam(struct net_device *dev,
                           struct ethtool_pauseparam *epause)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        struct port_info *p = &adapter->port[dev->if_port];
 
        epause->autoneg = (p->link_config.requested_fc & PAUSE_AUTONEG) != 0;
@@ -680,7 +680,7 @@ static void get_pauseparam(struct net_device *dev,
 static int set_pauseparam(struct net_device *dev,
                          struct ethtool_pauseparam *epause)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        struct port_info *p = &adapter->port[dev->if_port];
        struct link_config *lc = &p->link_config;
 
@@ -709,14 +709,14 @@ static int set_pauseparam(struct net_device *dev,
 
 static u32 get_rx_csum(struct net_device *dev)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
 
        return (adapter->flags & RX_CSUM_ENABLED) != 0;
 }
 
 static int set_rx_csum(struct net_device *dev, u32 data)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
 
        if (data)
                adapter->flags |= RX_CSUM_ENABLED;
@@ -727,7 +727,7 @@ static int set_rx_csum(struct net_device *dev, u32 data)
 
 static int set_tso(struct net_device *dev, u32 value)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
 
        if (!(adapter->flags & TSO_CAPABLE))
                return value ? -EOPNOTSUPP : 0;
@@ -736,7 +736,7 @@ static int set_tso(struct net_device *dev, u32 value)
 
 static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
 
        e->rx_max_pending = MAX_RX_BUFFERS;
@@ -752,7 +752,7 @@ static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
 
 static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
 
        if (e->rx_pending > MAX_RX_BUFFERS || e->rx_mini_pending ||
@@ -776,7 +776,7 @@ static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
 
 static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
 
        adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs;
        adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce;
@@ -787,7 +787,7 @@ static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
 
 static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
 
        c->rx_coalesce_usecs = adapter->params.sge.rx_coalesce_usecs;
        c->rate_sample_interval = adapter->params.sge.sample_interval_usecs;
@@ -797,7 +797,7 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
 
 static int get_eeprom_len(struct net_device *dev)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
 
        return t1_is_asic(adapter) ? EEPROM_SIZE : 0;
 }
@@ -810,7 +810,7 @@ static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
 {
        int i;
        u8 buf[EEPROM_SIZE] __attribute__((aligned(4)));
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
 
        e->magic = EEPROM_MAGIC(adapter);
        for (i = e->offset & ~3; i < e->offset + e->len; i += sizeof(u32))
@@ -848,7 +848,7 @@ static const struct ethtool_ops t1_ethtool_ops = {
 
 static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        struct mii_ioctl_data *data = if_mii(req);
 
        switch (cmd) {
@@ -887,7 +887,7 @@ static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 static int t1_change_mtu(struct net_device *dev, int new_mtu)
 {
        int ret;
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        struct cmac *mac = adapter->port[dev->if_port].mac;
 
        if (!mac->ops->set_mtu)
@@ -902,7 +902,7 @@ static int t1_change_mtu(struct net_device *dev, int new_mtu)
 
 static int t1_set_mac_addr(struct net_device *dev, void *p)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        struct cmac *mac = adapter->port[dev->if_port].mac;
        struct sockaddr *addr = p;
 
@@ -918,7 +918,7 @@ static int t1_set_mac_addr(struct net_device *dev, void *p)
 static void vlan_rx_register(struct net_device *dev,
                                   struct vlan_group *grp)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
 
        spin_lock_irq(&adapter->async_lock);
        adapter->vlan_grp = grp;
@@ -931,7 +931,7 @@ static void vlan_rx_register(struct net_device *dev,
 static void t1_netpoll(struct net_device *dev)
 {
        unsigned long flags;
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
 
        local_irq_save(flags);
        t1_interrupt(adapter->pdev->irq, adapter);
@@ -1077,7 +1077,7 @@ static int __devinit init_one(struct pci_dev *pdev,
                SET_NETDEV_DEV(netdev, &pdev->dev);
 
                if (!adapter) {
-                       adapter = netdev->priv;
+                       adapter = netdev_priv(netdev);
                        adapter->pdev = pdev;
                        adapter->port[0].dev = netdev;  /* so we don't leak it */
 
@@ -1118,7 +1118,7 @@ static int __devinit init_one(struct pci_dev *pdev,
                netdev->if_port = i;
                netdev->mem_start = mmio_start;
                netdev->mem_end = mmio_start + mmio_len - 1;
-               netdev->priv = adapter;
+               netdev->ml_priv = adapter;
                netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
                netdev->features |= NETIF_F_LLTX;
 
@@ -1382,7 +1382,7 @@ static inline void t1_sw_reset(struct pci_dev *pdev)
 static void __devexit remove_one(struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        int i;
 
        for_each_port(adapter, i) {
index d6c7d2aa761b503da15a96126ee1f2f3895e4f0a..ca80289fc04d80bf7dfb6405d80de684eb984403 100644 (file)
@@ -1385,7 +1385,6 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
        st = per_cpu_ptr(sge->port_stats[p->iff], smp_processor_id());
 
        skb->protocol = eth_type_trans(skb, adapter->port[p->iff].dev);
-       skb->dev->last_rx = jiffies;
        if ((adapter->flags & RX_CSUM_ENABLED) && p->csum == 0xffff &&
            skb->protocol == htons(ETH_P_IP) &&
            (skb->data[9] == IPPROTO_TCP || skb->data[9] == IPPROTO_UDP)) {
@@ -1786,7 +1785,7 @@ static inline int eth_hdr_len(const void *data)
  */
 int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct adapter *adapter = dev->priv;
+       struct adapter *adapter = dev->ml_priv;
        struct sge *sge = adapter->sge;
        struct sge_port_stats *st = per_cpu_ptr(sge->port_stats[dev->if_port],
                                                smp_processor_id());
index 017a5361b980c2f37b8ff1e6b05ac1d8c90a158b..d39a77cba1afe0c70214bd02b78df9ea8333a1e2 100644 (file)
@@ -1103,7 +1103,6 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
        struct cpmac_priv *priv;
        struct net_device *dev;
        struct plat_cpmac_data *pdata;
-       DECLARE_MAC_BUF(mac);
 
        pdata = pdev->dev.platform_data;
 
@@ -1180,8 +1179,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
        if (netif_msg_probe(priv)) {
                printk(KERN_INFO
                       "cpmac: device %s (regs: %p, irq: %d, phy: %s, "
-                      "mac: %s)\n", dev->name, (void *)mem->start, dev->irq,
-                      priv->phy_name, print_mac(mac, dev->dev_addr));
+                      "mac: %pM)\n", dev->name, (void *)mem->start, dev->irq,
+                      priv->phy_name, dev->dev_addr);
        }
        return 0;
 
index 7e8a63106bdf42f2aa3ba4e4303e9920fab56713..c9806c58b2fde2644505fde1409dbf6af24674fd 100644 (file)
@@ -419,7 +419,6 @@ e100_set_mac_address(struct net_device *dev, void *p)
 {
        struct net_local *np = netdev_priv(dev);
        struct sockaddr *addr = p;
-       DECLARE_MAC_BUF(mac);
 
        spin_lock(&np->lock); /* preemption protection */
 
@@ -440,8 +439,7 @@ e100_set_mac_address(struct net_device *dev, void *p)
 
        /* show it in the log as well */
 
-       printk(KERN_INFO "%s: changed MAC to %s\n",
-              dev->name, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: changed MAC to %pM\n", dev->name, dev->dev_addr);
 
        spin_unlock(&np->lock);
 
index 7107620f615dfd0d17bef1b06fce245ef12411f0..b063395c4a96779922e0b63f9f2c62f53d5c1690 100644 (file)
@@ -521,7 +521,6 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
        unsigned rev_type = 0;
        int eeprom_buff[CHKSUM_LEN];
        int retval;
-       DECLARE_MAC_BUF(mac);
 
        /* Initialize the device structure. */
        if (!modular) {
@@ -846,7 +845,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
        }
 
        /* print the ethernet address. */
-       printk(", MAC %s", print_mac(mac, dev->dev_addr));
+       printk(", MAC %pM", dev->dev_addr);
 
        dev->open               = net_open;
        dev->stop               = net_close;
@@ -1025,7 +1024,6 @@ skip_this_frame:
        }
         skb->protocol=eth_type_trans(skb,dev);
        netif_rx(skb);
-       dev->last_rx = jiffies;
        lp->stats.rx_packets++;
        lp->stats.rx_bytes += length;
 }
@@ -1719,7 +1717,6 @@ net_rx(struct net_device *dev)
 
         skb->protocol=eth_type_trans(skb,dev);
        netif_rx(skb);
-       dev->last_rx = jiffies;
        lp->stats.rx_packets++;
        lp->stats.rx_bytes += length;
 }
@@ -1817,11 +1814,10 @@ static int set_mac_address(struct net_device *dev, void *p)
 
        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 
-       if (net_debug) {
-               DECLARE_MAC_BUF(mac);
-               printk("%s: Setting MAC address to %s.\n",
-                      dev->name, print_mac(mac, dev->dev_addr));
-       }
+       if (net_debug)
+               printk("%s: Setting MAC address to %pM.\n",
+                      dev->name, dev->dev_addr);
+
        /* set the Ethernet address */
        for (i=0; i < ETH_ALEN/2; i++)
                writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
index 2c341f83d3270e8d32a42d24e1a472fffd945599..b6b2a46b7d0e92bfd4a8ed8dd5cd7c9457fe78a1 100644 (file)
@@ -493,6 +493,36 @@ static void enable_all_napi(struct adapter *adap)
                        napi_enable(&adap->sge.qs[i].napi);
 }
 
+/**
+ *     set_qset_lro - Turn a queue set's LRO capability on and off
+ *     @dev: the device the qset is attached to
+ *     @qset_idx: the queue set index
+ *     @val: the LRO switch
+ *
+ *     Sets LRO on or off for a particular queue set.
+ *     the device's features flag is updated to reflect the LRO
+ *     capability when all queues belonging to the device are
+ *     in the same state.
+ */
+static void set_qset_lro(struct net_device *dev, int qset_idx, int val)
+{
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
+       int i, lro_on = 1;
+
+       adapter->params.sge.qset[qset_idx].lro = !!val;
+       adapter->sge.qs[qset_idx].lro_enabled = !!val;
+
+       /* let ethtool report LRO on only if all queues are LRO enabled */
+       for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; ++i)
+               lro_on &= adapter->params.sge.qset[i].lro;
+
+       if (lro_on)
+               dev->features |= NETIF_F_LRO;
+       else
+               dev->features &= ~NETIF_F_LRO;
+}
+
 /**
  *     setup_sge_qsets - configure SGE Tx/Rx/response queues
  *     @adap: the adapter
@@ -516,8 +546,7 @@ static int setup_sge_qsets(struct adapter *adap)
                pi->qs = &adap->sge.qs[pi->first_qset];
                for (j = pi->first_qset; j < pi->first_qset + pi->nqsets;
                     ++j, ++qset_idx) {
-                       if (!pi->rx_csum_offload)
-                               adap->params.sge.qset[qset_idx].lro = 0;
+                       set_qset_lro(dev, qset_idx, pi->rx_csum_offload);
                        err = t3_sge_alloc_qset(adap, qset_idx, 1,
                                (adap->flags & USING_MSIX) ? qset_idx + 1 :
                                                             irq_idx,
@@ -1634,13 +1663,10 @@ static int set_rx_csum(struct net_device *dev, u32 data)
 
        p->rx_csum_offload = data;
        if (!data) {
-               struct adapter *adap = p->adapter;
                int i;
 
-               for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) {
-                       adap->params.sge.qset[i].lro = 0;
-                       adap->sge.qs[i].lro_enabled = 0;
-               }
+               for (i = p->first_qset; i < p->first_qset + p->nqsets; i++)
+                       set_qset_lro(dev, i, 0);
        }
        return 0;
 }
@@ -1795,6 +1821,25 @@ static void get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        memset(&wol->sopass, 0, sizeof(wol->sopass));
 }
 
+static int cxgb3_set_flags(struct net_device *dev, u32 data)
+{
+       struct port_info *pi = netdev_priv(dev);
+       int i;
+
+       if (data & ETH_FLAG_LRO) {
+               if (!pi->rx_csum_offload)
+                       return -EINVAL;
+
+               for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++)
+                       set_qset_lro(dev, i, 1);
+
+       } else
+               for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++)
+                       set_qset_lro(dev, i, 0);
+
+       return 0;
+}
+
 static const struct ethtool_ops cxgb_ethtool_ops = {
        .get_settings = get_settings,
        .set_settings = set_settings,
@@ -1824,6 +1869,8 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
        .get_regs = get_regs,
        .get_wol = get_wol,
        .set_tso = ethtool_op_set_tso,
+       .get_flags = ethtool_op_get_flags,
+       .set_flags = cxgb3_set_flags,
 };
 
 static int in_range(int val, int lo, int hi)
@@ -1940,11 +1987,9 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
                                }
                        }
                }
-               if (t.lro >= 0) {
-                       struct sge_qset *qs = &adapter->sge.qs[t.qset_idx];
-                       q->lro = t.lro;
-                       qs->lro_enabled = t.lro;
-               }
+               if (t.lro >= 0)
+                       set_qset_lro(dev, t.qset_idx, t.lro);
+
                break;
        }
        case CHELSIO_GET_QSET_PARAMS:{
index c6480be0bc1f7ed033b9a9ed0d856d12b4490255..268f15801ec6237fd17b0c8ba3c714e64546d9fe 100644 (file)
@@ -1876,7 +1876,6 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
 
        skb_pull(skb, sizeof(*p) + pad);
        skb->protocol = eth_type_trans(skb, adap->port[p->iff]);
-       skb->dev->last_rx = jiffies;
        pi = netdev_priv(skb->dev);
        if (pi->rx_csum_offload && p->csum_valid && p->csum == htons(0xffff) &&
            !p->fragment) {
index cb849b091f980c9521e45ed0ac227420fa835c30..970f820ba814fc3b71d1f09401d74da5f0fa0b6a 100644 (file)
@@ -369,7 +369,6 @@ static void de600_rx_intr(struct net_device *dev)
        netif_rx(skb);
 
        /* update stats */
-       dev->last_rx = jiffies;
        dev->stats.rx_packets++; /* count all receives */
        dev->stats.rx_bytes += size; /* count all received bytes */
 
@@ -384,7 +383,6 @@ static struct net_device * __init de600_probe(void)
        int     i;
        struct net_device *dev;
        int err;
-       DECLARE_MAC_BUF(mac);
 
        dev = alloc_etherdev(0);
        if (!dev)
@@ -439,7 +437,7 @@ static struct net_device * __init de600_probe(void)
                goto out1;
        }
 
-       printk(", Ethernet Address: %s\n", print_mac(mac, dev->dev_addr));
+       printk(", Ethernet Address: %pM\n", dev->dev_addr);
 
        dev->open = de600_open;
        dev->stop = de600_close;
index d454e143483ee39ad64ba0724753af67053527c0..0d4b6acc11a6d8b19ce4c6ac690cb5b3db861b14 100644 (file)
@@ -686,7 +686,6 @@ static int de620_rx_intr(struct net_device *dev)
                        PRINTK(("Read %d bytes\n", size));
                        skb->protocol=eth_type_trans(skb,dev);
                        netif_rx(skb); /* deliver it "upstairs" */
-                       dev->last_rx = jiffies;
                        /* count all receives */
                        dev->stats.rx_packets++;
                        dev->stats.rx_bytes += size;
@@ -800,7 +799,6 @@ struct net_device * __init de620_probe(int unit)
        struct net_device *dev;
        int err = -ENOMEM;
        int i;
-       DECLARE_MAC_BUF(mac);
 
        dev = alloc_etherdev(0);
        if (!dev)
@@ -853,7 +851,7 @@ struct net_device * __init de620_probe(int unit)
                dev->broadcast[i] = 0xff;
        }
 
-       printk(", Ethernet Address: %s", print_mac(mac, dev->dev_addr));
+       printk(", Ethernet Address: %pM", dev->dev_addr);
 
        printk(" (%dk RAM,",
                (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64);
@@ -876,10 +874,7 @@ struct net_device * __init de620_probe(int unit)
        if (de620_debug) {
                printk("\nEEPROM contents:\n");
                printk("RAM_Size = 0x%02X\n", nic_data.RAM_Size);
-               printk("NodeID = %02X:%02X:%02X:%02X:%02X:%02X\n",
-                       nic_data.NodeID[0], nic_data.NodeID[1],
-                       nic_data.NodeID[2], nic_data.NodeID[3],
-                       nic_data.NodeID[4], nic_data.NodeID[5]);
+               printk("NodeID = %pM\n", nic_data.NodeID);
                printk("Model = %d\n", nic_data.Model);
                printk("Media = %d\n", nic_data.Media);
                printk("SCR = 0x%02x\n", nic_data.SCR);
index 3e3506411ac08a50501e8049bb6f0b74af9a0363..7ce3053530f9c62279f38dd17340e89167b6044b 100644 (file)
@@ -622,7 +622,6 @@ static int lance_rx(struct net_device *dev)
 
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                }
 
@@ -1023,7 +1022,6 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
        int i, ret;
        unsigned long esar_base;
        unsigned char *esar;
-       DECLARE_MAC_BUF(mac);
 
        if (dec_lance_debug && version_printed++ == 0)
                printk(version);
@@ -1035,7 +1033,7 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
                dev = root_lance_dev;
                while (dev) {
                        i++;
-                       lp = (struct lance_private *)dev->priv;
+                       lp = netdev_priv(dev);
                        dev = lp->next;
                }
                snprintf(name, sizeof(name), fmt, i);
@@ -1223,8 +1221,7 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = esar[i * 4];
 
-       printk(", addr = %s, irq = %d\n",
-              print_mac(mac, dev->dev_addr), dev->irq);
+       printk(", addr = %pM, irq = %d\n", dev->dev_addr, dev->irq);
 
        dev->open = &lance_open;
        dev->stop = &lance_close;
index c062aacf229ce2b23e773e45584734184d6e3ffa..6e6583b609f702266eb4e4275c0488d2e5fac5da 100644 (file)
@@ -511,7 +511,7 @@ static int __devinit dfx_register(struct device *bdev)
        int dfx_bus_pci = DFX_BUS_PCI(bdev);
        int dfx_bus_tc = DFX_BUS_TC(bdev);
        int dfx_use_mmio = DFX_MMIO || dfx_bus_tc;
-       char *print_name = bdev->bus_id;
+       const char *print_name = dev_name(bdev);
        struct net_device *dev;
        DFX_board_t       *bp;                  /* board pointer */
        resource_size_t bar_start = 0;          /* pointer to port */
@@ -3103,7 +3103,6 @@ static void dfx_rcv_queue_process(
                                        netif_rx(skb);
 
                                        /* Update the rcv counters */
-                                       bp->dev->last_rx = jiffies;
                                        bp->rcv_total_frames++;
                                        if (*(p_buff + RCV_BUFF_K_DA) & 0x01)
                                                bp->rcv_multicast_frames++;
index ace39ec0a367c121be87001b4e44bde930c0633f..ec34f03cb9824049633fa4102d8bbd762e1412c9 100644 (file)
@@ -573,7 +573,6 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
        s16 nicsr;
        u_long ioaddr;
        u_long mem_start;
-       DECLARE_MAC_BUF(mac);
 
        /*
         * We are now supposed to enter this function with the
@@ -601,7 +600,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
                return -ENXIO;
        }
 
-       lp = (struct depca_private *) dev->priv;
+       lp = netdev_priv(dev);
        mem_start = lp->mem_start;
 
        if (!mem_start || lp->adapter < DEPCA || lp->adapter >=unknown)
@@ -633,7 +632,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
 
        printk(", h/w address ");
        status = get_hw_addr(dev);
-       printk("%s", print_mac(mac, dev->dev_addr));
+       printk("%pM", dev->dev_addr);
        if (status != 0) {
                printk("      which has an Ethernet PROM CRC error.\n");
                return -ENXIO;
@@ -821,7 +820,7 @@ out_priv:
 
 static int depca_open(struct net_device *dev)
 {
-       struct depca_private *lp = (struct depca_private *) dev->priv;
+       struct depca_private *lp = netdev_priv(dev);
        u_long ioaddr = dev->base_addr;
        s16 nicsr;
        int status = 0;
@@ -866,7 +865,7 @@ static int depca_open(struct net_device *dev)
 /* Initialize the lance Rx and Tx descriptor rings. */
 static void depca_init_ring(struct net_device *dev)
 {
-       struct depca_private *lp = (struct depca_private *) dev->priv;
+       struct depca_private *lp = netdev_priv(dev);
        u_int i;
        u_long offset;
 
@@ -924,7 +923,7 @@ static void depca_tx_timeout(struct net_device *dev)
 */
 static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct depca_private *lp = (struct depca_private *) dev->priv;
+       struct depca_private *lp = netdev_priv(dev);
        u_long ioaddr = dev->base_addr;
        int status = 0;
 
@@ -972,7 +971,7 @@ static irqreturn_t depca_interrupt(int irq, void *dev_id)
                return IRQ_NONE;
        }
 
-       lp = (struct depca_private *) dev->priv;
+       lp = netdev_priv(dev);
        ioaddr = dev->base_addr;
 
        spin_lock(&lp->lock);
@@ -1010,7 +1009,7 @@ static irqreturn_t depca_interrupt(int irq, void *dev_id)
 /* Called with lp->lock held */
 static int depca_rx(struct net_device *dev)
 {
-       struct depca_private *lp = (struct depca_private *) dev->priv;
+       struct depca_private *lp = netdev_priv(dev);
        int i, entry;
        s32 status;
 
@@ -1057,7 +1056,6 @@ static int depca_rx(struct net_device *dev)
                                        /*
                                           ** Update stats
                                         */
-                                       dev->last_rx = jiffies;
                                        dev->stats.rx_packets++;
                                        dev->stats.rx_bytes += pkt_len;
                                        for (i = 1; i < DEPCA_PKT_STAT_SZ - 1; i++) {
@@ -1108,7 +1106,7 @@ static int depca_rx(struct net_device *dev)
 */
 static int depca_tx(struct net_device *dev)
 {
-       struct depca_private *lp = (struct depca_private *) dev->priv;
+       struct depca_private *lp = netdev_priv(dev);
        int entry;
        s32 status;
        u_long ioaddr = dev->base_addr;
@@ -1149,7 +1147,7 @@ static int depca_tx(struct net_device *dev)
 
 static int depca_close(struct net_device *dev)
 {
-       struct depca_private *lp = (struct depca_private *) dev->priv;
+       struct depca_private *lp = netdev_priv(dev);
        s16 nicsr;
        u_long ioaddr = dev->base_addr;
 
@@ -1185,7 +1183,7 @@ static int depca_close(struct net_device *dev)
 
 static void LoadCSRs(struct net_device *dev)
 {
-       struct depca_private *lp = (struct depca_private *) dev->priv;
+       struct depca_private *lp = netdev_priv(dev);
        u_long ioaddr = dev->base_addr;
 
        outw(CSR1, DEPCA_ADDR); /* initialisation block address LSW */
@@ -1202,7 +1200,7 @@ static void LoadCSRs(struct net_device *dev)
 
 static int InitRestartDepca(struct net_device *dev)
 {
-       struct depca_private *lp = (struct depca_private *) dev->priv;
+       struct depca_private *lp = netdev_priv(dev);
        u_long ioaddr = dev->base_addr;
        int i, status = 0;
 
@@ -1234,7 +1232,7 @@ static int InitRestartDepca(struct net_device *dev)
 */
 static void set_multicast_list(struct net_device *dev)
 {
-       struct depca_private *lp = (struct depca_private *) dev->priv;
+       struct depca_private *lp = netdev_priv(dev);
        u_long ioaddr = dev->base_addr;
 
        netif_stop_queue(dev);
@@ -1263,7 +1261,7 @@ static void set_multicast_list(struct net_device *dev)
 */
 static void SetMulticastFilter(struct net_device *dev)
 {
-       struct depca_private *lp = (struct depca_private *) dev->priv;
+       struct depca_private *lp = netdev_priv(dev);
        struct dev_mc_list *dmi = dev->mc_list;
        char *addrs;
        int i, j, bit, byte;
@@ -1431,7 +1429,7 @@ static int __init depca_mca_probe(struct device *device)
 
        dev->irq = irq;
        dev->base_addr = iobase;
-       lp = dev->priv;
+       lp = netdev_priv(dev);
        lp->depca_bus = DEPCA_BUS_MCA;
        lp->adapter = depca_mca_adapter_type[mdev->index];
        lp->mem_start = mem_start;
@@ -1534,7 +1532,7 @@ static int __init depca_isa_probe (struct platform_device *device)
        dev->base_addr = ioaddr;
        dev->irq = irq;         /* Use whatever value the user gave
                                 * us, and 0 if he didn't. */
-       lp = dev->priv;
+       lp = netdev_priv(dev);
        lp->depca_bus = DEPCA_BUS_ISA;
        lp->adapter = adapter;
        lp->mem_start = mem_start;
@@ -1580,7 +1578,7 @@ static int __init depca_eisa_probe (struct device *device)
 
        dev->base_addr = ioaddr;
        dev->irq = irq;
-       lp = dev->priv;
+       lp = netdev_priv(dev);
        lp->depca_bus = DEPCA_BUS_EISA;
        lp->adapter = edev->id.driver_data;
        lp->mem_start = mem_start;
@@ -1605,7 +1603,7 @@ static int __devexit depca_device_remove (struct device *device)
        int bus;
 
        dev  = device->driver_data;
-       lp   = dev->priv;
+       lp   = netdev_priv(dev);
 
        unregister_netdev (dev);
        iounmap (lp->sh_mem);
@@ -1747,7 +1745,7 @@ static int __init DevicePresent(u_long ioaddr)
 static int __init get_hw_addr(struct net_device *dev)
 {
        u_long ioaddr = dev->base_addr;
-       struct depca_private *lp = dev->priv;
+       struct depca_private *lp = netdev_priv(dev);
        int i, k, tmp, status = 0;
        u_short j, x, chksum;
 
@@ -1782,7 +1780,7 @@ static int __init get_hw_addr(struct net_device *dev)
 */
 static int load_packet(struct net_device *dev, struct sk_buff *skb)
 {
-       struct depca_private *lp = (struct depca_private *) dev->priv;
+       struct depca_private *lp = netdev_priv(dev);
        int i, entry, end, len, status = 0;
 
        entry = lp->tx_new;     /* Ring around buffer number. */
@@ -1837,11 +1835,10 @@ static int load_packet(struct net_device *dev, struct sk_buff *skb)
 
 static void depca_dbg_open(struct net_device *dev)
 {
-       struct depca_private *lp = (struct depca_private *) dev->priv;
+       struct depca_private *lp = netdev_priv(dev);
        u_long ioaddr = dev->base_addr;
        struct depca_init *p = &lp->init_block;
        int i;
-       DECLARE_MAC_BUF(mac);
 
        if (depca_debug > 1) {
                /* Do not copy the shadow init block into shared memory */
@@ -1880,7 +1877,7 @@ static void depca_dbg_open(struct net_device *dev)
                printk("...0x%8.8x\n", readl(&lp->tx_ring[i].base));
                printk("Initialisation block at 0x%8.8lx(Phys)\n", lp->mem_start);
                printk("        mode: 0x%4.4x\n", p->mode);
-               printk("        physical address: %s\n", print_mac(mac, p->phys_addr));
+               printk("        physical address: %pM\n", p->phys_addr);
                printk("        multicast hash table: ");
                for (i = 0; i < (HASH_TABLE_LEN >> 3) - 1; i++) {
                        printk("%2.2x:", p->mcast_table[i]);
@@ -1909,7 +1906,7 @@ static void depca_dbg_open(struct net_device *dev)
 */
 static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-       struct depca_private *lp = (struct depca_private *) dev->priv;
+       struct depca_private *lp = netdev_priv(dev);
        struct depca_ioctl *ioc = (struct depca_ioctl *) &rq->ifr_ifru;
        int i, status = 0;
        u_long ioaddr = dev->base_addr;
index f8037110a522e3eb2616414908cacdaafa363c8f..9ec9785a9fc3424ebf72ced7e5a94c02ff87a77c 100644 (file)
@@ -97,7 +97,6 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
        static int version_printed;
        void *ring_space;
        dma_addr_t ring_dma;
-       DECLARE_MAC_BUF(mac);
 
        if (!version_printed++)
                printk ("%s", version);
@@ -257,8 +256,8 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
 
        card_idx++;
 
-       printk (KERN_INFO "%s: %s, %s, IRQ %d\n",
-               dev->name, np->name, print_mac(mac, dev->dev_addr), irq);
+       printk (KERN_INFO "%s: %s, %pM, IRQ %d\n",
+               dev->name, np->name, dev->dev_addr, irq);
        if (tx_coalesce > 1)
                printk(KERN_INFO "tx_coalesce:\t%d packets\n",
                                tx_coalesce);
@@ -892,7 +891,6 @@ receive_packet (struct net_device *dev)
                        }
 #endif
                        netif_rx (skb);
-                       dev->last_rx = jiffies;
                }
                entry = (entry + 1) % RX_RING_SIZE;
        }
index 5a9083e3f443b81f0b744cac37f3b36d274b88ff..bcf92917bbf3192504bd90e48e4165716615208d 100644 (file)
@@ -137,7 +137,7 @@ typedef struct board_info {
 
 static inline board_info_t *to_dm9000_board(struct net_device *dev)
 {
-       return dev->priv;
+       return netdev_priv(dev);
 }
 
 /* DM9000 network board routine ---------------------------- */
@@ -626,7 +626,7 @@ static unsigned char dm9000_type_to_char(enum dm9000_type type)
 static void
 dm9000_hash_table(struct net_device *dev)
 {
-       board_info_t *db = (board_info_t *) dev->priv;
+       board_info_t *db = netdev_priv(dev);
        struct dev_mc_list *mcptr = dev->mc_list;
        int mc_cnt = dev->mc_count;
        int i, oft;
@@ -677,7 +677,7 @@ dm9000_hash_table(struct net_device *dev)
 static void
 dm9000_init_dm9000(struct net_device *dev)
 {
-       board_info_t *db = dev->priv;
+       board_info_t *db = netdev_priv(dev);
        unsigned int imr;
 
        dm9000_dbg(db, 1, "entering %s\n", __func__);
@@ -723,7 +723,7 @@ dm9000_init_dm9000(struct net_device *dev)
 /* Our watchdog timed out. Called by the networking layer */
 static void dm9000_timeout(struct net_device *dev)
 {
-       board_info_t *db = (board_info_t *) dev->priv;
+       board_info_t *db = netdev_priv(dev);
        u8 reg_save;
        unsigned long flags;
 
@@ -751,7 +751,7 @@ static int
 dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        unsigned long flags;
-       board_info_t *db = dev->priv;
+       board_info_t *db = netdev_priv(dev);
 
        dm9000_dbg(db, 3, "%s:\n", __func__);
 
@@ -831,7 +831,7 @@ struct dm9000_rxhdr {
 static void
 dm9000_rx(struct net_device *dev)
 {
-       board_info_t *db = (board_info_t *) dev->priv;
+       board_info_t *db = netdev_priv(dev);
        struct dm9000_rxhdr rxhdr;
        struct sk_buff *skb;
        u8 rxbyte, *rdptr;
@@ -928,7 +928,7 @@ dm9000_rx(struct net_device *dev)
 static irqreturn_t dm9000_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
-       board_info_t *db = dev->priv;
+       board_info_t *db = netdev_priv(dev);
        int int_status;
        u8 reg_save;
 
@@ -996,7 +996,7 @@ static void dm9000_poll_controller(struct net_device *dev)
 static int
 dm9000_open(struct net_device *dev)
 {
-       board_info_t *db = dev->priv;
+       board_info_t *db = netdev_priv(dev);
        unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;
 
        if (netif_msg_ifup(db))
@@ -1046,7 +1046,7 @@ static void dm9000_msleep(board_info_t *db, unsigned int ms)
 static int
 dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
 {
-       board_info_t *db = (board_info_t *) dev->priv;
+       board_info_t *db = netdev_priv(dev);
        unsigned long flags;
        unsigned int reg_save;
        int ret;
@@ -1093,7 +1093,7 @@ static void
 dm9000_phy_write(struct net_device *dev,
                 int phyaddr_unused, int reg, int value)
 {
-       board_info_t *db = (board_info_t *) dev->priv;
+       board_info_t *db = netdev_priv(dev);
        unsigned long flags;
        unsigned long reg_save;
 
@@ -1134,7 +1134,7 @@ dm9000_phy_write(struct net_device *dev,
 static void
 dm9000_shutdown(struct net_device *dev)
 {
-       board_info_t *db = dev->priv;
+       board_info_t *db = netdev_priv(dev);
 
        /* RESET device */
        dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */
@@ -1150,7 +1150,7 @@ dm9000_shutdown(struct net_device *dev)
 static int
 dm9000_stop(struct net_device *ndev)
 {
-       board_info_t *db = ndev->priv;
+       board_info_t *db = netdev_priv(ndev);
 
        if (netif_msg_ifdown(db))
                dev_dbg(db->dev, "shutting down %s\n", ndev->name);
@@ -1197,7 +1197,7 @@ dm9000_probe(struct platform_device *pdev)
        dev_dbg(&pdev->dev, "dm9000_probe()\n");
 
        /* setup board info structure */
-       db = ndev->priv;
+       db = netdev_priv(ndev);
        memset(db, 0, sizeof(*db));
 
        db->dev = &pdev->dev;
@@ -1385,13 +1385,11 @@ dm9000_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, ndev);
        ret = register_netdev(ndev);
 
-       if (ret == 0) {
-               DECLARE_MAC_BUF(mac);
-               printk(KERN_INFO "%s: dm9000%c at %p,%p IRQ %d MAC: %s (%s)\n",
+       if (ret == 0)
+               printk(KERN_INFO "%s: dm9000%c at %p,%p IRQ %d MAC: %pM (%s)\n",
                       ndev->name, dm9000_type_to_char(db->type),
                       db->io_addr, db->io_data, ndev->irq,
-                      print_mac(mac, ndev->dev_addr), mac_src);
-       }
+                      ndev->dev_addr, mac_src);
        return 0;
 
 out:
@@ -1410,7 +1408,7 @@ dm9000_drv_suspend(struct platform_device *dev, pm_message_t state)
        board_info_t *db;
 
        if (ndev) {
-               db = (board_info_t *) ndev->priv;
+               db = netdev_priv(ndev);
                db->in_suspend = 1;
 
                if (netif_running(ndev)) {
@@ -1425,7 +1423,7 @@ static int
 dm9000_drv_resume(struct platform_device *dev)
 {
        struct net_device *ndev = platform_get_drvdata(dev);
-       board_info_t *db = (board_info_t *) ndev->priv;
+       board_info_t *db = netdev_priv(ndev);
 
        if (ndev) {
 
@@ -1449,7 +1447,7 @@ dm9000_drv_remove(struct platform_device *pdev)
        platform_set_drvdata(pdev, NULL);
 
        unregister_netdev(ndev);
-       dm9000_release_board(pdev, (board_info_t *) ndev->priv);
+       dm9000_release_board(pdev, (board_info_t *) netdev_priv(ndev));
        free_netdev(ndev);              /* free device structure */
 
        dev_dbg(&pdev->dev, "released and freed device\n");
index e8bfcce6b319da95be67ecc44e211b7f8ed7ac38..c9c707980865f13567f6e3579521494277d6c1ac 100644 (file)
@@ -1880,7 +1880,6 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
        } else {
                dev->stats.rx_packets++;
                dev->stats.rx_bytes += actual_size;
-               nic->netdev->last_rx = jiffies;
                netif_receive_skb(skb);
                if(work_done)
                        (*work_done)++;
@@ -2322,7 +2321,8 @@ static int e100_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 {
        struct nic *nic = netdev_priv(netdev);
 
-       if(wol->wolopts != WAKE_MAGIC && wol->wolopts != 0)
+       if ((wol->wolopts && wol->wolopts != WAKE_MAGIC) ||
+           !device_can_wakeup(&nic->pdev->dev))
                return -EOPNOTSUPP;
 
        if(wol->wolopts)
@@ -2330,6 +2330,8 @@ static int e100_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
        else
                nic->flags &= ~wol_magic;
 
+       device_set_wakeup_enable(&nic->pdev->dev, wol->wolopts);
+
        e100_exec_cb(nic, NULL, e100_configure);
 
        return 0;
@@ -2616,7 +2618,6 @@ static int __devinit e100_probe(struct pci_dev *pdev,
        struct net_device *netdev;
        struct nic *nic;
        int err;
-       DECLARE_MAC_BUF(mac);
 
        if(!(netdev = alloc_etherdev(sizeof(struct nic)))) {
                if(((1 << debug) - 1) & NETIF_MSG_PROBE)
@@ -2734,8 +2735,10 @@ static int __devinit e100_probe(struct pci_dev *pdev,
 
        /* Wol magic packet can be enabled from eeprom */
        if((nic->mac >= mac_82558_D101_A4) &&
-          (nic->eeprom[eeprom_id] & eeprom_id_wol))
+          (nic->eeprom[eeprom_id] & eeprom_id_wol)) {
                nic->flags |= wol_magic;
+               device_set_wakeup_enable(&pdev->dev, true);
+       }
 
        /* ack any pending wake events, disable PME */
        pci_pme_active(pdev, false);
@@ -2746,9 +2749,9 @@ static int __devinit e100_probe(struct pci_dev *pdev,
                goto err_out_free;
        }
 
-       DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %s\n",
+       DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n",
                (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0),
-               pdev->irq, print_mac(mac, netdev->dev_addr));
+               pdev->irq, netdev->dev_addr);
 
        return 0;
 
@@ -2794,11 +2797,10 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
        pci_save_state(pdev);
 
        if ((nic->flags & wol_magic) | e100_asf(nic)) {
-               pci_enable_wake(pdev, PCI_D3hot, 1);
-               pci_enable_wake(pdev, PCI_D3cold, 1);
+               if (pci_enable_wake(pdev, PCI_D3cold, true))
+                       pci_enable_wake(pdev, PCI_D3hot, true);
        } else {
-               pci_enable_wake(pdev, PCI_D3hot, 0);
-               pci_enable_wake(pdev, PCI_D3cold, 0);
+               pci_enable_wake(pdev, PCI_D3hot, false);
        }
 
        pci_disable_device(pdev);
index 872799b746f501a3af4264c13b4674dbb8802382..dd8343244378b375eedffad2d567f43408071eed 100644 (file)
@@ -912,7 +912,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        u16 eeprom_data = 0;
        u16 eeprom_apme_mask = E1000_EEPROM_APME;
        int bars, need_ioport;
-       DECLARE_MAC_BUF(mac);
 
        /* do not allocate ioport bars when not needed */
        need_ioport = e1000_is_need_ioport(pdev);
@@ -967,8 +966,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        hw->back = adapter;
 
        err = -EIO;
-       hw->hw_addr = ioremap(pci_resource_start(pdev, BAR_0),
-                             pci_resource_len(pdev, BAR_0));
+       hw->hw_addr = pci_ioremap_bar(pdev, BAR_0);
        if (!hw->hw_addr)
                goto err_ioremap;
 
@@ -1016,9 +1014,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
         * because it depends on mac_type */
        if ((hw->mac_type == e1000_ich8lan) &&
           (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
-               hw->flash_address =
-                       ioremap(pci_resource_start(pdev, 1),
-                               pci_resource_len(pdev, 1));
+               hw->flash_address = pci_ioremap_bar(pdev, 1);
                if (!hw->flash_address)
                        goto err_flashmap;
        }
@@ -1195,7 +1191,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
                 (hw->bus_width == e1000_bus_width_pciex_1) ? "Width x1" :
                 "32-bit"));
 
-       printk("%s\n", print_mac(mac, netdev->dev_addr));
+       printk("%pM\n", netdev->dev_addr);
 
        if (hw->bus_type == e1000_bus_type_pci_express) {
                DPRINTK(PROBE, WARNING, "This device (id %04x:%04x) will no "
@@ -3791,8 +3787,7 @@ static int e1000_clean(struct napi_struct *napi, int budget)
        struct net_device *poll_dev = adapter->netdev;
        int tx_cleaned = 0, work_done = 0;
 
-       /* Must NOT use netdev_priv macro here. */
-       adapter = poll_dev->priv;
+       adapter = netdev_priv(poll_dev);
 
        /* e1000_clean is called per-cpu.  This lock protects
         * tx_ring[0] from being cleaned by multiple cpus
@@ -4104,8 +4099,6 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
                        netif_receive_skb(skb);
                }
 
-               netdev->last_rx = jiffies;
-
 next_desc:
                rx_desc->status = 0;
 
@@ -4789,7 +4782,7 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
                                                pci_channel_state_t state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
 
        netif_device_detach(netdev);
 
@@ -4811,7 +4804,7 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
 static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
        int err;
 
@@ -4845,7 +4838,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
 static void e1000_io_resume(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct e1000_adapter *adapter = netdev->priv;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
 
        e1000_init_manageability(adapter);
index b2c910c52df9756717246d21bdf2b115ab475d2c..3027ad53fa65820364f64ecfacb4cd30861bbffd 100644 (file)
@@ -973,6 +973,12 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
                ew32(CTRL_EXT, reg);
        }
 
+       if (hw->mac.type == e1000_82571) {
+               reg = er32(PBA_ECC);
+               reg |= E1000_PBA_ECC_CORR_EN;
+               ew32(PBA_ECC, reg);
+       }
+
        /* PCI-Ex Control Register */
        if (hw->mac.type == e1000_82574) {
                reg = er32(GCR);
index 48f79ecb82a035e424c7ffa855bd9e92595087ba..34a68fcab5a9304c3e8f7094d6bb004a75fa628d 100644 (file)
 #define E1000_ICR_TXQ1          0x00800000 /* Tx Queue 1 Interrupt */
 #define E1000_ICR_OTHER         0x01000000 /* Other Interrupts */
 
+/* PBA ECC Register */
+#define E1000_PBA_ECC_COUNTER_MASK  0xFFF00000 /* ECC counter mask */
+#define E1000_PBA_ECC_COUNTER_SHIFT 20         /* ECC counter shift value */
+#define E1000_PBA_ECC_CORR_EN       0x00000001 /* ECC correction enable */
+#define E1000_PBA_ECC_STAT_CLR      0x00000002 /* Clear ECC error counter */
+#define E1000_PBA_ECC_INT_EN        0x00000004 /* Enable ICR bit 5 for ECC */
+
 /*
  * This defines the bits that are set in the Interrupt Mask
  * Set/Read Register.  Each bit is documented below:
index f66ed37a7f766484e59a91bab9b3565fa34f7555..c4ffd4b705170d8d4d2c879dcdd7869c14946347 100644 (file)
@@ -87,6 +87,7 @@ enum e1e_registers {
        E1000_EEMNGCTL = 0x01010, /* MNG EEprom Control */
        E1000_EEWR     = 0x0102C, /* EEPROM Write Register - RW */
        E1000_FLOP     = 0x0103C, /* FLASH Opcode Register */
+       E1000_PBA_ECC  = 0x01100, /* PBA ECC Register */
        E1000_ERT      = 0x02008, /* Early Rx Threshold - RW */
        E1000_FCRTL    = 0x02160, /* Flow Control Receive Threshold Low - RW */
        E1000_FCRTH    = 0x02168, /* Flow Control Receive Threshold High - RW */
index 91795f78c3e4da0a067378cdc757d8ddb32c138b..4f06641cd6d49413b5b35011bb0953934fad9dea 100644 (file)
@@ -103,8 +103,6 @@ static void e1000_receive_skb(struct e1000_adapter *adapter,
                                         le16_to_cpu(vlan));
        else
                netif_receive_skb(skb);
-
-       netdev->last_rx = jiffies;
 }
 
 /**
@@ -2004,8 +2002,7 @@ static int e1000_clean(struct napi_struct *napi, int budget)
        struct net_device *poll_dev = adapter->netdev;
        int tx_cleaned = 0, work_done = 0;
 
-       /* Must NOT use netdev_priv macro here. */
-       adapter = poll_dev->priv;
+       adapter = netdev_priv(poll_dev);
 
        if (adapter->msix_entries &&
            !(adapter->rx_ring->ims_val & adapter->tx_ring->ims_val))
@@ -4670,14 +4667,12 @@ static void e1000_print_device_info(struct e1000_adapter *adapter)
        u32 pba_num;
 
        /* print bus type/speed/width info */
-       e_info("(PCI Express:2.5GB/s:%s) %02x:%02x:%02x:%02x:%02x:%02x\n",
+       e_info("(PCI Express:2.5GB/s:%s) %pM\n",
               /* bus width */
               ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
                "Width x1"),
               /* MAC address */
-              netdev->dev_addr[0], netdev->dev_addr[1],
-              netdev->dev_addr[2], netdev->dev_addr[3],
-              netdev->dev_addr[4], netdev->dev_addr[5]);
+              netdev->dev_addr);
        e_info("Intel(R) PRO/%s Network Connection\n",
               (hw->phy.type == e1000_phy_ife) ? "10/100" : "1000");
        e1000e_read_pba_num(hw, &pba_num);
@@ -4925,10 +4920,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
 
        if (!is_valid_ether_addr(netdev->perm_addr)) {
-               e_err("Invalid MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
-                     netdev->perm_addr[0], netdev->perm_addr[1],
-                     netdev->perm_addr[2], netdev->perm_addr[3],
-                     netdev->perm_addr[4], netdev->perm_addr[5]);
+               e_err("Invalid MAC Address: %pM\n", netdev->perm_addr);
                err = -EIO;
                goto err_eeprom;
        }
index 1f11350e16cf24b6a1a25d44ab9f8c41d4481a79..0a984619411b563c41fa4219700bdfb1c0ddddd3 100644 (file)
@@ -605,7 +605,7 @@ out:
 
 static void __init printEEPROMInfo(struct net_device *dev)
 {
-       struct eepro_local *lp = (struct eepro_local *)dev->priv;
+       struct eepro_local *lp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
        unsigned short Word;
        int i,j;
@@ -690,7 +690,6 @@ static void __init eepro_print_info (struct net_device *dev)
        struct eepro_local *    lp = netdev_priv(dev);
        int                     i;
        const char *            ifmap[] = {"AUI", "10Base2", "10BaseT"};
-       DECLARE_MAC_BUF(mac);
 
        i = inb(dev->base_addr + ID_REG);
        printk(KERN_DEBUG " id: %#x ",i);
@@ -715,7 +714,7 @@ static void __init eepro_print_info (struct net_device *dev)
                        break;
        }
 
-       printk(" %s", print_mac(mac, dev->dev_addr));
+       printk(" %pM", dev->dev_addr);
 
        if (net_debug > 3)
                printk(KERN_DEBUG ", %dK RCV buffer",
@@ -1581,7 +1580,6 @@ eepro_rx(struct net_device *dev)
 
                        skb->protocol = eth_type_trans(skb,dev);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                }
 
@@ -1676,7 +1674,7 @@ eepro_transmit_interrupt(struct net_device *dev)
 static int eepro_ethtool_get_settings(struct net_device *dev,
                                        struct ethtool_cmd *cmd)
 {
-       struct eepro_local      *lp = (struct eepro_local *)dev->priv;
+       struct eepro_local      *lp = netdev_priv(dev);
 
        cmd->supported =        SUPPORTED_10baseT_Half |
                                SUPPORTED_10baseT_Full |
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
deleted file mode 100644 (file)
index e3e26c5..0000000
+++ /dev/null
@@ -1,2401 +0,0 @@
-/* drivers/net/eepro100.c: An Intel i82557-559 Ethernet driver for Linux. */
-/*
-       Written 1996-1999 by Donald Becker.
-
-       The driver also contains updates by different kernel developers
-       (see incomplete list below).
-       Current maintainer is Andrey V. Savochkin <saw@saw.sw.com.sg>.
-       Please use this email address and linux-kernel mailing list for bug reports.
-
-       This software may be used and distributed according to the terms
-       of the GNU General Public License, incorporated herein by reference.
-
-       This driver is for the Intel EtherExpress Pro100 (Speedo3) design.
-       It should work with all i82557/558/559 boards.
-
-       Version history:
-       1998 Apr - 2000 Feb  Andrey V. Savochkin <saw@saw.sw.com.sg>
-               Serious fixes for multicast filter list setting, TX timeout routine;
-               RX ring refilling logic;  other stuff
-       2000 Feb  Jeff Garzik <jgarzik@pobox.com>
-               Convert to new PCI driver interface
-       2000 Mar 24  Dragan Stancevic <visitor@valinux.com>
-               Disabled FC and ER, to avoid lockups when when we get FCP interrupts.
-       2000 Jul 17 Goutham Rao <goutham.rao@intel.com>
-               PCI DMA API fixes, adding pci_dma_sync_single calls where neccesary
-       2000 Aug 31 David Mosberger <davidm@hpl.hp.com>
-               rx_align support: enables rx DMA without causing unaligned accesses.
-*/
-
-static const char * const version =
-"eepro100.c:v1.09j-t 9/29/99 Donald Becker\n"
-"eepro100.c: $Revision: 1.36 $ 2000/11/17 Modified by Andrey V. Savochkin <saw@saw.sw.com.sg> and others\n";
-
-/* A few user-configurable values that apply to all boards.
-   First set is undocumented and spelled per Intel recommendations. */
-
-static int congenb /* = 0 */; /* Enable congestion control in the DP83840. */
-static int txfifo = 8;         /* Tx FIFO threshold in 4 byte units, 0-15 */
-static int rxfifo = 8;         /* Rx FIFO threshold, default 32 bytes. */
-/* Tx/Rx DMA burst length, 0-127, 0 == no preemption, tx==128 -> disabled. */
-static int txdmacount = 128;
-static int rxdmacount /* = 0 */;
-
-#if defined(__ia64__) || defined(__alpha__) || defined(__sparc__) || defined(__mips__) || \
-       defined(__arm__)
-  /* align rx buffers to 2 bytes so that IP header is aligned */
-# define rx_align(skb)         skb_reserve((skb), 2)
-# define RxFD_ALIGNMENT                __attribute__ ((aligned (2), packed))
-#else
-# define rx_align(skb)
-# define RxFD_ALIGNMENT
-#endif
-
-/* Set the copy breakpoint for the copy-only-tiny-buffer Rx method.
-   Lower values use more memory, but are faster. */
-static int rx_copybreak = 200;
-
-/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
-static int max_interrupt_work = 20;
-
-/* Maximum number of multicast addresses to filter (vs. rx-all-multicast) */
-static int multicast_filter_limit = 64;
-
-/* 'options' is used to pass a transceiver override or full-duplex flag
-   e.g. "options=16" for FD, "options=32" for 100mbps-only. */
-static int full_duplex[] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1};
-
-/* A few values that may be tweaked. */
-/* The ring sizes should be a power of two for efficiency. */
-#define TX_RING_SIZE   64
-#define RX_RING_SIZE   64
-/* How much slots multicast filter setup may take.
-   Do not descrease without changing set_rx_mode() implementaion. */
-#define TX_MULTICAST_SIZE   2
-#define TX_MULTICAST_RESERV (TX_MULTICAST_SIZE*2)
-/* Actual number of TX packets queued, must be
-   <= TX_RING_SIZE-TX_MULTICAST_RESERV. */
-#define TX_QUEUE_LIMIT  (TX_RING_SIZE-TX_MULTICAST_RESERV)
-/* Hysteresis marking queue as no longer full. */
-#define TX_QUEUE_UNFULL (TX_QUEUE_LIMIT-4)
-
-/* Operational parameters that usually are not changed. */
-
-/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT             (2*HZ)
-/* Size of an pre-allocated Rx buffer: <Ethernet MTU> + slack.*/
-#define PKT_BUF_SZ             1536
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/mii.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/irq.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/rtnetlink.h>
-#include <linux/skbuff.h>
-#include <linux/ethtool.h>
-
-static int use_io;
-static int debug = -1;
-#define DEBUG_DEFAULT          (NETIF_MSG_DRV          | \
-                                NETIF_MSG_HW           | \
-                                NETIF_MSG_RX_ERR       | \
-                                NETIF_MSG_TX_ERR)
-#define DEBUG                  ((debug >= 0) ? (1<<debug)-1 : DEBUG_DEFAULT)
-
-
-MODULE_AUTHOR("Maintainer: Andrey V. Savochkin <saw@saw.sw.com.sg>");
-MODULE_DESCRIPTION("Intel i82557/i82558/i82559 PCI EtherExpressPro driver");
-MODULE_LICENSE("GPL");
-module_param(use_io, int, 0);
-module_param(debug, int, 0);
-module_param_array(options, int, NULL, 0);
-module_param_array(full_duplex, int, NULL, 0);
-module_param(congenb, int, 0);
-module_param(txfifo, int, 0);
-module_param(rxfifo, int, 0);
-module_param(txdmacount, int, 0);
-module_param(rxdmacount, int, 0);
-module_param(rx_copybreak, int, 0);
-module_param(max_interrupt_work, int, 0);
-module_param(multicast_filter_limit, int, 0);
-MODULE_PARM_DESC(debug, "debug level (0-6)");
-MODULE_PARM_DESC(options, "Bits 0-3: transceiver type, bit 4: full duplex, bit 5: 100Mbps");
-MODULE_PARM_DESC(full_duplex, "full duplex setting(s) (1)");
-MODULE_PARM_DESC(congenb, "Enable congestion control (1)");
-MODULE_PARM_DESC(txfifo, "Tx FIFO threshold in 4 byte units, (0-15)");
-MODULE_PARM_DESC(rxfifo, "Rx FIFO threshold in 4 byte units, (0-15)");
-MODULE_PARM_DESC(txdmacount, "Tx DMA burst length; 128 - disable (0-128)");
-MODULE_PARM_DESC(rxdmacount, "Rx DMA burst length; 128 - disable (0-128)");
-MODULE_PARM_DESC(rx_copybreak, "copy breakpoint for copy-only-tiny-frames");
-MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt");
-MODULE_PARM_DESC(multicast_filter_limit, "maximum number of filtered multicast addresses");
-
-#define RUN_AT(x) (jiffies + (x))
-
-#define netdevice_start(dev)
-#define netdevice_stop(dev)
-#define netif_set_tx_timeout(dev, tf, tm) \
-                                                               do { \
-                                                                       (dev)->tx_timeout = (tf); \
-                                                                       (dev)->watchdog_timeo = (tm); \
-                                                               } while(0)
-
-
-
-/*
-                               Theory of Operation
-
-I. Board Compatibility
-
-This device driver is designed for the Intel i82557 "Speedo3" chip, Intel's
-single-chip fast Ethernet controller for PCI, as used on the Intel
-EtherExpress Pro 100 adapter.
-
-II. Board-specific settings
-
-PCI bus devices are configured by the system at boot time, so no jumpers
-need to be set on the board.  The system BIOS should be set to assign the
-PCI INTA signal to an otherwise unused system IRQ line.  While it's
-possible to share PCI interrupt lines, it negatively impacts performance and
-only recent kernels support it.
-
-III. Driver operation
-
-IIIA. General
-The Speedo3 is very similar to other Intel network chips, that is to say
-"apparently designed on a different planet".  This chips retains the complex
-Rx and Tx descriptors and multiple buffers pointers as previous chips, but
-also has simplified Tx and Rx buffer modes.  This driver uses the "flexible"
-Tx mode, but in a simplified lower-overhead manner: it associates only a
-single buffer descriptor with each frame descriptor.
-
-Despite the extra space overhead in each receive skbuff, the driver must use
-the simplified Rx buffer mode to assure that only a single data buffer is
-associated with each RxFD. The driver implements this by reserving space
-for the Rx descriptor at the head of each Rx skbuff.
-
-The Speedo-3 has receive and command unit base addresses that are added to
-almost all descriptor pointers.  The driver sets these to zero, so that all
-pointer fields are absolute addresses.
-
-The System Control Block (SCB) of some previous Intel chips exists on the
-chip in both PCI I/O and memory space.  This driver uses the I/O space
-registers, but might switch to memory mapped mode to better support non-x86
-processors.
-
-IIIB. Transmit structure
-
-The driver must use the complex Tx command+descriptor mode in order to
-have a indirect pointer to the skbuff data section.  Each Tx command block
-(TxCB) is associated with two immediately appended Tx Buffer Descriptor
-(TxBD).  A fixed ring of these TxCB+TxBD pairs are kept as part of the
-speedo_private data structure for each adapter instance.
-
-The newer i82558 explicitly supports this structure, and can read the two
-TxBDs in the same PCI burst as the TxCB.
-
-This ring structure is used for all normal transmit packets, but the
-transmit packet descriptors aren't long enough for most non-Tx commands such
-as CmdConfigure.  This is complicated by the possibility that the chip has
-already loaded the link address in the previous descriptor.  So for these
-commands we convert the next free descriptor on the ring to a NoOp, and point
-that descriptor's link to the complex command.
-
-An additional complexity of these non-transmit commands are that they may be
-added asynchronous to the normal transmit queue, so we disable interrupts
-whenever the Tx descriptor ring is manipulated.
-
-A notable aspect of these special configure commands is that they do
-work with the normal Tx ring entry scavenge method.  The Tx ring scavenge
-is done at interrupt time using the 'dirty_tx' index, and checking for the
-command-complete bit.  While the setup frames may have the NoOp command on the
-Tx ring marked as complete, but not have completed the setup command, this
-is not a problem.  The tx_ring entry can be still safely reused, as the
-tx_skbuff[] entry is always empty for config_cmd and mc_setup frames.
-
-Commands may have bits set e.g. CmdSuspend in the command word to either
-suspend or stop the transmit/command unit.  This driver always flags the last
-command with CmdSuspend, erases the CmdSuspend in the previous command, and
-then issues a CU_RESUME.
-Note: Watch out for the potential race condition here: imagine
-       erasing the previous suspend
-               the chip processes the previous command
-               the chip processes the final command, and suspends
-       doing the CU_RESUME
-               the chip processes the next-yet-valid post-final-command.
-So blindly sending a CU_RESUME is only safe if we do it immediately after
-after erasing the previous CmdSuspend, without the possibility of an
-intervening delay.  Thus the resume command is always within the
-interrupts-disabled region.  This is a timing dependence, but handling this
-condition in a timing-independent way would considerably complicate the code.
-
-Note: In previous generation Intel chips, restarting the command unit was a
-notoriously slow process.  This is presumably no longer true.
-
-IIIC. Receive structure
-
-Because of the bus-master support on the Speedo3 this driver uses the new
-SKBUFF_RX_COPYBREAK scheme, rather than a fixed intermediate receive buffer.
-This scheme allocates full-sized skbuffs as receive buffers.  The value
-SKBUFF_RX_COPYBREAK is used as the copying breakpoint: it is chosen to
-trade-off the memory wasted by passing the full-sized skbuff to the queue
-layer for all frames vs. the copying cost of copying a frame to a
-correctly-sized skbuff.
-
-For small frames the copying cost is negligible (esp. considering that we
-are pre-loading the cache with immediately useful header information), so we
-allocate a new, minimally-sized skbuff.  For large frames the copying cost
-is non-trivial, and the larger copy might flush the cache of useful data, so
-we pass up the skbuff the packet was received into.
-
-IV. Notes
-
-Thanks to Steve Williams of Intel for arranging the non-disclosure agreement
-that stated that I could disclose the information.  But I still resent
-having to sign an Intel NDA when I'm helping Intel sell their own product!
-
-*/
-
-static int speedo_found1(struct pci_dev *pdev, void __iomem *ioaddr, int fnd_cnt, int acpi_idle_state);
-
-/* Offsets to the various registers.
-   All accesses need not be longword aligned. */
-enum speedo_offsets {
-       SCBStatus = 0, SCBCmd = 2,      /* Rx/Command Unit command and status. */
-       SCBIntmask = 3,
-       SCBPointer = 4,                         /* General purpose pointer. */
-       SCBPort = 8,                            /* Misc. commands and operands.  */
-       SCBflash = 12, SCBeeprom = 14, /* EEPROM and flash memory control. */
-       SCBCtrlMDI = 16,                        /* MDI interface control. */
-       SCBEarlyRx = 20,                        /* Early receive byte count. */
-};
-/* Commands that can be put in a command list entry. */
-enum commands {
-       CmdNOp = 0, CmdIASetup = 0x10000, CmdConfigure = 0x20000,
-       CmdMulticastList = 0x30000, CmdTx = 0x40000, CmdTDR = 0x50000,
-       CmdDump = 0x60000, CmdDiagnose = 0x70000,
-       CmdSuspend = 0x40000000,        /* Suspend after completion. */
-       CmdIntr = 0x20000000,           /* Interrupt after completion. */
-       CmdTxFlex = 0x00080000,         /* Use "Flexible mode" for CmdTx command. */
-};
-/* Clear CmdSuspend (1<<30) avoiding interference with the card access to the
-   status bits.  Previous driver versions used separate 16 bit fields for
-   commands and statuses.  --SAW
- */
-#if defined(__alpha__)
-# define clear_suspend(cmd)  clear_bit(30, &(cmd)->cmd_status);
-#else
-# define clear_suspend(cmd)  ((__le16 *)&(cmd)->cmd_status)[1] &= ~cpu_to_le16(1<<14)
-#endif
-
-enum SCBCmdBits {
-       SCBMaskCmdDone=0x8000, SCBMaskRxDone=0x4000, SCBMaskCmdIdle=0x2000,
-       SCBMaskRxSuspend=0x1000, SCBMaskEarlyRx=0x0800, SCBMaskFlowCtl=0x0400,
-       SCBTriggerIntr=0x0200, SCBMaskAll=0x0100,
-       /* The rest are Rx and Tx commands. */
-       CUStart=0x0010, CUResume=0x0020, CUStatsAddr=0x0040, CUShowStats=0x0050,
-       CUCmdBase=0x0060,       /* CU Base address (set to zero) . */
-       CUDumpStats=0x0070, /* Dump then reset stats counters. */
-       RxStart=0x0001, RxResume=0x0002, RxAbort=0x0004, RxAddrLoad=0x0006,
-       RxResumeNoResources=0x0007,
-};
-
-enum SCBPort_cmds {
-       PortReset=0, PortSelfTest=1, PortPartialReset=2, PortDump=3,
-};
-
-/* The Speedo3 Rx and Tx frame/buffer descriptors. */
-struct descriptor {                        /* A generic descriptor. */
-       volatile __le32 cmd_status;     /* All command and status fields. */
-       __le32 link;                                /* struct descriptor *  */
-       unsigned char params[0];
-};
-
-/* The Speedo3 Rx and Tx buffer descriptors. */
-struct RxFD {                                  /* Receive frame descriptor. */
-       volatile __le32 status;
-       __le32 link;                                    /* struct RxFD * */
-       __le32 rx_buf_addr;                     /* void * */
-       __le32 count;
-} RxFD_ALIGNMENT;
-
-/* Selected elements of the Tx/RxFD.status word. */
-enum RxFD_bits {
-       RxComplete=0x8000, RxOK=0x2000,
-       RxErrCRC=0x0800, RxErrAlign=0x0400, RxErrTooBig=0x0200, RxErrSymbol=0x0010,
-       RxEth2Type=0x0020, RxNoMatch=0x0004, RxNoIAMatch=0x0002,
-       TxUnderrun=0x1000,  StatusComplete=0x8000,
-};
-
-#define CONFIG_DATA_SIZE 22
-struct TxFD {                                  /* Transmit frame descriptor set. */
-       __le32 status;
-       __le32 link;                                    /* void * */
-       __le32 tx_desc_addr;                    /* Always points to the tx_buf_addr element. */
-       __le32 count;                                   /* # of TBD (=1), Tx start thresh., etc. */
-       /* This constitutes two "TBD" entries -- we only use one. */
-#define TX_DESCR_BUF_OFFSET 16
-       __le32 tx_buf_addr0;                    /* void *, frame to be transmitted.  */
-       __le32 tx_buf_size0;                    /* Length of Tx frame. */
-       __le32 tx_buf_addr1;                    /* void *, frame to be transmitted.  */
-       __le32 tx_buf_size1;                    /* Length of Tx frame. */
-       /* the structure must have space for at least CONFIG_DATA_SIZE starting
-        * from tx_desc_addr field */
-};
-
-/* Multicast filter setting block.  --SAW */
-struct speedo_mc_block {
-       struct speedo_mc_block *next;
-       unsigned int tx;
-       dma_addr_t frame_dma;
-       unsigned int len;
-       struct descriptor frame __attribute__ ((__aligned__(16)));
-};
-
-/* Elements of the dump_statistics block. This block must be lword aligned. */
-struct speedo_stats {
-       __le32 tx_good_frames;
-       __le32 tx_coll16_errs;
-       __le32 tx_late_colls;
-       __le32 tx_underruns;
-       __le32 tx_lost_carrier;
-       __le32 tx_deferred;
-       __le32 tx_one_colls;
-       __le32 tx_multi_colls;
-       __le32 tx_total_colls;
-       __le32 rx_good_frames;
-       __le32 rx_crc_errs;
-       __le32 rx_align_errs;
-       __le32 rx_resource_errs;
-       __le32 rx_overrun_errs;
-       __le32 rx_colls_errs;
-       __le32 rx_runt_errs;
-       __le32 done_marker;
-};
-
-enum Rx_ring_state_bits {
-       RrNoMem=1, RrPostponed=2, RrNoResources=4, RrOOMReported=8,
-};
-
-/* Do not change the position (alignment) of the first few elements!
-   The later elements are grouped for cache locality.
-
-   Unfortunately, all the positions have been shifted since there.
-   A new re-alignment is required.  2000/03/06  SAW */
-struct speedo_private {
-    void __iomem *regs;
-       struct TxFD     *tx_ring;               /* Commands (usually CmdTxPacket). */
-       struct RxFD *rx_ringp[RX_RING_SIZE];    /* Rx descriptor, used as ring. */
-       /* The addresses of a Tx/Rx-in-place packets/buffers. */
-       struct sk_buff *tx_skbuff[TX_RING_SIZE];
-       struct sk_buff *rx_skbuff[RX_RING_SIZE];
-       /* Mapped addresses of the rings. */
-       dma_addr_t tx_ring_dma;
-#define TX_RING_ELEM_DMA(sp, n) ((sp)->tx_ring_dma + (n)*sizeof(struct TxFD))
-       dma_addr_t rx_ring_dma[RX_RING_SIZE];
-       struct descriptor *last_cmd;            /* Last command sent. */
-       unsigned int cur_tx, dirty_tx;          /* The ring entries to be free()ed. */
-       spinlock_t lock;                        /* Group with Tx control cache line. */
-       u32 tx_threshold;                       /* The value for txdesc.count. */
-       struct RxFD *last_rxf;                  /* Last filled RX buffer. */
-       dma_addr_t last_rxf_dma;
-       unsigned int cur_rx, dirty_rx;          /* The next free ring entry */
-       long last_rx_time;                      /* Last Rx, in jiffies, to handle Rx hang. */
-       struct net_device_stats stats;
-       struct speedo_stats *lstats;
-       dma_addr_t lstats_dma;
-       int chip_id;
-       struct pci_dev *pdev;
-       struct timer_list timer;                /* Media selection timer. */
-       struct speedo_mc_block *mc_setup_head;  /* Multicast setup frame list head. */
-       struct speedo_mc_block *mc_setup_tail;  /* Multicast setup frame list tail. */
-       long in_interrupt;                      /* Word-aligned dev->interrupt */
-       unsigned char acpi_pwr;
-       signed char rx_mode;                    /* Current PROMISC/ALLMULTI setting. */
-       unsigned int tx_full:1;                 /* The Tx queue is full. */
-       unsigned int flow_ctrl:1;               /* Use 802.3x flow control. */
-       unsigned int rx_bug:1;                  /* Work around receiver hang errata. */
-       unsigned char default_port:8;           /* Last dev->if_port value. */
-       unsigned char rx_ring_state;            /* RX ring status flags. */
-       unsigned short phy[2];                  /* PHY media interfaces available. */
-       unsigned short partner;                 /* Link partner caps. */
-       struct mii_if_info mii_if;              /* MII API hooks, info */
-       u32 msg_enable;                         /* debug message level */
-};
-
-/* The parameters for a CmdConfigure operation.
-   There are so many options that it would be difficult to document each bit.
-   We mostly use the default or recommended settings. */
-static const char i82557_config_cmd[CONFIG_DATA_SIZE] = {
-       22, 0x08, 0, 0,  0, 0, 0x32, 0x03,  1, /* 1=Use MII  0=Use AUI */
-       0, 0x2E, 0,  0x60, 0,
-       0xf2, 0x48,   0, 0x40, 0xf2, 0x80,              /* 0x40=Force full-duplex */
-       0x3f, 0x05, };
-static const char i82558_config_cmd[CONFIG_DATA_SIZE] = {
-       22, 0x08, 0, 1,  0, 0, 0x22, 0x03,  1, /* 1=Use MII  0=Use AUI */
-       0, 0x2E, 0,  0x60, 0x08, 0x88,
-       0x68, 0, 0x40, 0xf2, 0x84,              /* Disable FC */
-       0x31, 0x05, };
-
-/* PHY media interface chips. */
-static const char * const phys[] = {
-       "None", "i82553-A/B", "i82553-C", "i82503",
-       "DP83840", "80c240", "80c24", "i82555",
-       "unknown-8", "unknown-9", "DP83840A", "unknown-11",
-       "unknown-12", "unknown-13", "unknown-14", "unknown-15", };
-enum phy_chips { NonSuchPhy=0, I82553AB, I82553C, I82503, DP83840, S80C240,
-                                        S80C24, I82555, DP83840A=10, };
-static const char is_mii[] = { 0, 1, 1, 0, 1, 1, 0, 1 };
-#define EE_READ_CMD            (6)
-
-static int eepro100_init_one(struct pci_dev *pdev,
-               const struct pci_device_id *ent);
-
-static int do_eeprom_cmd(void __iomem *ioaddr, int cmd, int cmd_len);
-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 speedo_open(struct net_device *dev);
-static void speedo_resume(struct net_device *dev);
-static void speedo_timer(unsigned long data);
-static void speedo_init_rx_ring(struct net_device *dev);
-static void speedo_tx_timeout(struct net_device *dev);
-static int speedo_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static void speedo_refill_rx_buffers(struct net_device *dev, int force);
-static int speedo_rx(struct net_device *dev);
-static void speedo_tx_buffer_gc(struct net_device *dev);
-static irqreturn_t speedo_interrupt(int irq, void *dev_instance);
-static int speedo_close(struct net_device *dev);
-static struct net_device_stats *speedo_get_stats(struct net_device *dev);
-static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static void set_rx_mode(struct net_device *dev);
-static void speedo_show_state(struct net_device *dev);
-static const struct ethtool_ops ethtool_ops;
-
-
-
-#ifdef honor_default_port
-/* Optional driver feature to allow forcing the transceiver setting.
-   Not recommended. */
-static int mii_ctrl[8] = { 0x3300, 0x3100, 0x0000, 0x0100,
-                                                  0x2000, 0x2100, 0x0400, 0x3100};
-#endif
-
-/* How to wait for the command unit to accept a command.
-   Typically this takes 0 ticks. */
-static inline unsigned char wait_for_cmd_done(struct net_device *dev,
-                                                                                               struct speedo_private *sp)
-{
-       int wait = 1000;
-       void __iomem *cmd_ioaddr = sp->regs + SCBCmd;
-       unsigned char r;
-
-       do  {
-               udelay(1);
-               r = ioread8(cmd_ioaddr);
-       } while(r && --wait >= 0);
-
-       if (wait < 0)
-               printk(KERN_ALERT "%s: wait_for_cmd_done timeout!\n", dev->name);
-       return r;
-}
-
-static int __devinit eepro100_init_one (struct pci_dev *pdev,
-               const struct pci_device_id *ent)
-{
-       void __iomem *ioaddr;
-       int irq, pci_bar;
-       int acpi_idle_state = 0, pm;
-       static int cards_found /* = 0 */;
-       unsigned long pci_base;
-
-#ifndef MODULE
-       /* when built-in, we only print version if device is found */
-       static int did_version;
-       if (did_version++ == 0)
-               printk(version);
-#endif
-
-       /* save power state before pci_enable_device overwrites it */
-       pm = pci_find_capability(pdev, PCI_CAP_ID_PM);
-       if (pm) {
-               u16 pwr_command;
-               pci_read_config_word(pdev, pm + PCI_PM_CTRL, &pwr_command);
-               acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
-       }
-
-       if (pci_enable_device(pdev))
-               goto err_out_free_mmio_region;
-
-       pci_set_master(pdev);
-
-       if (!request_region(pci_resource_start(pdev, 1),
-                       pci_resource_len(pdev, 1), "eepro100")) {
-               dev_err(&pdev->dev, "eepro100: cannot reserve I/O ports\n");
-               goto err_out_none;
-       }
-       if (!request_mem_region(pci_resource_start(pdev, 0),
-                       pci_resource_len(pdev, 0), "eepro100")) {
-               dev_err(&pdev->dev, "eepro100: cannot reserve MMIO region\n");
-               goto err_out_free_pio_region;
-       }
-
-       irq = pdev->irq;
-       pci_bar = use_io ? 1 : 0;
-       pci_base = pci_resource_start(pdev, pci_bar);
-       if (DEBUG & NETIF_MSG_PROBE)
-               printk("Found Intel i82557 PCI Speedo at %#lx, IRQ %d.\n",
-                      pci_base, irq);
-
-       ioaddr = pci_iomap(pdev, pci_bar, 0);
-       if (!ioaddr) {
-               dev_err(&pdev->dev, "eepro100: cannot remap IO\n");
-               goto err_out_free_mmio_region;
-       }
-
-       if (speedo_found1(pdev, ioaddr, cards_found, acpi_idle_state) == 0)
-               cards_found++;
-       else
-               goto err_out_iounmap;
-
-       return 0;
-
-err_out_iounmap: ;
-       pci_iounmap(pdev, ioaddr);
-err_out_free_mmio_region:
-       release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
-err_out_free_pio_region:
-       release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1));
-err_out_none:
-       return -ENODEV;
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/*
- * Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
-
-static void poll_speedo (struct net_device *dev)
-{
-       /* disable_irq is not very nice, but with the funny lockless design
-          we have no other choice. */
-       disable_irq(dev->irq);
-       speedo_interrupt (dev->irq, dev);
-       enable_irq(dev->irq);
-}
-#endif
-
-static int __devinit speedo_found1(struct pci_dev *pdev,
-               void __iomem *ioaddr, int card_idx, int acpi_idle_state)
-{
-       struct net_device *dev;
-       struct speedo_private *sp;
-       const char *product;
-       int i, option;
-       u16 eeprom[0x100];
-       int size;
-       void *tx_ring_space;
-       dma_addr_t tx_ring_dma;
-       DECLARE_MAC_BUF(mac);
-
-       size = TX_RING_SIZE * sizeof(struct TxFD) + sizeof(struct speedo_stats);
-       tx_ring_space = pci_alloc_consistent(pdev, size, &tx_ring_dma);
-       if (tx_ring_space == NULL)
-               return -1;
-
-       dev = alloc_etherdev(sizeof(struct speedo_private));
-       if (dev == NULL) {
-               printk(KERN_ERR "eepro100: Could not allocate ethernet device.\n");
-               pci_free_consistent(pdev, size, tx_ring_space, tx_ring_dma);
-               return -1;
-       }
-
-       SET_NETDEV_DEV(dev, &pdev->dev);
-
-       if (dev->mem_start > 0)
-               option = dev->mem_start;
-       else if (card_idx >= 0  &&  options[card_idx] >= 0)
-               option = options[card_idx];
-       else
-               option = 0;
-
-       rtnl_lock();
-       if (dev_alloc_name(dev, dev->name) < 0)
-               goto err_free_unlock;
-
-       /* Read the station address EEPROM before doing the reset.
-          Nominally his should even be done before accepting the device, but
-          then we wouldn't have a device name with which to report the error.
-          The size test is for 6 bit vs. 8 bit address serial EEPROMs.
-       */
-       {
-               void __iomem *iobase;
-               int read_cmd, ee_size;
-               u16 sum;
-               int j;
-
-               /* Use IO only to avoid postponed writes and satisfy EEPROM timing
-                  requirements. */
-               iobase = pci_iomap(pdev, 1, pci_resource_len(pdev, 1));
-               if (!iobase)
-                       goto err_free_unlock;
-               if ((do_eeprom_cmd(iobase, EE_READ_CMD << 24, 27) & 0xffe0000)
-                       == 0xffe0000) {
-                       ee_size = 0x100;
-                       read_cmd = EE_READ_CMD << 24;
-               } else {
-                       ee_size = 0x40;
-                       read_cmd = EE_READ_CMD << 22;
-               }
-
-               for (j = 0, i = 0, sum = 0; i < ee_size; i++) {
-                       u16 value = do_eeprom_cmd(iobase, read_cmd | (i << 16), 27);
-                       eeprom[i] = value;
-                       sum += value;
-                       if (i < 3) {
-                               dev->dev_addr[j++] = value;
-                               dev->dev_addr[j++] = value >> 8;
-                       }
-               }
-               if (sum != 0xBABA)
-                       printk(KERN_WARNING "%s: Invalid EEPROM checksum %#4.4x, "
-                                  "check settings before activating this device!\n",
-                                  dev->name, sum);
-               /* Don't  unregister_netdev(dev);  as the EEPro may actually be
-                  usable, especially if the MAC address is set later.
-                  On the other hand, it may be unusable if MDI data is corrupted. */
-
-               pci_iounmap(pdev, iobase);
-       }
-
-       /* Reset the chip: stop Tx and Rx processes and clear counters.
-          This takes less than 10usec and will easily finish before the next
-          action. */
-       iowrite32(PortReset, ioaddr + SCBPort);
-       ioread32(ioaddr + SCBPort);
-       udelay(10);
-
-       if (eeprom[3] & 0x0100)
-               product = "OEM i82557/i82558 10/100 Ethernet";
-       else
-               product = pci_name(pdev);
-
-       printk(KERN_INFO "%s: %s, %s, IRQ %d.\n", dev->name, product,
-                  print_mac(mac, dev->dev_addr), pdev->irq);
-
-       sp = netdev_priv(dev);
-
-       /* we must initialize this early, for mdio_{read,write} */
-       sp->regs = ioaddr;
-
-#if 1 || defined(kernel_bloat)
-       /* OK, this is pure kernel bloat.  I don't like it when other drivers
-          waste non-pageable kernel space to emit similar messages, but I need
-          them for bug reports. */
-       {
-               const char *connectors[] = {" RJ45", " BNC", " AUI", " MII"};
-               /* The self-test results must be paragraph aligned. */
-               volatile s32 *self_test_results;
-               int boguscnt = 16000;   /* Timeout for set-test. */
-               if ((eeprom[3] & 0x03) != 0x03)
-                       printk(KERN_INFO "  Receiver lock-up bug exists -- enabling"
-                                  " work-around.\n");
-               printk(KERN_INFO "  Board assembly %4.4x%2.2x-%3.3d, Physical"
-                          " connectors present:",
-                          eeprom[8], eeprom[9]>>8, eeprom[9] & 0xff);
-               for (i = 0; i < 4; i++)
-                       if (eeprom[5] & (1<<i))
-                               printk(connectors[i]);
-               printk("\n"KERN_INFO"  Primary interface chip %s PHY #%d.\n",
-                          phys[(eeprom[6]>>8)&15], eeprom[6] & 0x1f);
-               if (eeprom[7] & 0x0700)
-                       printk(KERN_INFO "    Secondary interface chip %s.\n",
-                                  phys[(eeprom[7]>>8)&7]);
-               if (((eeprom[6]>>8) & 0x3f) == DP83840
-                       ||  ((eeprom[6]>>8) & 0x3f) == DP83840A) {
-                       int mdi_reg23 = mdio_read(dev, eeprom[6] & 0x1f, 23) | 0x0422;
-                       if (congenb)
-                         mdi_reg23 |= 0x0100;
-                       printk(KERN_INFO"  DP83840 specific setup, setting register 23 to %4.4x.\n",
-                                  mdi_reg23);
-                       mdio_write(dev, eeprom[6] & 0x1f, 23, mdi_reg23);
-               }
-               if ((option >= 0) && (option & 0x70)) {
-                       printk(KERN_INFO "  Forcing %dMbs %s-duplex operation.\n",
-                                  (option & 0x20 ? 100 : 10),
-                                  (option & 0x10 ? "full" : "half"));
-                       mdio_write(dev, eeprom[6] & 0x1f, MII_BMCR,
-                                          ((option & 0x20) ? 0x2000 : 0) |     /* 100mbps? */
-                                          ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
-               }
-
-               /* Perform a system self-test. */
-               self_test_results = (s32*) ((((long) tx_ring_space) + 15) & ~0xf);
-               self_test_results[0] = 0;
-               self_test_results[1] = -1;
-               iowrite32(tx_ring_dma | PortSelfTest, ioaddr + SCBPort);
-               do {
-                       udelay(10);
-               } while (self_test_results[1] == -1  &&  --boguscnt >= 0);
-
-               if (boguscnt < 0) {             /* Test optimized out. */
-                       printk(KERN_ERR "Self test failed, status %8.8x:\n"
-                                  KERN_ERR " Failure to initialize the i82557.\n"
-                                  KERN_ERR " Verify that the card is a bus-master"
-                                  " capable slot.\n",
-                                  self_test_results[1]);
-               } else
-                       printk(KERN_INFO "  General self-test: %s.\n"
-                                  KERN_INFO "  Serial sub-system self-test: %s.\n"
-                                  KERN_INFO "  Internal registers self-test: %s.\n"
-                                  KERN_INFO "  ROM checksum self-test: %s (%#8.8x).\n",
-                                  self_test_results[1] & 0x1000 ? "failed" : "passed",
-                                  self_test_results[1] & 0x0020 ? "failed" : "passed",
-                                  self_test_results[1] & 0x0008 ? "failed" : "passed",
-                                  self_test_results[1] & 0x0004 ? "failed" : "passed",
-                                  self_test_results[0]);
-       }
-#endif  /* kernel_bloat */
-
-       iowrite32(PortReset, ioaddr + SCBPort);
-       ioread32(ioaddr + SCBPort);
-       udelay(10);
-
-       /* Return the chip to its original power state. */
-       pci_set_power_state(pdev, acpi_idle_state);
-
-       pci_set_drvdata (pdev, dev);
-       SET_NETDEV_DEV(dev, &pdev->dev);
-
-       dev->irq = pdev->irq;
-
-       sp->pdev = pdev;
-       sp->msg_enable = DEBUG;
-       sp->acpi_pwr = acpi_idle_state;
-       sp->tx_ring = tx_ring_space;
-       sp->tx_ring_dma = tx_ring_dma;
-       sp->lstats = (struct speedo_stats *)(sp->tx_ring + TX_RING_SIZE);
-       sp->lstats_dma = TX_RING_ELEM_DMA(sp, TX_RING_SIZE);
-       init_timer(&sp->timer); /* used in ioctl() */
-       spin_lock_init(&sp->lock);
-
-       sp->mii_if.full_duplex = option >= 0 && (option & 0x10) ? 1 : 0;
-       if (card_idx >= 0) {
-               if (full_duplex[card_idx] >= 0)
-                       sp->mii_if.full_duplex = full_duplex[card_idx];
-       }
-       sp->default_port = option >= 0 ? (option & 0x0f) : 0;
-
-       sp->phy[0] = eeprom[6];
-       sp->phy[1] = eeprom[7];
-
-       sp->mii_if.phy_id = eeprom[6] & 0x1f;
-       sp->mii_if.phy_id_mask = 0x1f;
-       sp->mii_if.reg_num_mask = 0x1f;
-       sp->mii_if.dev = dev;
-       sp->mii_if.mdio_read = mdio_read;
-       sp->mii_if.mdio_write = mdio_write;
-
-       sp->rx_bug = (eeprom[3] & 0x03) == 3 ? 0 : 1;
-       if (((pdev->device > 0x1030 && (pdev->device < 0x103F)))
-           || (pdev->device == 0x2449) || (pdev->device == 0x2459)
-            || (pdev->device == 0x245D)) {
-               sp->chip_id = 1;
-       }
-
-       if (sp->rx_bug)
-               printk(KERN_INFO "  Receiver lock-up workaround activated.\n");
-
-       /* The Speedo-specific entries in the device structure. */
-       dev->open = &speedo_open;
-       dev->hard_start_xmit = &speedo_start_xmit;
-       netif_set_tx_timeout(dev, &speedo_tx_timeout, TX_TIMEOUT);
-       dev->stop = &speedo_close;
-       dev->get_stats = &speedo_get_stats;
-       dev->set_multicast_list = &set_rx_mode;
-       dev->do_ioctl = &speedo_ioctl;
-       SET_ETHTOOL_OPS(dev, &ethtool_ops);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = &poll_speedo;
-#endif
-
-       if (register_netdevice(dev))
-               goto err_free_unlock;
-       rtnl_unlock();
-
-       return 0;
-
- err_free_unlock:
-       rtnl_unlock();
-       free_netdev(dev);
-       return -1;
-}
-
-static void do_slow_command(struct net_device *dev, struct speedo_private *sp, int cmd)
-{
-       void __iomem *cmd_ioaddr = sp->regs + SCBCmd;
-       int wait = 0;
-       do
-               if (ioread8(cmd_ioaddr) == 0) break;
-       while(++wait <= 200);
-       if (wait > 100)
-               printk(KERN_ERR "Command %4.4x never accepted (%d polls)!\n",
-                      ioread8(cmd_ioaddr), wait);
-
-       iowrite8(cmd, cmd_ioaddr);
-
-       for (wait = 0; wait <= 100; wait++)
-               if (ioread8(cmd_ioaddr) == 0) return;
-       for (; wait <= 20000; wait++)
-               if (ioread8(cmd_ioaddr) == 0) return;
-               else udelay(1);
-       printk(KERN_ERR "Command %4.4x was not accepted after %d polls!"
-              "  Current status %8.8x.\n",
-              cmd, wait, ioread32(sp->regs + SCBStatus));
-}
-
-/* Serial EEPROM section.
-   A "bit" grungy, but we work our way through bit-by-bit :->. */
-/*  EEPROM_Ctrl bits. */
-#define EE_SHIFT_CLK   0x01    /* EEPROM shift clock. */
-#define EE_CS                  0x02    /* EEPROM chip select. */
-#define EE_DATA_WRITE  0x04    /* EEPROM chip data in. */
-#define EE_DATA_READ   0x08    /* EEPROM chip data out. */
-#define EE_ENB                 (0x4800 | EE_CS)
-#define EE_WRITE_0             0x4802
-#define EE_WRITE_1             0x4806
-#define EE_OFFSET              SCBeeprom
-
-/* The fixes for the code were kindly provided by Dragan Stancevic
-   <visitor@valinux.com> to strictly follow Intel specifications of EEPROM
-   access timing.
-   The publicly available sheet 64486302 (sec. 3.1) specifies 1us access
-   interval for serial EEPROM.  However, it looks like that there is an
-   additional requirement dictating larger udelay's in the code below.
-   2000/05/24  SAW */
-static int __devinit do_eeprom_cmd(void __iomem *ioaddr, int cmd, int cmd_len)
-{
-       unsigned retval = 0;
-       void __iomem *ee_addr = ioaddr + SCBeeprom;
-
-       iowrite16(EE_ENB, ee_addr); udelay(2);
-       iowrite16(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2);
-
-       /* Shift the command bits out. */
-       do {
-               short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
-               iowrite16(dataval, ee_addr); udelay(2);
-               iowrite16(dataval | EE_SHIFT_CLK, ee_addr); udelay(2);
-               retval = (retval << 1) | ((ioread16(ee_addr) & EE_DATA_READ) ? 1 : 0);
-       } while (--cmd_len >= 0);
-       iowrite16(EE_ENB, ee_addr); udelay(2);
-
-       /* Terminate the EEPROM access. */
-       iowrite16(EE_ENB & ~EE_CS, ee_addr);
-       return retval;
-}
-
-static int mdio_read(struct net_device *dev, int phy_id, int location)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       void __iomem *ioaddr = sp->regs;
-       int val, boguscnt = 64*10;              /* <64 usec. to complete, typ 27 ticks */
-       iowrite32(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI);
-       do {
-               val = ioread32(ioaddr + SCBCtrlMDI);
-               if (--boguscnt < 0) {
-                       printk(KERN_ERR " mdio_read() timed out with val = %8.8x.\n", val);
-                       break;
-               }
-       } while (! (val & 0x10000000));
-       return val & 0xffff;
-}
-
-static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       void __iomem *ioaddr = sp->regs;
-       int val, boguscnt = 64*10;              /* <64 usec. to complete, typ 27 ticks */
-       iowrite32(0x04000000 | (location<<16) | (phy_id<<21) | value,
-                ioaddr + SCBCtrlMDI);
-       do {
-               val = ioread32(ioaddr + SCBCtrlMDI);
-               if (--boguscnt < 0) {
-                       printk(KERN_ERR" mdio_write() timed out with val = %8.8x.\n", val);
-                       break;
-               }
-       } while (! (val & 0x10000000));
-}
-
-static int
-speedo_open(struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       void __iomem *ioaddr = sp->regs;
-       int retval;
-
-       if (netif_msg_ifup(sp))
-               printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq);
-
-       pci_set_power_state(sp->pdev, PCI_D0);
-
-       /* Set up the Tx queue early.. */
-       sp->cur_tx = 0;
-       sp->dirty_tx = 0;
-       sp->last_cmd = NULL;
-       sp->tx_full = 0;
-       sp->in_interrupt = 0;
-
-       /* .. we can safely take handler calls during init. */
-       retval = request_irq(dev->irq, &speedo_interrupt, IRQF_SHARED, dev->name, dev);
-       if (retval) {
-               return retval;
-       }
-
-       dev->if_port = sp->default_port;
-
-#ifdef oh_no_you_dont_unless_you_honour_the_options_passed_in_to_us
-       /* Retrigger negotiation to reset previous errors. */
-       if ((sp->phy[0] & 0x8000) == 0) {
-               int phy_addr = sp->phy[0] & 0x1f ;
-               /* Use 0x3300 for restarting NWay, other values to force xcvr:
-                  0x0000 10-HD
-                  0x0100 10-FD
-                  0x2000 100-HD
-                  0x2100 100-FD
-               */
-#ifdef honor_default_port
-               mdio_write(dev, phy_addr, MII_BMCR, mii_ctrl[dev->default_port & 7]);
-#else
-               mdio_write(dev, phy_addr, MII_BMCR, 0x3300);
-#endif
-       }
-#endif
-
-       speedo_init_rx_ring(dev);
-
-       /* Fire up the hardware. */
-       iowrite16(SCBMaskAll, ioaddr + SCBCmd);
-       speedo_resume(dev);
-
-       netdevice_start(dev);
-       netif_start_queue(dev);
-
-       /* Setup the chip and configure the multicast list. */
-       sp->mc_setup_head = NULL;
-       sp->mc_setup_tail = NULL;
-       sp->flow_ctrl = sp->partner = 0;
-       sp->rx_mode = -1;                       /* Invalid -> always reset the mode. */
-       set_rx_mode(dev);
-       if ((sp->phy[0] & 0x8000) == 0)
-               sp->mii_if.advertising = mdio_read(dev, sp->phy[0] & 0x1f, MII_ADVERTISE);
-
-       mii_check_link(&sp->mii_if);
-
-       if (netif_msg_ifup(sp)) {
-               printk(KERN_DEBUG "%s: Done speedo_open(), status %8.8x.\n",
-                          dev->name, ioread16(ioaddr + SCBStatus));
-       }
-
-       /* Set the timer.  The timer serves a dual purpose:
-          1) to monitor the media interface (e.g. link beat) and perhaps switch
-          to an alternate media type
-          2) to monitor Rx activity, and restart the Rx process if the receiver
-          hangs. */
-       sp->timer.expires = RUN_AT((24*HZ)/10);                         /* 2.4 sec. */
-       sp->timer.data = (unsigned long)dev;
-       sp->timer.function = &speedo_timer;                                     /* timer handler */
-       add_timer(&sp->timer);
-
-       /* No need to wait for the command unit to accept here. */
-       if ((sp->phy[0] & 0x8000) == 0)
-               mdio_read(dev, sp->phy[0] & 0x1f, MII_BMCR);
-
-       return 0;
-}
-
-/* Start the chip hardware after a full reset. */
-static void speedo_resume(struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       void __iomem *ioaddr = sp->regs;
-
-       /* Start with a Tx threshold of 256 (0x..20.... 8 byte units). */
-       sp->tx_threshold = 0x01208000;
-
-       /* Set the segment registers to '0'. */
-       if (wait_for_cmd_done(dev, sp) != 0) {
-               iowrite32(PortPartialReset, ioaddr + SCBPort);
-               udelay(10);
-       }
-
-        iowrite32(0, ioaddr + SCBPointer);
-        ioread32(ioaddr + SCBPointer);                 /* Flush to PCI. */
-        udelay(10);                    /* Bogus, but it avoids the bug. */
-
-        /* Note: these next two operations can take a while. */
-        do_slow_command(dev, sp, RxAddrLoad);
-        do_slow_command(dev, sp, CUCmdBase);
-
-       /* Load the statistics block and rx ring addresses. */
-       iowrite32(sp->lstats_dma, ioaddr + SCBPointer);
-       ioread32(ioaddr + SCBPointer);                  /* Flush to PCI */
-
-       iowrite8(CUStatsAddr, ioaddr + SCBCmd);
-       sp->lstats->done_marker = 0;
-       wait_for_cmd_done(dev, sp);
-
-       if (sp->rx_ringp[sp->cur_rx % RX_RING_SIZE] == NULL) {
-               if (netif_msg_rx_err(sp))
-                       printk(KERN_DEBUG "%s: NULL cur_rx in speedo_resume().\n",
-                                       dev->name);
-       } else {
-               iowrite32(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
-                        ioaddr + SCBPointer);
-               ioread32(ioaddr + SCBPointer);          /* Flush to PCI */
-       }
-
-       /* Note: RxStart should complete instantly. */
-       do_slow_command(dev, sp, RxStart);
-       do_slow_command(dev, sp, CUDumpStats);
-
-       /* Fill the first command with our physical address. */
-       {
-               struct descriptor *ias_cmd;
-
-               ias_cmd =
-                       (struct descriptor *)&sp->tx_ring[sp->cur_tx++ % TX_RING_SIZE];
-               /* Avoid a bug(?!) here by marking the command already completed. */
-               ias_cmd->cmd_status = cpu_to_le32((CmdSuspend | CmdIASetup) | 0xa000);
-               ias_cmd->link =
-                       cpu_to_le32(TX_RING_ELEM_DMA(sp, sp->cur_tx % TX_RING_SIZE));
-               memcpy(ias_cmd->params, dev->dev_addr, 6);
-               if (sp->last_cmd)
-                       clear_suspend(sp->last_cmd);
-               sp->last_cmd = ias_cmd;
-       }
-
-       /* Start the chip's Tx process and unmask interrupts. */
-       iowrite32(TX_RING_ELEM_DMA(sp, sp->dirty_tx % TX_RING_SIZE),
-                ioaddr + SCBPointer);
-       /* We are not ACK-ing FCP and ER in the interrupt handler yet so they should
-          remain masked --Dragan */
-       iowrite16(CUStart | SCBMaskEarlyRx | SCBMaskFlowCtl, ioaddr + SCBCmd);
-}
-
-/*
- * Sometimes the receiver stops making progress.  This routine knows how to
- * get it going again, without losing packets or being otherwise nasty like
- * a chip reset would be.  Previously the driver had a whole sequence
- * of if RxSuspended, if it's no buffers do one thing, if it's no resources,
- * do another, etc.  But those things don't really matter.  Separate logic
- * in the ISR provides for allocating buffers--the other half of operation
- * is just making sure the receiver is active.  speedo_rx_soft_reset does that.
- * This problem with the old, more involved algorithm is shown up under
- * ping floods on the order of 60K packets/second on a 100Mbps fdx network.
- */
-static void
-speedo_rx_soft_reset(struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       struct RxFD *rfd;
-       void __iomem *ioaddr;
-
-       ioaddr = sp->regs;
-       if (wait_for_cmd_done(dev, sp) != 0) {
-               printk("%s: previous command stalled\n", dev->name);
-               return;
-       }
-       /*
-       * Put the hardware into a known state.
-       */
-       iowrite8(RxAbort, ioaddr + SCBCmd);
-
-       rfd = sp->rx_ringp[sp->cur_rx % RX_RING_SIZE];
-
-       rfd->rx_buf_addr = cpu_to_le32(0xffffffff);
-
-       if (wait_for_cmd_done(dev, sp) != 0) {
-               printk("%s: RxAbort command stalled\n", dev->name);
-               return;
-       }
-       iowrite32(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
-               ioaddr + SCBPointer);
-       iowrite8(RxStart, ioaddr + SCBCmd);
-}
-
-
-/* Media monitoring and control. */
-static void speedo_timer(unsigned long data)
-{
-       struct net_device *dev = (struct net_device *)data;
-       struct speedo_private *sp = netdev_priv(dev);
-       void __iomem *ioaddr = sp->regs;
-       int phy_num = sp->phy[0] & 0x1f;
-
-       /* We have MII and lost link beat. */
-       if ((sp->phy[0] & 0x8000) == 0) {
-               int partner = mdio_read(dev, phy_num, MII_LPA);
-               if (partner != sp->partner) {
-                       int flow_ctrl = sp->mii_if.advertising & partner & 0x0400 ? 1 : 0;
-                       if (netif_msg_link(sp)) {
-                               printk(KERN_DEBUG "%s: Link status change.\n", dev->name);
-                               printk(KERN_DEBUG "%s: Old partner %x, new %x, adv %x.\n",
-                                          dev->name, sp->partner, partner, sp->mii_if.advertising);
-                       }
-                       sp->partner = partner;
-                       if (flow_ctrl != sp->flow_ctrl) {
-                               sp->flow_ctrl = flow_ctrl;
-                               sp->rx_mode = -1;       /* Trigger a reload. */
-                       }
-               }
-       }
-       mii_check_link(&sp->mii_if);
-       if (netif_msg_timer(sp)) {
-               printk(KERN_DEBUG "%s: Media control tick, status %4.4x.\n",
-                          dev->name, ioread16(ioaddr + SCBStatus));
-       }
-       if (sp->rx_mode < 0  ||
-               (sp->rx_bug  && jiffies - sp->last_rx_time > 2*HZ)) {
-               /* We haven't received a packet in a Long Time.  We might have been
-                  bitten by the receiver hang bug.  This can be cleared by sending
-                  a set multicast list command. */
-               if (netif_msg_timer(sp))
-                       printk(KERN_DEBUG "%s: Sending a multicast list set command"
-                                  " from a timer routine,"
-                                  " m=%d, j=%ld, l=%ld.\n",
-                                  dev->name, sp->rx_mode, jiffies, sp->last_rx_time);
-               set_rx_mode(dev);
-       }
-       /* We must continue to monitor the media. */
-       sp->timer.expires = RUN_AT(2*HZ);                       /* 2.0 sec. */
-       add_timer(&sp->timer);
-}
-
-static void speedo_show_state(struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       int i;
-
-       if (netif_msg_pktdata(sp)) {
-               printk(KERN_DEBUG "%s: Tx ring dump,  Tx queue %u / %u:\n",
-                   dev->name, sp->cur_tx, sp->dirty_tx);
-               for (i = 0; i < TX_RING_SIZE; i++)
-                       printk(KERN_DEBUG "%s:  %c%c%2d %8.8x.\n", dev->name,
-                           i == sp->dirty_tx % TX_RING_SIZE ? '*' : ' ',
-                           i == sp->cur_tx % TX_RING_SIZE ? '=' : ' ',
-                           i, sp->tx_ring[i].status);
-
-               printk(KERN_DEBUG "%s: Printing Rx ring"
-                   " (next to receive into %u, dirty index %u).\n",
-                   dev->name, sp->cur_rx, sp->dirty_rx);
-               for (i = 0; i < RX_RING_SIZE; i++)
-                       printk(KERN_DEBUG "%s: %c%c%c%2d %8.8x.\n", dev->name,
-                           sp->rx_ringp[i] == sp->last_rxf ? 'l' : ' ',
-                           i == sp->dirty_rx % RX_RING_SIZE ? '*' : ' ',
-                           i == sp->cur_rx % RX_RING_SIZE ? '=' : ' ',
-                           i, (sp->rx_ringp[i] != NULL) ?
-                           (unsigned)sp->rx_ringp[i]->status : 0);
-       }
-
-#if 0
-       {
-               void __iomem *ioaddr = sp->regs;
-               int phy_num = sp->phy[0] & 0x1f;
-               for (i = 0; i < 16; i++) {
-                       /* FIXME: what does it mean?  --SAW */
-                       if (i == 6) i = 21;
-                       printk(KERN_DEBUG "%s:  PHY index %d register %d is %4.4x.\n",
-                                  dev->name, phy_num, i, mdio_read(dev, phy_num, i));
-               }
-       }
-#endif
-
-}
-
-/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
-static void
-speedo_init_rx_ring(struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       struct RxFD *rxf, *last_rxf = NULL;
-       dma_addr_t last_rxf_dma = 0 /* to shut up the compiler */;
-       int i;
-
-       sp->cur_rx = 0;
-
-       for (i = 0; i < RX_RING_SIZE; i++) {
-               struct sk_buff *skb;
-               skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD));
-               if (skb)
-                       rx_align(skb);        /* Align IP on 16 byte boundary */
-               sp->rx_skbuff[i] = skb;
-               if (skb == NULL)
-                       break;                  /* OK.  Just initially short of Rx bufs. */
-               skb->dev = dev;                 /* Mark as being used by this device. */
-               rxf = (struct RxFD *)skb->data;
-               sp->rx_ringp[i] = rxf;
-               sp->rx_ring_dma[i] =
-                       pci_map_single(sp->pdev, rxf,
-                                       PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_BIDIRECTIONAL);
-               skb_reserve(skb, sizeof(struct RxFD));
-               if (last_rxf) {
-                       last_rxf->link = cpu_to_le32(sp->rx_ring_dma[i]);
-                       pci_dma_sync_single_for_device(sp->pdev, last_rxf_dma,
-                                                                                  sizeof(struct RxFD), PCI_DMA_TODEVICE);
-               }
-               last_rxf = rxf;
-               last_rxf_dma = sp->rx_ring_dma[i];
-               rxf->status = cpu_to_le32(0x00000001);  /* '1' is flag value only. */
-               rxf->link = 0;                                          /* None yet. */
-               /* This field unused by i82557. */
-               rxf->rx_buf_addr = cpu_to_le32(0xffffffff);
-               rxf->count = cpu_to_le32(PKT_BUF_SZ << 16);
-               pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[i],
-                                                                          sizeof(struct RxFD), PCI_DMA_TODEVICE);
-       }
-       sp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
-       /* Mark the last entry as end-of-list. */
-       last_rxf->status = cpu_to_le32(0xC0000002);     /* '2' is flag value only. */
-       pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[RX_RING_SIZE-1],
-                                                                  sizeof(struct RxFD), PCI_DMA_TODEVICE);
-       sp->last_rxf = last_rxf;
-       sp->last_rxf_dma = last_rxf_dma;
-}
-
-static void speedo_purge_tx(struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       int entry;
-
-       while ((int)(sp->cur_tx - sp->dirty_tx) > 0) {
-               entry = sp->dirty_tx % TX_RING_SIZE;
-               if (sp->tx_skbuff[entry]) {
-                       sp->stats.tx_errors++;
-                       pci_unmap_single(sp->pdev,
-                                       le32_to_cpu(sp->tx_ring[entry].tx_buf_addr0),
-                                       sp->tx_skbuff[entry]->len, PCI_DMA_TODEVICE);
-                       dev_kfree_skb_irq(sp->tx_skbuff[entry]);
-                       sp->tx_skbuff[entry] = NULL;
-               }
-               sp->dirty_tx++;
-       }
-       while (sp->mc_setup_head != NULL) {
-               struct speedo_mc_block *t;
-               if (netif_msg_tx_err(sp))
-                       printk(KERN_DEBUG "%s: freeing mc frame.\n", dev->name);
-               pci_unmap_single(sp->pdev, sp->mc_setup_head->frame_dma,
-                               sp->mc_setup_head->len, PCI_DMA_TODEVICE);
-               t = sp->mc_setup_head->next;
-               kfree(sp->mc_setup_head);
-               sp->mc_setup_head = t;
-       }
-       sp->mc_setup_tail = NULL;
-       sp->tx_full = 0;
-       netif_wake_queue(dev);
-}
-
-static void reset_mii(struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-
-       /* Reset the MII transceiver, suggested by Fred Young @ scalable.com. */
-       if ((sp->phy[0] & 0x8000) == 0) {
-               int phy_addr = sp->phy[0] & 0x1f;
-               int advertising = mdio_read(dev, phy_addr, MII_ADVERTISE);
-               int mii_bmcr = mdio_read(dev, phy_addr, MII_BMCR);
-               mdio_write(dev, phy_addr, MII_BMCR, 0x0400);
-               mdio_write(dev, phy_addr, MII_BMSR, 0x0000);
-               mdio_write(dev, phy_addr, MII_ADVERTISE, 0x0000);
-               mdio_write(dev, phy_addr, MII_BMCR, 0x8000);
-#ifdef honor_default_port
-               mdio_write(dev, phy_addr, MII_BMCR, mii_ctrl[dev->default_port & 7]);
-#else
-               mdio_read(dev, phy_addr, MII_BMCR);
-               mdio_write(dev, phy_addr, MII_BMCR, mii_bmcr);
-               mdio_write(dev, phy_addr, MII_ADVERTISE, advertising);
-#endif
-       }
-}
-
-static void speedo_tx_timeout(struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       void __iomem *ioaddr = sp->regs;
-       int status = ioread16(ioaddr + SCBStatus);
-       unsigned long flags;
-
-       if (netif_msg_tx_err(sp)) {
-               printk(KERN_WARNING "%s: Transmit timed out: status %4.4x "
-                  " %4.4x at %d/%d command %8.8x.\n",
-                  dev->name, status, ioread16(ioaddr + SCBCmd),
-                  sp->dirty_tx, sp->cur_tx,
-                  sp->tx_ring[sp->dirty_tx % TX_RING_SIZE].status);
-
-       }
-       speedo_show_state(dev);
-#if 0
-       if ((status & 0x00C0) != 0x0080
-               &&  (status & 0x003C) == 0x0010) {
-               /* Only the command unit has stopped. */
-               printk(KERN_WARNING "%s: Trying to restart the transmitter...\n",
-                          dev->name);
-               iowrite32(TX_RING_ELEM_DMA(sp, dirty_tx % TX_RING_SIZE]),
-                        ioaddr + SCBPointer);
-               iowrite16(CUStart, ioaddr + SCBCmd);
-               reset_mii(dev);
-       } else {
-#else
-       {
-#endif
-               del_timer_sync(&sp->timer);
-               /* Reset the Tx and Rx units. */
-               iowrite32(PortReset, ioaddr + SCBPort);
-               /* We may get spurious interrupts here.  But I don't think that they
-                  may do much harm.  1999/12/09 SAW */
-               udelay(10);
-               /* Disable interrupts. */
-               iowrite16(SCBMaskAll, ioaddr + SCBCmd);
-               synchronize_irq(dev->irq);
-               speedo_tx_buffer_gc(dev);
-               /* Free as much as possible.
-                  It helps to recover from a hang because of out-of-memory.
-                  It also simplifies speedo_resume() in case TX ring is full or
-                  close-to-be full. */
-               speedo_purge_tx(dev);
-               speedo_refill_rx_buffers(dev, 1);
-               spin_lock_irqsave(&sp->lock, flags);
-               speedo_resume(dev);
-               sp->rx_mode = -1;
-               dev->trans_start = jiffies;
-               spin_unlock_irqrestore(&sp->lock, flags);
-               set_rx_mode(dev); /* it takes the spinlock itself --SAW */
-               /* Reset MII transceiver.  Do it before starting the timer to serialize
-                  mdio_xxx operations.  Yes, it's a paranoya :-)  2000/05/09 SAW */
-               reset_mii(dev);
-               sp->timer.expires = RUN_AT(2*HZ);
-               add_timer(&sp->timer);
-       }
-       return;
-}
-
-static int
-speedo_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       void __iomem *ioaddr = sp->regs;
-       int entry;
-
-       /* Prevent interrupts from changing the Tx ring from underneath us. */
-       unsigned long flags;
-
-       spin_lock_irqsave(&sp->lock, flags);
-
-       /* Check if there are enough space. */
-       if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
-               printk(KERN_ERR "%s: incorrect tbusy state, fixed.\n", dev->name);
-               netif_stop_queue(dev);
-               sp->tx_full = 1;
-               spin_unlock_irqrestore(&sp->lock, flags);
-               return 1;
-       }
-
-       /* Calculate the Tx descriptor entry. */
-       entry = sp->cur_tx++ % TX_RING_SIZE;
-
-       sp->tx_skbuff[entry] = skb;
-       sp->tx_ring[entry].status =
-               cpu_to_le32(CmdSuspend | CmdTx | CmdTxFlex);
-       if (!(entry & ((TX_RING_SIZE>>2)-1)))
-               sp->tx_ring[entry].status |= cpu_to_le32(CmdIntr);
-       sp->tx_ring[entry].link =
-               cpu_to_le32(TX_RING_ELEM_DMA(sp, sp->cur_tx % TX_RING_SIZE));
-       sp->tx_ring[entry].tx_desc_addr =
-               cpu_to_le32(TX_RING_ELEM_DMA(sp, entry) + TX_DESCR_BUF_OFFSET);
-       /* The data region is always in one buffer descriptor. */
-       sp->tx_ring[entry].count = cpu_to_le32(sp->tx_threshold);
-       sp->tx_ring[entry].tx_buf_addr0 =
-               cpu_to_le32(pci_map_single(sp->pdev, skb->data,
-                                          skb->len, PCI_DMA_TODEVICE));
-       sp->tx_ring[entry].tx_buf_size0 = cpu_to_le32(skb->len);
-
-       /* workaround for hardware bug on 10 mbit half duplex */
-
-       if ((sp->partner == 0) && (sp->chip_id == 1)) {
-               wait_for_cmd_done(dev, sp);
-               iowrite8(0 , ioaddr + SCBCmd);
-               udelay(1);
-       }
-
-       /* Trigger the command unit resume. */
-       wait_for_cmd_done(dev, sp);
-       clear_suspend(sp->last_cmd);
-       /* We want the time window between clearing suspend flag on the previous
-          command and resuming CU to be as small as possible.
-          Interrupts in between are very undesired.  --SAW */
-       iowrite8(CUResume, ioaddr + SCBCmd);
-       sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
-
-       /* Leave room for set_rx_mode(). If there is no more space than reserved
-          for multicast filter mark the ring as full. */
-       if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
-               netif_stop_queue(dev);
-               sp->tx_full = 1;
-       }
-
-       spin_unlock_irqrestore(&sp->lock, flags);
-
-       dev->trans_start = jiffies;
-
-       return 0;
-}
-
-static void speedo_tx_buffer_gc(struct net_device *dev)
-{
-       unsigned int dirty_tx;
-       struct speedo_private *sp = netdev_priv(dev);
-
-       dirty_tx = sp->dirty_tx;
-       while ((int)(sp->cur_tx - dirty_tx) > 0) {
-               int entry = dirty_tx % TX_RING_SIZE;
-               int status = le32_to_cpu(sp->tx_ring[entry].status);
-
-               if (netif_msg_tx_done(sp))
-                       printk(KERN_DEBUG " scavenge candidate %d status %4.4x.\n",
-                                  entry, status);
-               if ((status & StatusComplete) == 0)
-                       break;                  /* It still hasn't been processed. */
-               if (status & TxUnderrun)
-                       if (sp->tx_threshold < 0x01e08000) {
-                               if (netif_msg_tx_err(sp))
-                                       printk(KERN_DEBUG "%s: TX underrun, threshold adjusted.\n",
-                                                  dev->name);
-                               sp->tx_threshold += 0x00040000;
-                       }
-               /* Free the original skb. */
-               if (sp->tx_skbuff[entry]) {
-                       sp->stats.tx_packets++; /* Count only user packets. */
-                       sp->stats.tx_bytes += sp->tx_skbuff[entry]->len;
-                       pci_unmap_single(sp->pdev,
-                                       le32_to_cpu(sp->tx_ring[entry].tx_buf_addr0),
-                                       sp->tx_skbuff[entry]->len, PCI_DMA_TODEVICE);
-                       dev_kfree_skb_irq(sp->tx_skbuff[entry]);
-                       sp->tx_skbuff[entry] = NULL;
-               }
-               dirty_tx++;
-       }
-
-       if (netif_msg_tx_err(sp) && (int)(sp->cur_tx - dirty_tx) > TX_RING_SIZE) {
-               printk(KERN_ERR "out-of-sync dirty pointer, %d vs. %d,"
-                          " full=%d.\n",
-                          dirty_tx, sp->cur_tx, sp->tx_full);
-               dirty_tx += TX_RING_SIZE;
-       }
-
-       while (sp->mc_setup_head != NULL
-                  && (int)(dirty_tx - sp->mc_setup_head->tx - 1) > 0) {
-               struct speedo_mc_block *t;
-               if (netif_msg_tx_err(sp))
-                       printk(KERN_DEBUG "%s: freeing mc frame.\n", dev->name);
-               pci_unmap_single(sp->pdev, sp->mc_setup_head->frame_dma,
-                               sp->mc_setup_head->len, PCI_DMA_TODEVICE);
-               t = sp->mc_setup_head->next;
-               kfree(sp->mc_setup_head);
-               sp->mc_setup_head = t;
-       }
-       if (sp->mc_setup_head == NULL)
-               sp->mc_setup_tail = NULL;
-
-       sp->dirty_tx = dirty_tx;
-}
-
-/* The interrupt handler does all of the Rx thread work and cleans up
-   after the Tx thread. */
-static irqreturn_t speedo_interrupt(int irq, void *dev_instance)
-{
-       struct net_device *dev = (struct net_device *)dev_instance;
-       struct speedo_private *sp;
-       void __iomem *ioaddr;
-       long boguscnt = max_interrupt_work;
-       unsigned short status;
-       unsigned int handled = 0;
-
-       sp = netdev_priv(dev);
-       ioaddr = sp->regs;
-
-#ifndef final_version
-       /* A lock to prevent simultaneous entry on SMP machines. */
-       if (test_and_set_bit(0, (void*)&sp->in_interrupt)) {
-               printk(KERN_ERR"%s: SMP simultaneous entry of an interrupt handler.\n",
-                          dev->name);
-               sp->in_interrupt = 0;   /* Avoid halting machine. */
-               return IRQ_NONE;
-       }
-#endif
-
-       do {
-               status = ioread16(ioaddr + SCBStatus);
-               /* Acknowledge all of the current interrupt sources ASAP. */
-               /* Will change from 0xfc00 to 0xff00 when we start handling
-                  FCP and ER interrupts --Dragan */
-               iowrite16(status & 0xfc00, ioaddr + SCBStatus);
-
-               if (netif_msg_intr(sp))
-                       printk(KERN_DEBUG "%s: interrupt  status=%#4.4x.\n",
-                                  dev->name, status);
-
-               if ((status & 0xfc00) == 0)
-                       break;
-               handled = 1;
-
-
-               if ((status & 0x5000) ||        /* Packet received, or Rx error. */
-                       (sp->rx_ring_state&(RrNoMem|RrPostponed)) == RrPostponed)
-                                                                       /* Need to gather the postponed packet. */
-                       speedo_rx(dev);
-
-               /* Always check if all rx buffers are allocated.  --SAW */
-               speedo_refill_rx_buffers(dev, 0);
-
-               spin_lock(&sp->lock);
-               /*
-                * The chip may have suspended reception for various reasons.
-                * Check for that, and re-prime it should this be the case.
-                */
-               switch ((status >> 2) & 0xf) {
-               case 0: /* Idle */
-                       break;
-               case 1: /* Suspended */
-               case 2: /* No resources (RxFDs) */
-               case 9: /* Suspended with no more RBDs */
-               case 10: /* No resources due to no RBDs */
-               case 12: /* Ready with no RBDs */
-                       speedo_rx_soft_reset(dev);
-                       break;
-               case 3:  case 5:  case 6:  case 7:  case 8:
-               case 11:  case 13:  case 14:  case 15:
-                       /* these are all reserved values */
-                       break;
-               }
-
-
-               /* User interrupt, Command/Tx unit interrupt or CU not active. */
-               if (status & 0xA400) {
-                       speedo_tx_buffer_gc(dev);
-                       if (sp->tx_full
-                               && (int)(sp->cur_tx - sp->dirty_tx) < TX_QUEUE_UNFULL) {
-                               /* The ring is no longer full. */
-                               sp->tx_full = 0;
-                               netif_wake_queue(dev); /* Attention: under a spinlock.  --SAW */
-                       }
-               }
-
-               spin_unlock(&sp->lock);
-
-               if (--boguscnt < 0) {
-                       printk(KERN_ERR "%s: Too much work at interrupt, status=0x%4.4x.\n",
-                                  dev->name, status);
-                       /* Clear all interrupt sources. */
-                       /* Will change from 0xfc00 to 0xff00 when we start handling
-                          FCP and ER interrupts --Dragan */
-                       iowrite16(0xfc00, ioaddr + SCBStatus);
-                       break;
-               }
-       } while (1);
-
-       if (netif_msg_intr(sp))
-               printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
-                          dev->name, ioread16(ioaddr + SCBStatus));
-
-       clear_bit(0, (void*)&sp->in_interrupt);
-       return IRQ_RETVAL(handled);
-}
-
-static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       struct RxFD *rxf;
-       struct sk_buff *skb;
-       /* Get a fresh skbuff to replace the consumed one. */
-       skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD));
-       if (skb)
-               rx_align(skb);          /* Align IP on 16 byte boundary */
-       sp->rx_skbuff[entry] = skb;
-       if (skb == NULL) {
-               sp->rx_ringp[entry] = NULL;
-               return NULL;
-       }
-       rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->data;
-       sp->rx_ring_dma[entry] =
-               pci_map_single(sp->pdev, rxf,
-                                          PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
-       skb->dev = dev;
-       skb_reserve(skb, sizeof(struct RxFD));
-       rxf->rx_buf_addr = cpu_to_le32(0xffffffff);
-       pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry],
-                                                                  sizeof(struct RxFD), PCI_DMA_TODEVICE);
-       return rxf;
-}
-
-static inline void speedo_rx_link(struct net_device *dev, int entry,
-                                                                 struct RxFD *rxf, dma_addr_t rxf_dma)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       rxf->status = cpu_to_le32(0xC0000001);  /* '1' for driver use only. */
-       rxf->link = 0;                  /* None yet. */
-       rxf->count = cpu_to_le32(PKT_BUF_SZ << 16);
-       sp->last_rxf->link = cpu_to_le32(rxf_dma);
-       sp->last_rxf->status &= cpu_to_le32(~0xC0000000);
-       pci_dma_sync_single_for_device(sp->pdev, sp->last_rxf_dma,
-                                                                  sizeof(struct RxFD), PCI_DMA_TODEVICE);
-       sp->last_rxf = rxf;
-       sp->last_rxf_dma = rxf_dma;
-}
-
-static int speedo_refill_rx_buf(struct net_device *dev, int force)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       int entry;
-       struct RxFD *rxf;
-
-       entry = sp->dirty_rx % RX_RING_SIZE;
-       if (sp->rx_skbuff[entry] == NULL) {
-               rxf = speedo_rx_alloc(dev, entry);
-               if (rxf == NULL) {
-                       unsigned int forw;
-                       int forw_entry;
-                       if (netif_msg_rx_err(sp) || !(sp->rx_ring_state & RrOOMReported)) {
-                               printk(KERN_WARNING "%s: can't fill rx buffer (force %d)!\n",
-                                               dev->name, force);
-                               sp->rx_ring_state |= RrOOMReported;
-                       }
-                       speedo_show_state(dev);
-                       if (!force)
-                               return -1;      /* Better luck next time!  */
-                       /* Borrow an skb from one of next entries. */
-                       for (forw = sp->dirty_rx + 1; forw != sp->cur_rx; forw++)
-                               if (sp->rx_skbuff[forw % RX_RING_SIZE] != NULL)
-                                       break;
-                       if (forw == sp->cur_rx)
-                               return -1;
-                       forw_entry = forw % RX_RING_SIZE;
-                       sp->rx_skbuff[entry] = sp->rx_skbuff[forw_entry];
-                       sp->rx_skbuff[forw_entry] = NULL;
-                       rxf = sp->rx_ringp[forw_entry];
-                       sp->rx_ringp[forw_entry] = NULL;
-                       sp->rx_ringp[entry] = rxf;
-               }
-       } else {
-               rxf = sp->rx_ringp[entry];
-       }
-       speedo_rx_link(dev, entry, rxf, sp->rx_ring_dma[entry]);
-       sp->dirty_rx++;
-       sp->rx_ring_state &= ~(RrNoMem|RrOOMReported); /* Mark the progress. */
-       return 0;
-}
-
-static void speedo_refill_rx_buffers(struct net_device *dev, int force)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-
-       /* Refill the RX ring. */
-       while ((int)(sp->cur_rx - sp->dirty_rx) > 0 &&
-                       speedo_refill_rx_buf(dev, force) != -1);
-}
-
-static int
-speedo_rx(struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       int entry = sp->cur_rx % RX_RING_SIZE;
-       int rx_work_limit = sp->dirty_rx + RX_RING_SIZE - sp->cur_rx;
-       int alloc_ok = 1;
-       int npkts = 0;
-
-       if (netif_msg_intr(sp))
-               printk(KERN_DEBUG " In speedo_rx().\n");
-       /* If we own the next entry, it's a new packet. Send it up. */
-       while (sp->rx_ringp[entry] != NULL) {
-               int status;
-               int pkt_len;
-
-               pci_dma_sync_single_for_cpu(sp->pdev, sp->rx_ring_dma[entry],
-                                                                       sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
-               status = le32_to_cpu(sp->rx_ringp[entry]->status);
-               pkt_len = le32_to_cpu(sp->rx_ringp[entry]->count) & 0x3fff;
-
-               if (!(status & RxComplete))
-                       break;
-
-               if (--rx_work_limit < 0)
-                       break;
-
-               /* Check for a rare out-of-memory case: the current buffer is
-                  the last buffer allocated in the RX ring.  --SAW */
-               if (sp->last_rxf == sp->rx_ringp[entry]) {
-                       /* Postpone the packet.  It'll be reaped at an interrupt when this
-                          packet is no longer the last packet in the ring. */
-                       if (netif_msg_rx_err(sp))
-                               printk(KERN_DEBUG "%s: RX packet postponed!\n",
-                                          dev->name);
-                       sp->rx_ring_state |= RrPostponed;
-                       break;
-               }
-
-               if (netif_msg_rx_status(sp))
-                       printk(KERN_DEBUG "  speedo_rx() status %8.8x len %d.\n", status,
-                                  pkt_len);
-               if ((status & (RxErrTooBig|RxOK|0x0f90)) != RxOK) {
-                       if (status & RxErrTooBig)
-                               printk(KERN_ERR "%s: Ethernet frame overran the Rx buffer, "
-                                          "status %8.8x!\n", dev->name, status);
-                       else if (! (status & RxOK)) {
-                               /* There was a fatal error.  This *should* be impossible. */
-                               sp->stats.rx_errors++;
-                               printk(KERN_ERR "%s: Anomalous event in speedo_rx(), "
-                                          "status %8.8x.\n",
-                                          dev->name, status);
-                       }
-               } else {
-                       struct sk_buff *skb;
-
-                       /* Check if the packet is long enough to just accept without
-                          copying to a properly sized skbuff. */
-                       if (pkt_len < rx_copybreak
-                               && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
-                               skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
-                               /* 'skb_put()' points to the start of sk_buff data area. */
-                               pci_dma_sync_single_for_cpu(sp->pdev, sp->rx_ring_dma[entry],
-                                                                                       sizeof(struct RxFD) + pkt_len,
-                                                                                       PCI_DMA_FROMDEVICE);
-
-#if 1 || USE_IP_CSUM
-                               /* Packet is in one chunk -- we can copy + cksum. */
-                               skb_copy_to_linear_data(skb, sp->rx_skbuff[entry]->data, pkt_len);
-                               skb_put(skb, pkt_len);
-#else
-                               skb_copy_from_linear_data(sp->rx_skbuff[entry],
-                                                         skb_put(skb, pkt_len),
-                                                         pkt_len);
-#endif
-                               pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry],
-                                                                                          sizeof(struct RxFD) + pkt_len,
-                                                                                          PCI_DMA_FROMDEVICE);
-                               npkts++;
-                       } else {
-                               /* Pass up the already-filled skbuff. */
-                               skb = sp->rx_skbuff[entry];
-                               if (skb == NULL) {
-                                       printk(KERN_ERR "%s: Inconsistent Rx descriptor chain.\n",
-                                                  dev->name);
-                                       break;
-                               }
-                               sp->rx_skbuff[entry] = NULL;
-                               skb_put(skb, pkt_len);
-                               npkts++;
-                               sp->rx_ringp[entry] = NULL;
-                               pci_unmap_single(sp->pdev, sp->rx_ring_dma[entry],
-                                                                PKT_BUF_SZ + sizeof(struct RxFD),
-                                                                PCI_DMA_FROMDEVICE);
-                       }
-                       skb->protocol = eth_type_trans(skb, dev);
-                       netif_rx(skb);
-                       dev->last_rx = jiffies;
-                       sp->stats.rx_packets++;
-                       sp->stats.rx_bytes += pkt_len;
-               }
-               entry = (++sp->cur_rx) % RX_RING_SIZE;
-               sp->rx_ring_state &= ~RrPostponed;
-               /* Refill the recently taken buffers.
-                  Do it one-by-one to handle traffic bursts better. */
-               if (alloc_ok && speedo_refill_rx_buf(dev, 0) == -1)
-                       alloc_ok = 0;
-       }
-
-       /* Try hard to refill the recently taken buffers. */
-       speedo_refill_rx_buffers(dev, 1);
-
-       if (npkts)
-               sp->last_rx_time = jiffies;
-
-       return 0;
-}
-
-static int
-speedo_close(struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       void __iomem *ioaddr = sp->regs;
-       int i;
-
-       netdevice_stop(dev);
-       netif_stop_queue(dev);
-
-       if (netif_msg_ifdown(sp))
-               printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.\n",
-                          dev->name, ioread16(ioaddr + SCBStatus));
-
-       /* Shut off the media monitoring timer. */
-       del_timer_sync(&sp->timer);
-
-       iowrite16(SCBMaskAll, ioaddr + SCBCmd);
-
-       /* Shutting down the chip nicely fails to disable flow control. So.. */
-       iowrite32(PortPartialReset, ioaddr + SCBPort);
-       ioread32(ioaddr + SCBPort); /* flush posted write */
-       /*
-        * The chip requires a 10 microsecond quiet period.  Wait here!
-        */
-       udelay(10);
-
-       free_irq(dev->irq, dev);
-       speedo_show_state(dev);
-
-    /* Free all the skbuffs in the Rx and Tx queues. */
-       for (i = 0; i < RX_RING_SIZE; i++) {
-               struct sk_buff *skb = sp->rx_skbuff[i];
-               sp->rx_skbuff[i] = NULL;
-               /* Clear the Rx descriptors. */
-               if (skb) {
-                       pci_unmap_single(sp->pdev,
-                                        sp->rx_ring_dma[i],
-                                        PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
-                       dev_kfree_skb(skb);
-               }
-       }
-
-       for (i = 0; i < TX_RING_SIZE; i++) {
-               struct sk_buff *skb = sp->tx_skbuff[i];
-               sp->tx_skbuff[i] = NULL;
-               /* Clear the Tx descriptors. */
-               if (skb) {
-                       pci_unmap_single(sp->pdev,
-                                        le32_to_cpu(sp->tx_ring[i].tx_buf_addr0),
-                                        skb->len, PCI_DMA_TODEVICE);
-                       dev_kfree_skb(skb);
-               }
-       }
-
-       /* Free multicast setting blocks. */
-       for (i = 0; sp->mc_setup_head != NULL; i++) {
-               struct speedo_mc_block *t;
-               t = sp->mc_setup_head->next;
-               kfree(sp->mc_setup_head);
-               sp->mc_setup_head = t;
-       }
-       sp->mc_setup_tail = NULL;
-       if (netif_msg_ifdown(sp))
-               printk(KERN_DEBUG "%s: %d multicast blocks dropped.\n", dev->name, i);
-
-       pci_set_power_state(sp->pdev, PCI_D2);
-
-       return 0;
-}
-
-/* The Speedo-3 has an especially awkward and unusable method of getting
-   statistics out of the chip.  It takes an unpredictable length of time
-   for the dump-stats command to complete.  To avoid a busy-wait loop we
-   update the stats with the previous dump results, and then trigger a
-   new dump.
-
-   Oh, and incoming frames are dropped while executing dump-stats!
-   */
-static struct net_device_stats *
-speedo_get_stats(struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       void __iomem *ioaddr = sp->regs;
-
-       /* Update only if the previous dump finished. */
-       if (sp->lstats->done_marker == cpu_to_le32(0xA007)) {
-               sp->stats.tx_aborted_errors += le32_to_cpu(sp->lstats->tx_coll16_errs);
-               sp->stats.tx_window_errors += le32_to_cpu(sp->lstats->tx_late_colls);
-               sp->stats.tx_fifo_errors += le32_to_cpu(sp->lstats->tx_underruns);
-               sp->stats.tx_fifo_errors += le32_to_cpu(sp->lstats->tx_lost_carrier);
-               /*sp->stats.tx_deferred += le32_to_cpu(sp->lstats->tx_deferred);*/
-               sp->stats.collisions += le32_to_cpu(sp->lstats->tx_total_colls);
-               sp->stats.rx_crc_errors += le32_to_cpu(sp->lstats->rx_crc_errs);
-               sp->stats.rx_frame_errors += le32_to_cpu(sp->lstats->rx_align_errs);
-               sp->stats.rx_over_errors += le32_to_cpu(sp->lstats->rx_resource_errs);
-               sp->stats.rx_fifo_errors += le32_to_cpu(sp->lstats->rx_overrun_errs);
-               sp->stats.rx_length_errors += le32_to_cpu(sp->lstats->rx_runt_errs);
-               sp->lstats->done_marker = 0x0000;
-               if (netif_running(dev)) {
-                       unsigned long flags;
-                       /* Take a spinlock to make wait_for_cmd_done and sending the
-                          command atomic.  --SAW */
-                       spin_lock_irqsave(&sp->lock, flags);
-                       wait_for_cmd_done(dev, sp);
-                       iowrite8(CUDumpStats, ioaddr + SCBCmd);
-                       spin_unlock_irqrestore(&sp->lock, flags);
-               }
-       }
-       return &sp->stats;
-}
-
-static void speedo_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       strncpy(info->driver, "eepro100", sizeof(info->driver)-1);
-       strncpy(info->version, version, sizeof(info->version)-1);
-       if (sp->pdev)
-               strcpy(info->bus_info, pci_name(sp->pdev));
-}
-
-static int speedo_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       spin_lock_irq(&sp->lock);
-       mii_ethtool_gset(&sp->mii_if, ecmd);
-       spin_unlock_irq(&sp->lock);
-       return 0;
-}
-
-static int speedo_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       int res;
-       spin_lock_irq(&sp->lock);
-       res = mii_ethtool_sset(&sp->mii_if, ecmd);
-       spin_unlock_irq(&sp->lock);
-       return res;
-}
-
-static int speedo_nway_reset(struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       return mii_nway_restart(&sp->mii_if);
-}
-
-static u32 speedo_get_link(struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       return mii_link_ok(&sp->mii_if);
-}
-
-static u32 speedo_get_msglevel(struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       return sp->msg_enable;
-}
-
-static void speedo_set_msglevel(struct net_device *dev, u32 v)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       sp->msg_enable = v;
-}
-
-static const struct ethtool_ops ethtool_ops = {
-       .get_drvinfo = speedo_get_drvinfo,
-       .get_settings = speedo_get_settings,
-       .set_settings = speedo_set_settings,
-       .nway_reset = speedo_nway_reset,
-       .get_link = speedo_get_link,
-       .get_msglevel = speedo_get_msglevel,
-       .set_msglevel = speedo_set_msglevel,
-};
-
-static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       struct mii_ioctl_data *data = if_mii(rq);
-       int phy = sp->phy[0] & 0x1f;
-       int saved_acpi;
-       int t;
-
-    switch(cmd) {
-       case SIOCGMIIPHY:               /* Get address of MII PHY in use. */
-               data->phy_id = phy;
-
-       case SIOCGMIIREG:               /* Read MII PHY register. */
-               /* FIXME: these operations need to be serialized with MDIO
-                  access from the timeout handler.
-                  They are currently serialized only with MDIO access from the
-                  timer routine.  2000/05/09 SAW */
-               saved_acpi = pci_set_power_state(sp->pdev, PCI_D0);
-               t = del_timer_sync(&sp->timer);
-               data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f);
-               if (t)
-                       add_timer(&sp->timer); /* may be set to the past  --SAW */
-               pci_set_power_state(sp->pdev, saved_acpi);
-               return 0;
-
-       case SIOCSMIIREG:               /* Write MII PHY register. */
-               if (!capable(CAP_NET_ADMIN))
-                       return -EPERM;
-               saved_acpi = pci_set_power_state(sp->pdev, PCI_D0);
-               t = del_timer_sync(&sp->timer);
-               mdio_write(dev, data->phy_id, data->reg_num, data->val_in);
-               if (t)
-                       add_timer(&sp->timer); /* may be set to the past  --SAW */
-               pci_set_power_state(sp->pdev, saved_acpi);
-               return 0;
-       default:
-               return -EOPNOTSUPP;
-       }
-}
-
-/* Set or clear the multicast filter for this adaptor.
-   This is very ugly with Intel chips -- we usually have to execute an
-   entire configuration command, plus process a multicast command.
-   This is complicated.  We must put a large configuration command and
-   an arbitrarily-sized multicast command in the transmit list.
-   To minimize the disruption -- the previous command might have already
-   loaded the link -- we convert the current command block, normally a Tx
-   command, into a no-op and link it to the new command.
-*/
-static void set_rx_mode(struct net_device *dev)
-{
-       struct speedo_private *sp = netdev_priv(dev);
-       void __iomem *ioaddr = sp->regs;
-       struct descriptor *last_cmd;
-       char new_rx_mode;
-       unsigned long flags;
-       int entry, i;
-
-       if (dev->flags & IFF_PROMISC) {                 /* Set promiscuous. */
-               new_rx_mode = 3;
-       } else if ((dev->flags & IFF_ALLMULTI)  ||
-                          dev->mc_count > multicast_filter_limit) {
-               new_rx_mode = 1;
-       } else
-               new_rx_mode = 0;
-
-       if (netif_msg_rx_status(sp))
-               printk(KERN_DEBUG "%s: set_rx_mode %d -> %d\n", dev->name,
-                               sp->rx_mode, new_rx_mode);
-
-       if ((int)(sp->cur_tx - sp->dirty_tx) > TX_RING_SIZE - TX_MULTICAST_SIZE) {
-           /* The Tx ring is full -- don't add anything!  Hope the mode will be
-                * set again later. */
-               sp->rx_mode = -1;
-               return;
-       }
-
-       if (new_rx_mode != sp->rx_mode) {
-               u8 *config_cmd_data;
-
-               spin_lock_irqsave(&sp->lock, flags);
-               entry = sp->cur_tx++ % TX_RING_SIZE;
-               last_cmd = sp->last_cmd;
-               sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
-
-               sp->tx_skbuff[entry] = NULL;                    /* Redundant. */
-               sp->tx_ring[entry].status = cpu_to_le32(CmdSuspend | CmdConfigure);
-               sp->tx_ring[entry].link =
-                       cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE));
-               config_cmd_data = (void *)&sp->tx_ring[entry].tx_desc_addr;
-               /* Construct a full CmdConfig frame. */
-               memcpy(config_cmd_data, i82558_config_cmd, CONFIG_DATA_SIZE);
-               config_cmd_data[1] = (txfifo << 4) | rxfifo;
-               config_cmd_data[4] = rxdmacount;
-               config_cmd_data[5] = txdmacount + 0x80;
-               config_cmd_data[15] |= (new_rx_mode & 2) ? 1 : 0;
-               /* 0x80 doesn't disable FC 0x84 does.
-                  Disable Flow control since we are not ACK-ing any FC interrupts
-                  for now. --Dragan */
-               config_cmd_data[19] = 0x84;
-               config_cmd_data[19] |= sp->mii_if.full_duplex ? 0x40 : 0;
-               config_cmd_data[21] = (new_rx_mode & 1) ? 0x0D : 0x05;
-               if (sp->phy[0] & 0x8000) {                      /* Use the AUI port instead. */
-                       config_cmd_data[15] |= 0x80;
-                       config_cmd_data[8] = 0;
-               }
-               /* Trigger the command unit resume. */
-               wait_for_cmd_done(dev, sp);
-               clear_suspend(last_cmd);
-               iowrite8(CUResume, ioaddr + SCBCmd);
-               if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
-                       netif_stop_queue(dev);
-                       sp->tx_full = 1;
-               }
-               spin_unlock_irqrestore(&sp->lock, flags);
-       }
-
-       if (new_rx_mode == 0  &&  dev->mc_count < 4) {
-               /* The simple case of 0-3 multicast list entries occurs often, and
-                  fits within one tx_ring[] entry. */
-               struct dev_mc_list *mclist;
-               __le16 *setup_params, *eaddrs;
-
-               spin_lock_irqsave(&sp->lock, flags);
-               entry = sp->cur_tx++ % TX_RING_SIZE;
-               last_cmd = sp->last_cmd;
-               sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
-
-               sp->tx_skbuff[entry] = NULL;
-               sp->tx_ring[entry].status = cpu_to_le32(CmdSuspend | CmdMulticastList);
-               sp->tx_ring[entry].link =
-                       cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE));
-               sp->tx_ring[entry].tx_desc_addr = 0; /* Really MC list count. */
-               setup_params = (__le16 *)&sp->tx_ring[entry].tx_desc_addr;
-               *setup_params++ = cpu_to_le16(dev->mc_count*6);
-               /* Fill in the multicast addresses. */
-               for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
-                        i++, mclist = mclist->next) {
-                       eaddrs = (__le16 *)mclist->dmi_addr;
-                       *setup_params++ = *eaddrs++;
-                       *setup_params++ = *eaddrs++;
-                       *setup_params++ = *eaddrs++;
-               }
-
-               wait_for_cmd_done(dev, sp);
-               clear_suspend(last_cmd);
-               /* Immediately trigger the command unit resume. */
-               iowrite8(CUResume, ioaddr + SCBCmd);
-
-               if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
-                       netif_stop_queue(dev);
-                       sp->tx_full = 1;
-               }
-               spin_unlock_irqrestore(&sp->lock, flags);
-       } else if (new_rx_mode == 0) {
-               struct dev_mc_list *mclist;
-               __le16 *setup_params, *eaddrs;
-               struct speedo_mc_block *mc_blk;
-               struct descriptor *mc_setup_frm;
-               int i;
-
-               mc_blk = kmalloc(sizeof(*mc_blk) + 2 + multicast_filter_limit*6,
-                                                GFP_ATOMIC);
-               if (mc_blk == NULL) {
-                       printk(KERN_ERR "%s: Failed to allocate a setup frame.\n",
-                                  dev->name);
-                       sp->rx_mode = -1; /* We failed, try again. */
-                       return;
-               }
-               mc_blk->next = NULL;
-               mc_blk->len = 2 + multicast_filter_limit*6;
-               mc_blk->frame_dma =
-                       pci_map_single(sp->pdev, &mc_blk->frame, mc_blk->len,
-                                       PCI_DMA_TODEVICE);
-               mc_setup_frm = &mc_blk->frame;
-
-               /* Fill the setup frame. */
-               if (netif_msg_ifup(sp))
-                       printk(KERN_DEBUG "%s: Constructing a setup frame at %p.\n",
-                                  dev->name, mc_setup_frm);
-               mc_setup_frm->cmd_status =
-                       cpu_to_le32(CmdSuspend | CmdIntr | CmdMulticastList);
-               /* Link set below. */
-               setup_params = (__le16 *)&mc_setup_frm->params;
-               *setup_params++ = cpu_to_le16(dev->mc_count*6);
-               /* Fill in the multicast addresses. */
-               for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
-                        i++, mclist = mclist->next) {
-                       eaddrs = (__le16 *)mclist->dmi_addr;
-                       *setup_params++ = *eaddrs++;
-                       *setup_params++ = *eaddrs++;
-                       *setup_params++ = *eaddrs++;
-               }
-
-               /* Disable interrupts while playing with the Tx Cmd list. */
-               spin_lock_irqsave(&sp->lock, flags);
-
-               if (sp->mc_setup_tail)
-                       sp->mc_setup_tail->next = mc_blk;
-               else
-                       sp->mc_setup_head = mc_blk;
-               sp->mc_setup_tail = mc_blk;
-               mc_blk->tx = sp->cur_tx;
-
-               entry = sp->cur_tx++ % TX_RING_SIZE;
-               last_cmd = sp->last_cmd;
-               sp->last_cmd = mc_setup_frm;
-
-               /* Change the command to a NoOp, pointing to the CmdMulti command. */
-               sp->tx_skbuff[entry] = NULL;
-               sp->tx_ring[entry].status = cpu_to_le32(CmdNOp);
-               sp->tx_ring[entry].link = cpu_to_le32(mc_blk->frame_dma);
-
-               /* Set the link in the setup frame. */
-               mc_setup_frm->link =
-                       cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE));
-
-               pci_dma_sync_single_for_device(sp->pdev, mc_blk->frame_dma,
-                                                                          mc_blk->len, PCI_DMA_TODEVICE);
-
-               wait_for_cmd_done(dev, sp);
-               clear_suspend(last_cmd);
-               /* Immediately trigger the command unit resume. */
-               iowrite8(CUResume, ioaddr + SCBCmd);
-
-               if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
-                       netif_stop_queue(dev);
-                       sp->tx_full = 1;
-               }
-               spin_unlock_irqrestore(&sp->lock, flags);
-
-               if (netif_msg_rx_status(sp))
-                       printk(" CmdMCSetup frame length %d in entry %d.\n",
-                                  dev->mc_count, entry);
-       }
-
-       sp->rx_mode = new_rx_mode;
-}
-
-#ifdef CONFIG_PM
-static int eepro100_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct net_device *dev = pci_get_drvdata (pdev);
-       struct speedo_private *sp = netdev_priv(dev);
-       void __iomem *ioaddr = sp->regs;
-
-       pci_save_state(pdev);
-
-       if (!netif_running(dev))
-               return 0;
-
-       del_timer_sync(&sp->timer);
-
-       netif_device_detach(dev);
-       iowrite32(PortPartialReset, ioaddr + SCBPort);
-
-       /* XXX call pci_set_power_state ()? */
-       pci_disable_device(pdev);
-       pci_set_power_state (pdev, PCI_D3hot);
-       return 0;
-}
-
-static int eepro100_resume(struct pci_dev *pdev)
-{
-       struct net_device *dev = pci_get_drvdata (pdev);
-       struct speedo_private *sp = netdev_priv(dev);
-       void __iomem *ioaddr = sp->regs;
-       int rc;
-
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-
-       rc = pci_enable_device(pdev);
-       if (rc)
-               return rc;
-
-       pci_set_master(pdev);
-
-       if (!netif_running(dev))
-               return 0;
-
-       /* I'm absolutely uncertain if this part of code may work.
-          The problems are:
-           - correct hardware reinitialization;
-               - correct driver behavior between different steps of the
-                 reinitialization;
-               - serialization with other driver calls.
-          2000/03/08  SAW */
-       iowrite16(SCBMaskAll, ioaddr + SCBCmd);
-       speedo_resume(dev);
-       netif_device_attach(dev);
-       sp->rx_mode = -1;
-       sp->flow_ctrl = sp->partner = 0;
-       set_rx_mode(dev);
-       sp->timer.expires = RUN_AT(2*HZ);
-       add_timer(&sp->timer);
-       return 0;
-}
-#endif /* CONFIG_PM */
-
-static void __devexit eepro100_remove_one (struct pci_dev *pdev)
-{
-       struct net_device *dev = pci_get_drvdata (pdev);
-       struct speedo_private *sp = netdev_priv(dev);
-
-       unregister_netdev(dev);
-
-       release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1));
-       release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
-
-       pci_iounmap(pdev, sp->regs);
-       pci_free_consistent(pdev, TX_RING_SIZE * sizeof(struct TxFD)
-                                                               + sizeof(struct speedo_stats),
-                                               sp->tx_ring, sp->tx_ring_dma);
-       pci_disable_device(pdev);
-       free_netdev(dev);
-}
-
-static struct pci_device_id eepro100_pci_tbl[] = {
-       { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
-       { 0,}
-};
-MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
-
-static struct pci_driver eepro100_driver = {
-       .name           = "eepro100",
-       .id_table       = eepro100_pci_tbl,
-       .probe          = eepro100_init_one,
-       .remove         = __devexit_p(eepro100_remove_one),
-#ifdef CONFIG_PM
-       .suspend        = eepro100_suspend,
-       .resume         = eepro100_resume,
-#endif /* CONFIG_PM */
-};
-
-static int __init eepro100_init_module(void)
-{
-#ifdef MODULE
-       printk(version);
-#endif
-       return pci_register_driver(&eepro100_driver);
-}
-
-static void __exit eepro100_cleanup_module(void)
-{
-       pci_unregister_driver(&eepro100_driver);
-}
-
-module_init(eepro100_init_module);
-module_exit(eepro100_cleanup_module);
-
-/*
- * Local variables:
- *  compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 4
- * End:
- */
index b751c1b96cfa77e2d445e3c182a4d2003cb8de73..a125e41240f52315def85ef2b242426f817a0ce0 100644 (file)
@@ -967,7 +967,6 @@ static void eexp_hw_rx_pio(struct net_device *dev)
                                insw(ioaddr+DATAPORT, skb_put(skb,pkt_len),(pkt_len+1)>>1);
                                skb->protocol = eth_type_trans(skb,dev);
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                                dev->stats.rx_packets++;
                                dev->stats.rx_bytes += pkt_len;
                        }
index 002d918fb4c742fc4a66af17a1d427e19959cbe0..9930d5f8b9e11b199459e69936c64a6900ffe4cb 100644 (file)
@@ -40,7 +40,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME       "ehea"
-#define DRV_VERSION    "EHEA_0095"
+#define DRV_VERSION    "EHEA_0096"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
index 422fcb93e2c381b2b80d365244084559184dbc2f..44c9ae18383f837056a969d1775d9d28f7ecc7e6 100644 (file)
@@ -728,7 +728,6 @@ static int ehea_proc_rwqes(struct net_device *dev,
                        }
 
                        ehea_proc_skb(pr, cqe, skb);
-                       dev->last_rx = jiffies;
                } else {
                        pr->p_stats.poll_receive_errors++;
                        port_reset = ehea_treat_poll_error(pr, rq, cqe,
index 9d006878f0459db1dfe30c079639638ae2025fcf..3c0ec82f36fb0f8e882e9823b9168744368925c9 100644 (file)
@@ -653,7 +653,7 @@ static int ehea_update_busmap(unsigned long pfn, unsigned long nr_pages, int add
                int top = ehea_calc_index(i, EHEA_TOP_INDEX_SHIFT);
                int dir = ehea_calc_index(i, EHEA_DIR_INDEX_SHIFT);
                int idx = i & EHEA_INDEX_MASK;
-               
+
                if (add) {
                        int ret = ehea_init_bmap(ehea_bmap, top, dir);
                        if (ret)
@@ -780,7 +780,7 @@ void ehea_destroy_busmap(void)
 
        kfree(ehea_bmap);
        ehea_bmap = NULL;
-out_destroy:   
+out_destroy:
        mutex_unlock(&ehea_busmap_mutex);
 }
 
@@ -858,10 +858,10 @@ static u64 ehea_reg_mr_sections(int top, int dir, u64 *pt,
        for (idx = 0; idx < EHEA_MAP_ENTRIES; idx++) {
                if (!ehea_bmap->top[top]->dir[dir]->ent[idx])
                        continue;
-               
+
                hret = ehea_reg_mr_section(top, dir, idx, pt, adapter, mr);
                if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED))
-                               return hret;
+                       return hret;
        }
        return hret;
 }
@@ -879,7 +879,7 @@ static u64 ehea_reg_mr_dir_sections(int top, u64 *pt,
 
                hret = ehea_reg_mr_sections(top, dir, pt, adapter, mr);
                if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED))
-                               return hret;
+                       return hret;
        }
        return hret;
 }
index e1b441effbbec15b81de2fe4b2d36992ac993724..32c19790d0135f921ab8f89d90909a04fcffa057 100644 (file)
@@ -477,12 +477,10 @@ static int enc28j60_set_hw_macaddr(struct net_device *ndev)
 
        mutex_lock(&priv->lock);
        if (!priv->hw_enable) {
-               if (netif_msg_drv(priv)) {
-                       DECLARE_MAC_BUF(mac);
+               if (netif_msg_drv(priv))
                        printk(KERN_INFO DRV_NAME
-                               ": %s: Setting MAC address to %s\n",
-                               ndev->name, print_mac(mac, ndev->dev_addr));
-               }
+                               ": %s: Setting MAC address to %pM\n",
+                               ndev->name, ndev->dev_addr);
                /* NOTE: MAC address in ENC28J60 is byte-backward */
                nolock_regb_write(priv, MAADR5, ndev->dev_addr[0]);
                nolock_regb_write(priv, MAADR4, ndev->dev_addr[1]);
@@ -946,7 +944,6 @@ static void enc28j60_hw_rx(struct net_device *ndev)
                        /* update statistics */
                        ndev->stats.rx_packets++;
                        ndev->stats.rx_bytes += len;
-                       ndev->last_rx = jiffies;
                        netif_rx(skb);
                }
        }
@@ -1328,11 +1325,9 @@ static int enc28j60_net_open(struct net_device *dev)
                printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
 
        if (!is_valid_ether_addr(dev->dev_addr)) {
-               if (netif_msg_ifup(priv)) {
-                       DECLARE_MAC_BUF(mac);
-                       dev_err(&dev->dev, "invalid MAC address %s\n",
-                               print_mac(mac, dev->dev_addr));
-               }
+               if (netif_msg_ifup(priv))
+                       dev_err(&dev->dev, "invalid MAC address %pM\n",
+                               dev->dev_addr);
                return -EADDRNOTAVAIL;
        }
        /* Reset the hardware here (and take it out of low power mode) */
@@ -1453,7 +1448,7 @@ enc28j60_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
        strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
        strlcpy(info->version, DRV_VERSION, sizeof(info->version));
        strlcpy(info->bus_info,
-               dev->dev.parent->bus_id, sizeof(info->bus_info));
+               dev_name(dev->dev.parent), sizeof(info->bus_info));
 }
 
 static int
index 180e968dc54d87401eaa174c30a724223425d4bf..8594d7f8fe66b121fa1fa5429653cac28a7389eb 100644 (file)
@@ -951,7 +951,6 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
                }
 
                skb->dev = enic->netdev;
-               enic->netdev->last_rx = jiffies;
 
                if (enic->vlan_group && vlan_stripped) {
 
index 95184b9108ef18fec0bbffda0518c4b9754c64c8..e5fc9384f8f51891eefe153fdab71ca7fa7b98c7 100644 (file)
@@ -90,11 +90,8 @@ int enic_get_vnic_config(struct enic *enic)
 
        c->intr_timer = min_t(u16, VNIC_INTR_TIMER_MAX, c->intr_timer);
 
-       printk(KERN_INFO PFX "vNIC MAC addr %02x:%02x:%02x:%02x:%02x:%02x "
-               "wq/rq %d/%d\n",
-               enic->mac_addr[0], enic->mac_addr[1], enic->mac_addr[2],
-               enic->mac_addr[3], enic->mac_addr[4], enic->mac_addr[5],
-               c->wq_desc_count, c->rq_desc_count);
+       printk(KERN_INFO PFX "vNIC MAC addr %pM wq/rq %d/%d\n",
+               enic->mac_addr, c->wq_desc_count, c->rq_desc_count);
        printk(KERN_INFO PFX "vNIC mtu %d csum tx/rx %d/%d tso/lro %d/%d "
                "intr timer %d\n",
                c->mtu, ENIC_SETTING(enic, TXCSUM),
index 4d104f5c30f97b454880dfaefb147c12656de09a..9afd33c7188d7c20bfc055013b4eb05670984171 100644 (file)
@@ -489,10 +489,7 @@ void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
 
        err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
        if (err)
-               printk(KERN_ERR
-                       "Can't add addr [%02x:%02x:%02x:%02x:%02x:%02x], %d\n",
-                       addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
-                       err);
+               printk(KERN_ERR "Can't add addr [%pM], %d\n", addr, err);
 }
 
 void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
@@ -507,10 +504,7 @@ void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
 
        err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait);
        if (err)
-               printk(KERN_ERR
-                       "Can't del addr [%02x:%02x:%02x:%02x:%02x:%02x], %d\n",
-                       addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
-                       err);
+               printk(KERN_ERR "Can't del addr [%pM], %d\n", addr, err);
 }
 
 int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
index 76118ddd104272f82f194746739ceacbb102c017..4a951b8cb4d73cb1db4ca264efb895a6b6529685 100644 (file)
@@ -322,7 +322,6 @@ static int __devinit epic_init_one (struct pci_dev *pdev,
        int i, ret, option = 0, duplex = 0;
        void *ring_space;
        dma_addr_t ring_dma;
-       DECLARE_MAC_BUF(mac);
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -364,7 +363,7 @@ static int __devinit epic_init_one (struct pci_dev *pdev,
        ioaddr = pci_resource_start (pdev, 0);
 #else
        ioaddr = pci_resource_start (pdev, 1);
-       ioaddr = (long) ioremap (ioaddr, pci_resource_len (pdev, 1));
+       ioaddr = (long) pci_ioremap_bar(pdev, 1);
        if (!ioaddr) {
                dev_err(&pdev->dev, "ioremap failed\n");
                goto err_out_free_netdev;
@@ -372,7 +371,7 @@ static int __devinit epic_init_one (struct pci_dev *pdev,
 #endif
 
        pci_set_drvdata(pdev, dev);
-       ep = dev->priv;
+       ep = netdev_priv(dev);
        ep->mii.dev = dev;
        ep->mii.mdio_read = mdio_read;
        ep->mii.mdio_write = mdio_write;
@@ -499,9 +498,9 @@ static int __devinit epic_init_one (struct pci_dev *pdev,
        if (ret < 0)
                goto err_out_unmap_rx;
 
-       printk(KERN_INFO "%s: %s at %#lx, IRQ %d, %s\n",
+       printk(KERN_INFO "%s: %s at %#lx, IRQ %d, %pM\n",
               dev->name, pci_id_tbl[chip_idx].name, ioaddr, dev->irq,
-              print_mac(mac, dev->dev_addr));
+              dev->dev_addr);
 
 out:
        return ret;
@@ -655,7 +654,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int loc, int value)
 
 static int epic_open(struct net_device *dev)
 {
-       struct epic_private *ep = dev->priv;
+       struct epic_private *ep = netdev_priv(dev);
        long ioaddr = dev->base_addr;
        int i;
        int retval;
@@ -767,7 +766,7 @@ static int epic_open(struct net_device *dev)
 static void epic_pause(struct net_device *dev)
 {
        long ioaddr = dev->base_addr;
-       struct epic_private *ep = dev->priv;
+       struct epic_private *ep = netdev_priv(dev);
 
        netif_stop_queue (dev);
 
@@ -790,7 +789,7 @@ static void epic_pause(struct net_device *dev)
 static void epic_restart(struct net_device *dev)
 {
        long ioaddr = dev->base_addr;
-       struct epic_private *ep = dev->priv;
+       struct epic_private *ep = netdev_priv(dev);
        int i;
 
        /* Soft reset the chip. */
@@ -842,7 +841,7 @@ static void epic_restart(struct net_device *dev)
 
 static void check_media(struct net_device *dev)
 {
-       struct epic_private *ep = dev->priv;
+       struct epic_private *ep = netdev_priv(dev);
        long ioaddr = dev->base_addr;
        int mii_lpa = ep->mii_phy_cnt ? mdio_read(dev, ep->phys[0], MII_LPA) : 0;
        int negotiated = mii_lpa & ep->mii.advertising;
@@ -864,7 +863,7 @@ static void check_media(struct net_device *dev)
 static void epic_timer(unsigned long data)
 {
        struct net_device *dev = (struct net_device *)data;
-       struct epic_private *ep = dev->priv;
+       struct epic_private *ep = netdev_priv(dev);
        long ioaddr = dev->base_addr;
        int next_tick = 5*HZ;
 
@@ -885,7 +884,7 @@ static void epic_timer(unsigned long data)
 
 static void epic_tx_timeout(struct net_device *dev)
 {
-       struct epic_private *ep = dev->priv;
+       struct epic_private *ep = netdev_priv(dev);
        long ioaddr = dev->base_addr;
 
        if (debug > 0) {
@@ -914,7 +913,7 @@ static void epic_tx_timeout(struct net_device *dev)
 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
 static void epic_init_ring(struct net_device *dev)
 {
-       struct epic_private *ep = dev->priv;
+       struct epic_private *ep = netdev_priv(dev);
        int i;
 
        ep->tx_full = 0;
@@ -960,7 +959,7 @@ static void epic_init_ring(struct net_device *dev)
 
 static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct epic_private *ep = dev->priv;
+       struct epic_private *ep = netdev_priv(dev);
        int entry, free_count;
        u32 ctrl_word;
        unsigned long flags;
@@ -1088,7 +1087,7 @@ static void epic_tx(struct net_device *dev, struct epic_private *ep)
 static irqreturn_t epic_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
-       struct epic_private *ep = dev->priv;
+       struct epic_private *ep = netdev_priv(dev);
        long ioaddr = dev->base_addr;
        unsigned int handled = 0;
        int status;
@@ -1156,7 +1155,7 @@ out:
 
 static int epic_rx(struct net_device *dev, int budget)
 {
-       struct epic_private *ep = dev->priv;
+       struct epic_private *ep = netdev_priv(dev);
        int entry = ep->cur_rx % RX_RING_SIZE;
        int rx_work_limit = ep->dirty_rx + RX_RING_SIZE - ep->cur_rx;
        int work_done = 0;
@@ -1223,7 +1222,6 @@ static int epic_rx(struct net_device *dev, int budget)
                        }
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_receive_skb(skb);
-                       dev->last_rx = jiffies;
                        ep->stats.rx_packets++;
                        ep->stats.rx_bytes += pkt_len;
                }
@@ -1308,7 +1306,7 @@ rx_action:
 static int epic_close(struct net_device *dev)
 {
        long ioaddr = dev->base_addr;
-       struct epic_private *ep = dev->priv;
+       struct epic_private *ep = netdev_priv(dev);
        struct sk_buff *skb;
        int i;
 
@@ -1358,7 +1356,7 @@ static int epic_close(struct net_device *dev)
 
 static struct net_device_stats *epic_get_stats(struct net_device *dev)
 {
-       struct epic_private *ep = dev->priv;
+       struct epic_private *ep = netdev_priv(dev);
        long ioaddr = dev->base_addr;
 
        if (netif_running(dev)) {
@@ -1379,7 +1377,7 @@ static struct net_device_stats *epic_get_stats(struct net_device *dev)
 static void set_rx_mode(struct net_device *dev)
 {
        long ioaddr = dev->base_addr;
-       struct epic_private *ep = dev->priv;
+       struct epic_private *ep = netdev_priv(dev);
        unsigned char mc_filter[8];              /* Multicast hash filter */
        int i;
 
@@ -1418,7 +1416,7 @@ static void set_rx_mode(struct net_device *dev)
 
 static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info)
 {
-       struct epic_private *np = dev->priv;
+       struct epic_private *np = netdev_priv(dev);
 
        strcpy (info->driver, DRV_NAME);
        strcpy (info->version, DRV_VERSION);
@@ -1427,7 +1425,7 @@ static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *
 
 static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-       struct epic_private *np = dev->priv;
+       struct epic_private *np = netdev_priv(dev);
        int rc;
 
        spin_lock_irq(&np->lock);
@@ -1439,7 +1437,7 @@ static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-       struct epic_private *np = dev->priv;
+       struct epic_private *np = netdev_priv(dev);
        int rc;
 
        spin_lock_irq(&np->lock);
@@ -1451,13 +1449,13 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 static int netdev_nway_reset(struct net_device *dev)
 {
-       struct epic_private *np = dev->priv;
+       struct epic_private *np = netdev_priv(dev);
        return mii_nway_restart(&np->mii);
 }
 
 static u32 netdev_get_link(struct net_device *dev)
 {
-       struct epic_private *np = dev->priv;
+       struct epic_private *np = netdev_priv(dev);
        return mii_link_ok(&np->mii);
 }
 
@@ -1506,7 +1504,7 @@ static const struct ethtool_ops netdev_ethtool_ops = {
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-       struct epic_private *np = dev->priv;
+       struct epic_private *np = netdev_priv(dev);
        long ioaddr = dev->base_addr;
        struct mii_ioctl_data *data = if_mii(rq);
        int rc;
@@ -1534,7 +1532,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 static void __devexit epic_remove_one (struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
-       struct epic_private *ep = dev->priv;
+       struct epic_private *ep = netdev_priv(dev);
 
        pci_free_consistent(pdev, TX_TOTAL_SIZE, ep->tx_ring, ep->tx_ring_dma);
        pci_free_consistent(pdev, RX_TOTAL_SIZE, ep->rx_ring, ep->rx_ring_dma);
index deefa51b8c31b652cdbbc1509dfcb6d006f0d915..e7df9f4a183deaf19afe5ca633467e931c168ec5 100644 (file)
@@ -179,7 +179,6 @@ static int __init es_probe1(struct net_device *dev, int ioaddr)
 {
        int i, retval;
        unsigned long eisa_id;
-       DECLARE_MAC_BUF(mac);
 
        if (!request_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT, "es3210"))
                return -ENODEV;
@@ -205,14 +204,14 @@ static int __init es_probe1(struct net_device *dev, int ioaddr)
        if (dev->dev_addr[0] != ES_ADDR0 ||
            dev->dev_addr[1] != ES_ADDR1 ||
            dev->dev_addr[2] != ES_ADDR2) {
-               printk("es3210.c: card not found %s (invalid_prefix).\n",
-                      print_mac(mac, dev->dev_addr));
+               printk("es3210.c: card not found %pM (invalid_prefix).\n",
+                      dev->dev_addr);
                retval = -ENODEV;
                goto out;
        }
 
-       printk("es3210.c: ES3210 rev. %ld at %#x, node %s",
-              eisa_id>>24, ioaddr, print_mac(mac, dev->dev_addr));
+       printk("es3210.c: ES3210 rev. %ld at %#x, node %pM",
+              eisa_id>>24, ioaddr, dev->dev_addr);
 
        /* Snarf the interrupt now. */
        if (dev->irq == 0) {
index bee8b3fbc56591c9d8f493ae2295dba5ba849793..8d9fe4dd346f24bb505b81bf2d314ebf17ba0a65 100644 (file)
@@ -1205,7 +1205,6 @@ static void eth16i_rx(struct net_device *dev)
                                printk(KERN_DEBUG ".\n");
                        }
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                        dev->stats.rx_bytes += pkt_len;
 
@@ -1466,7 +1465,7 @@ void __exit cleanup_module(void)
        for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++) {
                struct net_device *dev = dev_eth16i[this_dev];
 
-               if(dev->priv) {
+               if (netdev_priv(dev)) {
                        unregister_netdev(dev);
                        free_irq(dev->irq, dev);
                        release_region(dev->base_addr, ETH16I_IO_EXTENT);
index 593a120e31b2bdc406dd8e3e6cfd8aeca27d1798..f3b664aafb8269871c69606cc3ff26bbd05d36c2 100644 (file)
@@ -396,7 +396,6 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
        u_long mem_start, shmem_length;
        u_char cr, cmr, icr, nicsr, lemac, hard_strapped = 0;
        u_char eeprom_image[EEPROM_MAX], chksum, eisa_cr = 0;
-       DECLARE_MAC_BUF(mac);
 
        /*
        ** Stop the EWRK3. Enable the DBR ROM. Disable interrupts and remote boot.
@@ -461,7 +460,7 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
        if (lemac != LeMAC2)
                DevicePresent(iobase);  /* need after EWRK3_INIT */
        status = get_hw_addr(dev, eeprom_image, lemac);
-       printk("%s\n", print_mac(mac, dev->dev_addr));
+       printk("%pM\n", dev->dev_addr);
 
        if (status) {
                printk("      which has an EEPROM CRC error.\n");
@@ -646,10 +645,8 @@ static int ewrk3_open(struct net_device *dev)
                        ewrk3_init(dev);
 
                        if (ewrk3_debug > 1) {
-                               DECLARE_MAC_BUF(mac);
                                printk("%s: ewrk3 open with irq %d\n", dev->name, dev->irq);
-                               printk("  physical address: %s\n",
-                                      print_mac(mac, dev->dev_addr));
+                               printk("  physical address: %pM\n", dev->dev_addr);
                                if (lp->shmem_length == 0) {
                                        printk("  no shared memory, I/O only mode\n");
                                } else {
@@ -1029,7 +1026,6 @@ static int ewrk3_rx(struct net_device *dev)
                                                /*
                                                   ** Update stats
                                                 */
-                                               dev->last_rx = jiffies;
                                                dev->stats.rx_packets++;
                                                dev->stats.rx_bytes += pkt_len;
                                        } else {
index b455ae931f7ac3f76d4efa6d506269f77a3c111c..31ab1ff623fcfca4575939569dfdeb79dc6dd218 100644 (file)
@@ -486,7 +486,6 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev,
 #else
        int bar = 1;
 #endif
-       DECLARE_MAC_BUF(mac);
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -665,9 +664,9 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev,
        if (err)
                goto err_out_free_tx;
 
-       printk(KERN_INFO "%s: %s at %p, %s, IRQ %d.\n",
+       printk(KERN_INFO "%s: %s at %p, %pM, IRQ %d.\n",
               dev->name, skel_netdrv_tbl[chip_id].chip_name, ioaddr,
-              print_mac(mac, dev->dev_addr), irq);
+              dev->dev_addr, irq);
 
        return 0;
 
@@ -1727,7 +1726,6 @@ static int netdev_rx(struct net_device *dev)
                        }
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        np->stats.rx_packets++;
                        np->stats.rx_bytes += pkt_len;
                }
index ecd5c71a7a8a5f6470f7362a051434f61529e5b3..7e33c129d51cb4d936fa16ea146b55721fa660ce 100644 (file)
@@ -1155,7 +1155,7 @@ static phy_info_t const phy_info_ks8721bl = {
 
 static void mii_parse_dp8384x_sr2(uint mii_reg, struct net_device *dev)
 {
-       struct fec_enet_private *fep = dev->priv;
+       struct fec_enet_private *fep = netdev_priv(dev);
        volatile uint *s = &(fep->phy_status);
 
        *s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC);
@@ -2562,7 +2562,6 @@ static int __init fec_enet_module_init(void)
 {
        struct net_device *dev;
        int i, err;
-       DECLARE_MAC_BUF(mac);
 
        printk("FEC ENET Version 0.2\n");
 
@@ -2581,8 +2580,7 @@ static int __init fec_enet_module_init(void)
                        return -EIO;
                }
 
-               printk("%s: ethernet %s\n",
-                      dev->name, print_mac(mac, dev->dev_addr));
+               printk("%s: ethernet %pM\n", dev->name, dev->dev_addr);
        }
        return 0;
 }
index aec3b97e794d865d9de5373e6a45c072069ad6f6..cd8e98b45ec50d9e253dcc9251ce8e62f8703ab6 100644 (file)
@@ -216,7 +216,7 @@ static int mpc52xx_fec_init_phy(struct net_device *dev)
        struct phy_device *phydev;
        char phy_id[BUS_ID_SIZE];
 
-       snprintf(phy_id, BUS_ID_SIZE, "%x:%02x",
+       snprintf(phy_id, sizeof(phy_id), "%x:%02x",
                        (unsigned int)dev->base_addr, priv->phy_addr);
 
        priv->link = PHY_DOWN;
@@ -487,7 +487,6 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id)
                        rskb->protocol = eth_type_trans(rskb, dev);
 
                        netif_rx(rskb);
-                       dev->last_rx = jiffies;
                } else {
                        /* Can't get a new one : reuse the same & drop pkt */
                        dev_notice(&dev->dev, "Memory squeeze, dropping packet.\n");
index cc7328b1552136f0fa7c8e8f5587b61e110f216b..765210ea097d25a2077b618d85abd226377d5715 100644 (file)
@@ -818,7 +818,7 @@ struct fe_priv {
  * Maximum number of loops until we assume that a bit in the irq mask
  * is stuck. Overridable with module param.
  */
-static int max_interrupt_work = 5;
+static int max_interrupt_work = 15;
 
 /*
  * Optimization can be either throuput mode or cpu mode
@@ -2735,7 +2735,6 @@ static int nv_rx_process(struct net_device *dev, int limit)
 #else
                netif_rx(skb);
 #endif
-               dev->last_rx = jiffies;
                dev->stats.rx_packets++;
                dev->stats.rx_bytes += len;
 next_pkt:
@@ -2848,7 +2847,6 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
                                }
                        }
 
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                        dev->stats.rx_bytes += len;
                } else {
@@ -5420,7 +5418,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
        u32 powerstate, txreg;
        u32 phystate_orig = 0, phystate;
        int phyinitialized = 0;
-       DECLARE_MAC_BUF(mac);
        static int printed_version;
 
        if (!printed_version++)
@@ -5653,8 +5650,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                 * to 01:23:45:67:89:ab
                 */
                dev_printk(KERN_ERR, &pci_dev->dev,
-                       "Invalid Mac address detected: %s\n",
-                       print_mac(mac, dev->dev_addr));
+                       "Invalid Mac address detected: %pM\n",
+                       dev->dev_addr);
                dev_printk(KERN_ERR, &pci_dev->dev,
                        "Please complain to your hardware vendor. Switching to a random MAC.\n");
                dev->dev_addr[0] = 0x00;
@@ -5663,8 +5660,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                get_random_bytes(&dev->dev_addr[3], 3);
        }
 
-       dprintk(KERN_DEBUG "%s: MAC Address %s\n",
-               pci_name(pci_dev), print_mac(mac, dev->dev_addr));
+       dprintk(KERN_DEBUG "%s: MAC Address %pM\n",
+               pci_name(pci_dev), dev->dev_addr);
 
        /* set mac address */
        nv_copy_mac_to_hw(dev);
index a6f49d02578711ed090a7625a34152e4b36655bc..df66d620b11555385642935d1a73f651981b52b0 100644 (file)
@@ -1117,10 +1117,7 @@ static int __devinit fs_enet_probe(struct of_device *ofdev,
        if (ret)
                goto out_free_bd;
 
-       printk(KERN_INFO "%s: fs_enet: %02x:%02x:%02x:%02x:%02x:%02x\n",
-              ndev->name,
-              ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
-              ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
+       printk(KERN_INFO "%s: fs_enet: %pM\n", ndev->name, ndev->dev_addr);
 
        return 0;
 
index c4af949bf860d81ffd69ce6ff6eceb9cf0c8a69a..2635f5bed77f41b6a8242891229e8ca3d4816a75 100644 (file)
@@ -162,7 +162,6 @@ static int gfar_probe(struct platform_device *pdev)
        struct gianfar_platform_data *einfo;
        struct resource *r;
        int err = 0, irq;
-       DECLARE_MAC_BUF(mac);
 
        einfo = (struct gianfar_platform_data *) pdev->dev.platform_data;
 
@@ -364,8 +363,7 @@ static int gfar_probe(struct platform_device *pdev)
        gfar_init_sysfs(dev);
 
        /* Print out the device info */
-       printk(KERN_INFO DEVICE_NAME "%s\n",
-              dev->name, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO DEVICE_NAME "%pM\n", dev->name, dev->dev_addr);
 
        /* Even more device info helps when determining which kernel */
        /* provided which set of benchmarks. */
@@ -548,7 +546,7 @@ static int init_phy(struct net_device *dev)
        priv->oldspeed = 0;
        priv->oldduplex = -1;
 
-       snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, priv->einfo->bus_id, priv->einfo->phy_id);
+       snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, priv->einfo->bus_id, priv->einfo->phy_id);
 
        interface = gfar_get_interface(dev);
 
@@ -1696,8 +1694,6 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
                        dev->stats.rx_bytes += pkt_len;
                }
 
-               dev->last_rx = jiffies;
-
                priv->rx_skbuff[priv->skb_currx] = newskb;
 
                /* Setup the new bdp */
index 3199526bcecbab3f879f9cd56507c570305a8c2f..77f2b2934e6752420ad156139b0525741b498189 100644 (file)
@@ -582,7 +582,6 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
        void *ring_space;
        dma_addr_t ring_dma;
        int ret = -ENOMEM;
-       DECLARE_MAC_BUF(mac);
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -744,9 +743,9 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
                goto err_out_unmap_rx;
        }
 
-       printk(KERN_INFO "%s: %s type %x at %p, %s, IRQ %d.\n",
+       printk(KERN_INFO "%s: %s type %x at %p, %pM, IRQ %d.\n",
                   dev->name, chip_tbl[chip_id].name, readl(ioaddr + ChipRev),
-                  ioaddr, print_mac(mac, dev->dev_addr), irq);
+                  ioaddr, dev->dev_addr, irq);
        i = readb(ioaddr + PCIClkMeas);
        printk(KERN_INFO "%s:  %d-bit %d Mhz PCI bus (%d), Virtual Jumpers "
                   "%2.2x, LPA %4.4x.\n",
@@ -1646,7 +1645,6 @@ static int hamachi_rx(struct net_device *dev)
 #endif  /* RX_CHECKSUM */
 
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        hmp->stats.rx_packets++;
                }
                entry = (++hmp->cur_rx) % RX_RING_SIZE;
index 0f501d2ca93560553bed346b225cc53793b5e17a..50f1e172ee8f9556a09e7fbdb1ab05f69c09f74e 100644 (file)
@@ -373,7 +373,6 @@ static void sp_bump(struct sixpack *sp, char cmd)
        memcpy(ptr, sp->cooked_buf + 1, count);
        skb->protocol = ax25_type_trans(skb, sp->dev);
        netif_rx(skb);
-       sp->dev->last_rx = jiffies;
        sp->dev->stats.rx_packets++;
 
        return;
index 00bc7fbb6b374687ebd45f79a84cee5ad472bcaa..81a65e3a1c053fe070e9a3c8985ef6f909439801 100644 (file)
@@ -555,7 +555,6 @@ static void do_rxpacket(struct net_device *dev)
        memcpy(cp, bc->hdlcrx.buf, pktlen - 1);
        skb->protocol = ax25_type_trans(skb, dev);
        netif_rx(skb);
-       dev->last_rx = jiffies;
        bc->stats.rx_packets++;
 }
 
index 58f4b1d7bf1fc303d5b962b9820aa423c943168b..46f8f3390e7d1806c038f791f0f103c744c09830 100644 (file)
@@ -230,7 +230,6 @@ static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ty
 
        skb->protocol = ax25_type_trans(skb, dev);
        netif_rx(skb);
-       dev->last_rx = jiffies;
 unlock:
 
        rcu_read_unlock();
@@ -441,16 +440,15 @@ static int bpq_seq_show(struct seq_file *seq, void *v)
                         "dev   ether      destination        accept from\n");
        else {
                const struct bpqdev *bpqdev = v;
-               DECLARE_MAC_BUF(mac);
 
-               seq_printf(seq, "%-5s %-10s %s  ",
+               seq_printf(seq, "%-5s %-10s %pM  ",
                        bpqdev->axdev->name, bpqdev->ethdev->name,
-                       print_mac(mac, bpqdev->dest_addr));
+                       bpqdev->dest_addr);
 
                if (is_multicast_ether_addr(bpqdev->acpt_addr))
                        seq_printf(seq, "*\n");
                else
-                       seq_printf(seq, "%s\n", print_mac(mac, bpqdev->acpt_addr));
+                       seq_printf(seq, "%pM\n", bpqdev->acpt_addr);
 
        }
        return 0;
index e8cfadefa4b6751dbb74bd663a0f101e76a98d54..7e46114422375927775044fe691803c84d1f1858 100644 (file)
@@ -1283,7 +1283,6 @@ static void rx_bh(struct work_struct *ugli_api)
                        memcpy(&data[1], priv->rx_buf[i], cb);
                        skb->protocol = ax25_type_trans(skb, priv->dev);
                        netif_rx(skb);
-                       priv->dev->last_rx = jiffies;
                        priv->stats.rx_packets++;
                        priv->stats.rx_bytes += cb;
                }
index c258a0586e611d641c134f53114c76df0025ec66..8eba61a1d4abc3ff7365b08d33f4d70c2d368819 100644 (file)
@@ -162,7 +162,6 @@ static void hdlc_rx_flag(struct net_device *dev, struct hdlcdrv_state *s)
        memcpy(cp, s->hdlcrx.buffer, pkt_len - 1);
        skb->protocol = ax25_type_trans(skb, dev);
        netif_rx(skb);
-       dev->last_rx = jiffies;
        s->stats.rx_packets++;
 }
 
index b8e25c4624d2c2db3d6e84bb90e7b7cd55261a6e..7570c73f18c09550ad27eaffa872fdd4a05bcda5 100644 (file)
@@ -303,7 +303,6 @@ static void ax_bump(struct mkiss *ax)
        memcpy(skb_put(skb,count), ax->rbuff, count);
        skb->protocol = ax25_type_trans(skb, ax->dev);
        netif_rx(skb);
-       ax->dev->last_rx = jiffies;
        ax->stats.rx_packets++;
        ax->stats.rx_bytes += count;
        spin_unlock_bh(&ax->buflock);
index c17e39bc546007cda47673ead55580e4e6b22357..802d1c7c4af1ebf6beca6a99bdb747d3ca22db1c 100644 (file)
@@ -1627,7 +1627,6 @@ static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb)
        skb->protocol = ax25_type_trans(skb, scc->dev);
        
        netif_rx(skb);
-       scc->dev->last_rx = jiffies;
        return;
 }
 
index 1c942862a3f4944710de74c546cba66943b8b81a..5407f7486c9c00cdc310962e237284897eac9113 100644 (file)
@@ -515,7 +515,6 @@ static inline void yam_rx_flag(struct net_device *dev, struct yam_port *yp)
                                memcpy(cp, yp->rx_buf, pkt_len - 1);
                                skb->protocol = ax25_type_trans(skb, dev);
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                                ++yp->stats.rx_packets;
                        }
                }
index fbbd3e660c2731800bf6b7e136a62980bc51032f..9026fd6ea0ff10d69ae866a14ee7bfe9861451cf 100644 (file)
@@ -166,7 +166,6 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr)
        const char name[] = "HP-PC-LAN+";
        int mem_start;
        static unsigned version_printed;
-       DECLARE_MAC_BUF(mac);
 
        if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME))
                return -EBUSY;
@@ -193,7 +192,7 @@ static int __init hpp_probe1(struct net_device *dev, int ioaddr)
        }
        checksum += inb(ioaddr + 14);
 
-       printk("%s", print_mac(mac, dev->dev_addr));
+       printk("%pM", dev->dev_addr);
 
        if (checksum != 0xff) {
                printk(" bad checksum %2.2x.\n", checksum);
index 0a8c64930ad305fc756d0dfb7addffff50d406a2..3669194f10630c7da9919645dadf4902f7e781c5 100644 (file)
@@ -127,7 +127,6 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr)
        int i, retval, board_id, wordmode;
        const char *name;
        static unsigned version_printed;
-       DECLARE_MAC_BUF(mac);
 
        if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME))
                return -EBUSY;
@@ -161,7 +160,7 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr)
        for(i = 0; i < ETHER_ADDR_LEN; i++)
                dev->dev_addr[i] = inb(ioaddr + i);
 
-       printk(" %s", print_mac(mac, dev->dev_addr));
+       printk(" %pM", dev->dev_addr);
 
        /* Snarf the interrupt now.  Someday this could be moved to open(). */
        if (dev->irq < 2) {
index 571dd80fb85009910f6a49d3cda27baa085b54f1..4dda9b043b134358292b60426580a752db43cff2 100644 (file)
@@ -1834,7 +1834,6 @@ static void hp100_rx(struct net_device *dev)
                                        ptr[9], ptr[10], ptr[11]);
 #endif
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        lp->stats.rx_packets++;
                        lp->stats.rx_bytes += pkt_len;
                }
@@ -1925,7 +1924,6 @@ static void hp100_rx_bm(struct net_device *dev)
 
                                netif_rx(ptr->skb);     /* Up and away... */
 
-                               dev->last_rx = jiffies;
                                lp->stats.rx_packets++;
                                lp->stats.rx_bytes += pkt_len;
                        }
@@ -2093,9 +2091,8 @@ static void hp100_set_multicast_list(struct net_device *dev)
                                addrs = dmi->dmi_addr;
                                if ((*addrs & 0x01) == 0x01) {  /* multicast address? */
 #ifdef HP100_DEBUG
-                                       DECLARE_MAC_BUF(mac);
-                                       printk("hp100: %s: multicast = %s, ",
-                                                    dev->name, print_mac(mac, addrs));
+                                       printk("hp100: %s: multicast = %pM, ",
+                                                    dev->name, addrs);
 #endif
                                        for (j = idx = 0; j < 6; j++) {
                                                idx ^= *addrs++ & 0x3f;
index b96cf2dcb10932bf7a6758fcd399dba1385b50f1..b0ae0766ea4e06f7470150a4ea3e7f9817c1b262 100644 (file)
@@ -103,7 +103,6 @@ static int __devinit hydra_init(struct zorro_dev *z)
     int start_page, stop_page;
     int j;
     int err;
-    DECLARE_MAC_BUF(mac);
 
     static u32 hydra_offsets[16] = {
        0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
@@ -163,8 +162,8 @@ static int __devinit hydra_init(struct zorro_dev *z)
     zorro_set_drvdata(z, dev);
 
     printk(KERN_INFO "%s: Hydra at 0x%08lx, address "
-          "%s (hydra.c " HYDRA_VERSION ")\n",
-          dev->name, z->resource.start, print_mac(mac, dev->dev_addr));
+          "%pM (hydra.c " HYDRA_VERSION ")\n",
+          dev->name, z->resource.start, dev->dev_addr);
 
     return 0;
 }
index 901212aa37cbf7a55be095d372b47865d9ebb1df..87a706694fb35f6519e4933944b06df429849d48 100644 (file)
@@ -396,9 +396,7 @@ static void emac_hash_mc(struct emac_instance *dev)
 
        for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) {
                int slot, reg, mask;
-               DBG2(dev, "mc %02x:%02x:%02x:%02x:%02x:%02x" NL,
-                    dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2],
-                    dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]);
+               DBG2(dev, "mc %pM" NL, dmi->dmi_addr);
 
                slot = EMAC_XAHT_CRC_TO_SLOT(dev, ether_crc(ETH_ALEN, dmi->dmi_addr));
                reg = EMAC_XAHT_SLOT_TO_REG(dev, slot);
@@ -2865,11 +2863,8 @@ static int __devinit emac_probe(struct of_device *ofdev,
        wake_up_all(&emac_probe_wait);
 
 
-       printk(KERN_INFO
-              "%s: EMAC-%d %s, MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
-              ndev->name, dev->cell_index, np->full_name,
-              ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
-              ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
+       printk(KERN_INFO "%s: EMAC-%d %s, MAC %pM\n",
+              ndev->name, dev->cell_index, np->full_name, ndev->dev_addr);
 
        if (dev->phy_mode == PHY_MODE_SGMII)
                printk(KERN_NOTICE "%s: in SGMII mode\n", ndev->name);
index f02764725a221fdde54b43ea9be1e7d65c8e8b75..5b5bf9f9861ac2f63ef8f9db6bca6cfd945fba34 100644 (file)
@@ -605,7 +605,6 @@ static void irqrx_handler(struct net_device *dev)
                                skb->ip_summed = CHECKSUM_NONE;
 
                                /* bookkeeping */
-                               dev->last_rx = jiffies;
                                dev->stats.rx_packets++;
                                dev->stats.rx_bytes += rda.length;
 
@@ -914,7 +913,6 @@ static int __devinit ibmlana_init_one(struct device *kdev)
        int base = 0, irq = 0, iobase = 0, memlen = 0;
        ibmlana_priv *priv;
        ibmlana_medium medium;
-       DECLARE_MAC_BUF(mac);
 
        dev = alloc_etherdev(sizeof(ibmlana_priv));
        if (!dev)
@@ -990,10 +988,10 @@ static int __devinit ibmlana_init_one(struct device *kdev)
        /* print config */
 
        printk(KERN_INFO "%s: IRQ %d, I/O %#lx, memory %#lx-%#lx, "
-              "MAC address %s.\n",
+              "MAC address %pM.\n",
               dev->name, priv->realirq, dev->base_addr,
               dev->mem_start, dev->mem_end - 1,
-              print_mac(mac, dev->dev_addr));
+              dev->dev_addr);
        printk(KERN_INFO "%s: %s medium\n", dev->name, MediaNames[priv->medium]);
 
        /* reset board */
index c2d57f836088c4ba38955de02a5ecd9408f478f8..02ecfdb4df6b796d54297efb99cea723f92e0676 100644 (file)
@@ -527,7 +527,7 @@ retry:
 
 static int ibmveth_open(struct net_device *netdev)
 {
-       struct ibmveth_adapter *adapter = netdev->priv;
+       struct ibmveth_adapter *adapter = netdev_priv(netdev);
        u64 mac_address = 0;
        int rxq_entries = 1;
        unsigned long lpar_rc;
@@ -666,7 +666,7 @@ static int ibmveth_open(struct net_device *netdev)
 
 static int ibmveth_close(struct net_device *netdev)
 {
-       struct ibmveth_adapter *adapter = netdev->priv;
+       struct ibmveth_adapter *adapter = netdev_priv(netdev);
        long lpar_rc;
 
        ibmveth_debug_printk("close starting\n");
@@ -722,7 +722,7 @@ static u32 netdev_get_link(struct net_device *dev) {
 
 static void ibmveth_set_rx_csum_flags(struct net_device *dev, u32 data)
 {
-       struct ibmveth_adapter *adapter = dev->priv;
+       struct ibmveth_adapter *adapter = netdev_priv(dev);
 
        if (data)
                adapter->rx_csum = 1;
@@ -741,7 +741,7 @@ static void ibmveth_set_rx_csum_flags(struct net_device *dev, u32 data)
 
 static void ibmveth_set_tx_csum_flags(struct net_device *dev, u32 data)
 {
-       struct ibmveth_adapter *adapter = dev->priv;
+       struct ibmveth_adapter *adapter = netdev_priv(dev);
 
        if (data) {
                dev->features |= NETIF_F_IP_CSUM;
@@ -753,7 +753,7 @@ static void ibmveth_set_tx_csum_flags(struct net_device *dev, u32 data)
 static int ibmveth_set_csum_offload(struct net_device *dev, u32 data,
                                    void (*done) (struct net_device *, u32))
 {
-       struct ibmveth_adapter *adapter = dev->priv;
+       struct ibmveth_adapter *adapter = netdev_priv(dev);
        u64 set_attr, clr_attr, ret_attr;
        long ret;
        int rc1 = 0, rc2 = 0;
@@ -805,7 +805,7 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data,
 
 static int ibmveth_set_rx_csum(struct net_device *dev, u32 data)
 {
-       struct ibmveth_adapter *adapter = dev->priv;
+       struct ibmveth_adapter *adapter = netdev_priv(dev);
 
        if ((data && adapter->rx_csum) || (!data && !adapter->rx_csum))
                return 0;
@@ -815,7 +815,7 @@ static int ibmveth_set_rx_csum(struct net_device *dev, u32 data)
 
 static int ibmveth_set_tx_csum(struct net_device *dev, u32 data)
 {
-       struct ibmveth_adapter *adapter = dev->priv;
+       struct ibmveth_adapter *adapter = netdev_priv(dev);
        int rc = 0;
 
        if (data && (dev->features & NETIF_F_IP_CSUM))
@@ -833,7 +833,7 @@ static int ibmveth_set_tx_csum(struct net_device *dev, u32 data)
 
 static u32 ibmveth_get_rx_csum(struct net_device *dev)
 {
-       struct ibmveth_adapter *adapter = dev->priv;
+       struct ibmveth_adapter *adapter = netdev_priv(dev);
        return adapter->rx_csum;
 }
 
@@ -862,7 +862,7 @@ static void ibmveth_get_ethtool_stats(struct net_device *dev,
                                      struct ethtool_stats *stats, u64 *data)
 {
        int i;
-       struct ibmveth_adapter *adapter = dev->priv;
+       struct ibmveth_adapter *adapter = netdev_priv(dev);
 
        for (i = 0; i < ARRAY_SIZE(ibmveth_stats); i++)
                data[i] = IBMVETH_GET_STAT(adapter, ibmveth_stats[i].offset);
@@ -889,7 +889,7 @@ static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
 static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
-       struct ibmveth_adapter *adapter = netdev->priv;
+       struct ibmveth_adapter *adapter = netdev_priv(netdev);
        union ibmveth_buf_desc desc;
        unsigned long lpar_rc;
        unsigned long correlator;
@@ -1014,7 +1014,6 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
                        netdev->stats.rx_packets++;
                        netdev->stats.rx_bytes += length;
                        frames_processed++;
-                       netdev->last_rx = jiffies;
                }
        } while (frames_processed < budget);
 
@@ -1045,7 +1044,7 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
 static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance)
 {
        struct net_device *netdev = dev_instance;
-       struct ibmveth_adapter *adapter = netdev->priv;
+       struct ibmveth_adapter *adapter = netdev_priv(netdev);
        unsigned long lpar_rc;
 
        if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
@@ -1059,7 +1058,7 @@ static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance)
 
 static void ibmveth_set_multicast_list(struct net_device *netdev)
 {
-       struct ibmveth_adapter *adapter = netdev->priv;
+       struct ibmveth_adapter *adapter = netdev_priv(netdev);
        unsigned long lpar_rc;
 
        if((netdev->flags & IFF_PROMISC) || (netdev->mc_count > adapter->mcastFilterSize)) {
@@ -1107,7 +1106,7 @@ static void ibmveth_set_multicast_list(struct net_device *netdev)
 
 static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
 {
-       struct ibmveth_adapter *adapter = dev->priv;
+       struct ibmveth_adapter *adapter = netdev_priv(dev);
        struct vio_dev *viodev = adapter->vdev;
        int new_mtu_oh = new_mtu + IBMVETH_BUFF_OH;
        int i;
@@ -1159,7 +1158,7 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void ibmveth_poll_controller(struct net_device *dev)
 {
-       ibmveth_replenish_task(dev->priv);
+       ibmveth_replenish_task(netdev_priv(dev));
        ibmveth_interrupt(dev->irq, dev);
 }
 #endif
@@ -1241,7 +1240,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
        if(!netdev)
                return -ENOMEM;
 
-       adapter = netdev->priv;
+       adapter = netdev_priv(netdev);
        dev->dev.driver_data = netdev;
 
        adapter->vdev = dev;
@@ -1337,7 +1336,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
 static int __devexit ibmveth_remove(struct vio_dev *dev)
 {
        struct net_device *netdev = dev->dev.driver_data;
-       struct ibmveth_adapter *adapter = netdev->priv;
+       struct ibmveth_adapter *adapter = netdev_priv(netdev);
        int i;
 
        for(i = 0; i<IbmVethNumBufferPools; i++)
@@ -1371,13 +1370,12 @@ static int ibmveth_show(struct seq_file *seq, void *v)
        struct ibmveth_adapter *adapter = seq->private;
        char *current_mac = ((char*) &adapter->netdev->dev_addr);
        char *firmware_mac = ((char*) &adapter->mac_addr) ;
-       DECLARE_MAC_BUF(mac);
 
        seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version);
 
        seq_printf(seq, "Unit Address:    0x%x\n", adapter->vdev->unit_address);
-       seq_printf(seq, "Current MAC:     %s\n", print_mac(mac, current_mac));
-       seq_printf(seq, "Firmware MAC:    %s\n", print_mac(mac, firmware_mac));
+       seq_printf(seq, "Current MAC:     %pM\n", current_mac);
+       seq_printf(seq, "Firmware MAC:    %pM\n", firmware_mac);
 
        seq_printf(seq, "\nAdapter Statistics:\n");
        seq_printf(seq, "  TX:  vio_map_single failres:      %ld\n", adapter->tx_map_failed);
@@ -1472,7 +1470,7 @@ const char * buf, size_t count)
                                                      kobj);
        struct net_device *netdev =
            container_of(kobj->parent, struct device, kobj)->driver_data;
-       struct ibmveth_adapter *adapter = netdev->priv;
+       struct ibmveth_adapter *adapter = netdev_priv(netdev);
        long value = simple_strtol(buf, NULL, 10);
        long rc;
 
index 89964fa739a031bb2a778298a96a11e1a30e8ad3..9b9066c5b0e132af2602f330a739bfe54a5b2c5c 100644 (file)
@@ -101,8 +101,8 @@ static const struct igb_stats igb_gstrings_stats[] = {
 };
 
 #define IGB_QUEUE_STATS_LEN \
-       ((((struct igb_adapter *)netdev->priv)->num_rx_queues + \
-        ((struct igb_adapter *)netdev->priv)->num_tx_queues) * \
+       ((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues + \
+        ((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues) * \
        (sizeof(struct igb_queue_stats) / sizeof(u64)))
 #define IGB_GLOBAL_STATS_LEN   \
        sizeof(igb_gstrings_stats) / sizeof(struct igb_stats)
index 1cbae85b142627facb0753ab2513b95587e9cfc2..5f954b01e21abc2597cf1f56f91e038bacab1f42 100644 (file)
@@ -1275,16 +1275,14 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 
        dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n");
        /* print bus type/speed/width info */
-       dev_info(&pdev->dev,
-                "%s: (PCIe:%s:%s) %02x:%02x:%02x:%02x:%02x:%02x\n",
+       dev_info(&pdev->dev, "%s: (PCIe:%s:%s) %pM\n",
                 netdev->name,
                 ((hw->bus.speed == e1000_bus_speed_2500)
                  ? "2.5Gb/s" : "unknown"),
                 ((hw->bus.width == e1000_bus_width_pcie_x4)
                  ? "Width x4" : (hw->bus.width == e1000_bus_width_pcie_x1)
                  ? "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]);
+                netdev->dev_addr);
 
        igb_read_part_num(hw, &part_num);
        dev_info(&pdev->dev, "%s: PBA No: %06x-%03x\n", netdev->name,
@@ -3942,8 +3940,6 @@ send_up:
 
                igb_receive_skb(rx_ring, staterr, rx_desc, skb);
 
-               netdev->last_rx = jiffies;
-
 next_desc:
                rx_desc->wb.upper.status_error = 0;
 
index 1f25263dc7ebb8f90066d7388bbd297bd8d82b26..170b12d1d70e49e2ab02918b41e1236bd9544a84 100644 (file)
@@ -390,11 +390,8 @@ static int nic_init(struct ioc3 *ioc3)
        }
 
        printk("Found %s NIC", type);
-       if (type != unknown) {
-               printk (" registration number %02x:%02x:%02x:%02x:%02x:%02x,"
-                       " CRC %02x", serial[0], serial[1], serial[2],
-                       serial[3], serial[4], serial[5], crc);
-       }
+       if (type != unknown)
+               printk (" registration number %pM, CRC %02x", serial, crc);
        printk(".\n");
 
        return 0;
@@ -443,12 +440,9 @@ static void ioc3_get_eaddr_nic(struct ioc3_private *ip)
  */
 static void ioc3_get_eaddr(struct ioc3_private *ip)
 {
-       DECLARE_MAC_BUF(mac);
-
        ioc3_get_eaddr_nic(ip);
 
-       printk("Ethernet address is %s.\n",
-              print_mac(mac, priv_netdev(ip)->dev_addr));
+       printk("Ethernet address is %pM.\n", priv_netdev(ip)->dev_addr);
 }
 
 static void __ioc3_set_mac_address(struct net_device *dev)
@@ -627,7 +621,6 @@ static inline void ioc3_rx(struct ioc3_private *ip)
                        rxb = (struct ioc3_erxbuf *) new_skb->data;
                        skb_reserve(new_skb, RX_OFFSET);
 
-                       priv_netdev(ip)->last_rx = jiffies;
                        ip->stats.rx_packets++;         /* Statistics */
                        ip->stats.rx_bytes += len;
                } else {
index 7373dafbb3f7d3f9d06ed71a785b840a5e236c87..24c777aff5c63df40eabcd8cd5665f6935b2ef31 100644 (file)
@@ -1222,7 +1222,6 @@ static void ipg_nic_rx_with_start_and_end(struct net_device *dev,
        skb->protocol = eth_type_trans(skb, dev);
        skb->ip_summed = CHECKSUM_NONE;
        netif_rx(skb);
-       dev->last_rx = jiffies;
        sp->rx_buff[entry] = NULL;
 }
 
@@ -1256,7 +1255,6 @@ static void ipg_nic_rx_with_start(struct net_device *dev,
        jumbo->skb = skb;
 
        sp->rx_buff[entry] = NULL;
-       dev->last_rx = jiffies;
 }
 
 static void ipg_nic_rx_with_end(struct net_device *dev,
@@ -1292,7 +1290,6 @@ static void ipg_nic_rx_with_end(struct net_device *dev,
                        }
                }
 
-               dev->last_rx = jiffies;
                jumbo->found_start = 0;
                jumbo->current_size = 0;
                jumbo->skb = NULL;
@@ -1325,7 +1322,6 @@ static void ipg_nic_rx_no_start_no_end(struct net_device *dev,
                                               skb->data, sp->rxfrag_size);
                                }
                        }
-                       dev->last_rx = jiffies;
                        ipg_nic_rx_free_skb(dev);
                }
        } else {
@@ -1494,11 +1490,6 @@ static int ipg_nic_rx(struct net_device *dev)
                         * when processing completes.
                         */
                        netif_rx(skb);
-
-                       /* Record frame receive time (jiffies = Linux
-                        * kernel current time stamp).
-                        */
-                       dev->last_rx = jiffies;
                }
 
                /* Assure RX buffer is not reused by IPG. */
index 2ff181861d2d05b51ccc9a1c8f8f55a5aa897027..3c58e67ef1e491c16af64cea5994cc4d88272bee 100644 (file)
@@ -292,7 +292,7 @@ static int ali_ircc_open(int i, chipio_t *info)
                return -ENOMEM;
        }
 
-       self = dev->priv;
+       self = netdev_priv(dev);
        self->netdev = dev;
        spin_lock_init(&self->lock);
    
@@ -665,7 +665,7 @@ static irqreturn_t ali_ircc_interrupt(int irq, void *dev_id)
                
        IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__);
                
-       self = dev->priv;
+       self = netdev_priv(dev);
        
        spin_lock(&self->lock);
        
@@ -1333,7 +1333,7 @@ static int ali_ircc_net_open(struct net_device *dev)
        
        IRDA_ASSERT(dev != NULL, return -1;);
        
-       self = (struct ali_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
        
        IRDA_ASSERT(self != NULL, return 0;);
        
@@ -1396,7 +1396,7 @@ static int ali_ircc_net_close(struct net_device *dev)
                
        IRDA_ASSERT(dev != NULL, return -1;);
 
-       self = (struct ali_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
        IRDA_ASSERT(self != NULL, return 0;);
 
        /* Stop device */
@@ -1436,7 +1436,7 @@ static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
        
        IRDA_DEBUG(1, "%s(), ---------------- Start -----------------\n", __func__ );
        
-       self = (struct ali_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
        iobase = self->io.fir_base;
 
        netif_stop_queue(dev);
@@ -1931,7 +1931,6 @@ static int  ali_ircc_dma_receive_complete(struct ali_ircc_cb *self)
                        skb_reset_mac_header(skb);
                        skb->protocol = htons(ETH_P_IRDA);
                        netif_rx(skb);
-                       self->netdev->last_rx = jiffies;
                }
        }
        
@@ -1960,7 +1959,7 @@ static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
        
        IRDA_ASSERT(dev != NULL, return 0;);
        
-       self = (struct ali_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
        IRDA_ASSERT(self != NULL, return 0;);
 
        iobase = self->io.sir_base;
@@ -2028,7 +2027,7 @@ static int ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        
        IRDA_ASSERT(dev != NULL, return -1;);
 
-       self = dev->priv;
+       self = netdev_priv(dev);
 
        IRDA_ASSERT(self != NULL, return -1;);
 
@@ -2114,7 +2113,7 @@ static int ali_ircc_is_receiving(struct ali_ircc_cb *self)
 
 static struct net_device_stats *ali_ircc_net_get_stats(struct net_device *dev)
 {
-       struct ali_ircc_cb *self = (struct ali_ircc_cb *) dev->priv;
+       struct ali_ircc_cb *self = netdev_priv(dev);
        
        IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__ );
                
index a1e4508717c8743bfa8f8d15c77a1383318e8884..6c4b53ffbcaccf453067a4e58b99d96df887fe8a 100644 (file)
@@ -620,7 +620,6 @@ static int au1k_irda_rx(struct net_device *dev)
                /* next descriptor */
                prxd = aup->rx_ring[aup->rx_head];
                flags = prxd->flags;
-               dev->last_rx = jiffies;
 
        }
        return 0;
index 69d16b30323b8fca6ecb974c2e66967e115f15bc..687c2d53d4d2135a244c5be1c9438601dd8687c6 100644 (file)
@@ -979,7 +979,7 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
   unsigned long flags;
   struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
 
-  self = (struct toshoboe_cb *) dev->priv;
+  self = netdev_priv(dev);
 
   IRDA_ASSERT (self != NULL, return 0; );
 
@@ -1384,7 +1384,7 @@ toshoboe_net_close (struct net_device *dev)
   IRDA_DEBUG (4, "%s()\n", __func__);
 
   IRDA_ASSERT (dev != NULL, return -1; );
-  self = (struct toshoboe_cb *) dev->priv;
+  self = netdev_priv(dev);
 
   /* Stop device */
   netif_stop_queue(dev);
@@ -1422,7 +1422,7 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 
   IRDA_ASSERT (dev != NULL, return -1; );
 
-  self = dev->priv;
+  self = netdev_priv(dev);
 
   IRDA_ASSERT (self != NULL, return -1; );
 
@@ -1546,7 +1546,7 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
       return -ENOMEM;
     }
 
-  self = dev->priv;
+  self = netdev_priv(dev);
   self->netdev = dev;
   self->pdev = pci_dev;
   self->base = pci_resource_start(pci_dev,0);
index b5d6b9ac162ae813ca4f74955c32187f31fa6053..205e4e825a97639320d1898995e2de52368aefb2 100644 (file)
@@ -384,7 +384,7 @@ static void speed_bulk_callback(struct urb *urb)
  */
 static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
-       struct irda_usb_cb *self = netdev->priv;
+       struct irda_usb_cb *self = netdev_priv(netdev);
        struct urb *urb = self->tx_urb;
        unsigned long flags;
        s32 speed;
@@ -628,7 +628,7 @@ static void write_bulk_callback(struct urb *urb)
 static void irda_usb_net_timeout(struct net_device *netdev)
 {
        unsigned long flags;
-       struct irda_usb_cb *self = netdev->priv;
+       struct irda_usb_cb *self = netdev_priv(netdev);
        struct urb *urb;
        int     done = 0;       /* If we have made any progress */
 
@@ -929,7 +929,6 @@ static void irda_usb_receive(struct urb *urb)
        /* Keep stats up to date */
        self->stats.rx_bytes += len;
        self->stats.rx_packets++;
-       self->netdev->last_rx = jiffies;
 
 done:
        /* Note : at this point, the URB we've just received (urb)
@@ -1175,7 +1174,7 @@ static int irda_usb_net_open(struct net_device *netdev)
        IRDA_DEBUG(1, "%s()\n", __func__);
 
        IRDA_ASSERT(netdev != NULL, return -1;);
-       self = (struct irda_usb_cb *) netdev->priv;
+       self = netdev_priv(netdev);
        IRDA_ASSERT(self != NULL, return -1;);
 
        spin_lock_irqsave(&self->lock, flags);
@@ -1257,7 +1256,7 @@ static int irda_usb_net_close(struct net_device *netdev)
        IRDA_DEBUG(1, "%s()\n", __func__);
 
        IRDA_ASSERT(netdev != NULL, return -1;);
-       self = (struct irda_usb_cb *) netdev->priv;
+       self = netdev_priv(netdev);
        IRDA_ASSERT(self != NULL, return -1;);
 
        /* Clear this flag *before* unlinking the urbs and *before*
@@ -1306,7 +1305,7 @@ static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        int ret = 0;
 
        IRDA_ASSERT(dev != NULL, return -1;);
-       self = dev->priv;
+       self = netdev_priv(dev);
        IRDA_ASSERT(self != NULL, return -1;);
 
        IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __func__, dev->name, cmd);
@@ -1348,7 +1347,7 @@ static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
  */
 static struct net_device_stats *irda_usb_net_get_stats(struct net_device *dev)
 {
-       struct irda_usb_cb *self = dev->priv;
+       struct irda_usb_cb *self = netdev_priv(dev);
        return &self->stats;
 }
 
@@ -1641,7 +1640,7 @@ static int irda_usb_probe(struct usb_interface *intf,
                goto err_out;
 
        SET_NETDEV_DEV(net, &intf->dev);
-       self = net->priv;
+       self = netdev_priv(net);
        self->netdev = net;
        spin_lock_init(&self->lock);
        init_timer(&self->rx_defer_timer);
index e1429fc6d05036abc63f34d22009f850d455d7da..c747c874d44d8388acaf199ab6373761e27a0f4d 100644 (file)
@@ -235,7 +235,6 @@ static void kingsun_rcv_irq(struct urb *urb)
                                                  &kingsun->stats,
                                                  &kingsun->rx_buff, bytes[i]);
                        }
-                       kingsun->netdev->last_rx = jiffies;
                        do_gettimeofday(&kingsun->rx_time);
                        kingsun->receiving =
                                (kingsun->rx_buff.state != OUTSIDE_FRAME)
index 2e67ae015d916eae51ca1a2ceb666b7b6905e5a7..600d96f9cdb7408d619bb78c7481c645c24caa4e 100644 (file)
@@ -474,7 +474,6 @@ static void ks959_rcv_irq(struct urb *urb)
                                                  bytes[i]);
                        }
                }
-               kingsun->netdev->last_rx = jiffies;
                do_gettimeofday(&kingsun->rx_time);
                kingsun->receiving =
                    (kingsun->rx_unwrap_buff.state != OUTSIDE_FRAME) ? 1 : 0;
index 3843b5faba8b5da67a7463c02cba196b6a8b6105..0e7f89337b25791ec137eb0d910cb548fa75152e 100644 (file)
@@ -371,7 +371,6 @@ static void ksdazzle_rcv_irq(struct urb *urb)
                        async_unwrap_char(kingsun->netdev, &kingsun->stats,
                                          &kingsun->rx_unwrap_buff, bytes[i]);
                }
-               kingsun->netdev->last_rx = jiffies;
                kingsun->receiving =
                    (kingsun->rx_unwrap_buff.state != OUTSIDE_FRAME) ? 1 : 0;
        }
index ad92d3ff1c4093ff6ea8281c430374ab26ff3ac2..904c9610c0dd61a5d1de949aaadc2d3a87f8bb3e 100644 (file)
@@ -806,7 +806,6 @@ static void mcs_receive_irq(struct urb *urb)
                        mcs_unwrap_fir(mcs, urb->transfer_buffer,
                                urb->actual_length);
                }
-               mcs->netdev->last_rx = jiffies;
                do_gettimeofday(&mcs->rx_time);
        }
 
index 8583d951a6ad15529fb4c8ec2169865582e5aa6f..2c6bf2d11bb13451d422f465110e69edd6e695a4 100644 (file)
@@ -373,7 +373,7 @@ static int __init nsc_ircc_open(chipio_t *info)
                return -ENOMEM;
        }
 
-       self = dev->priv;
+       self = netdev_priv(dev);
        self->netdev = dev;
        spin_lock_init(&self->lock);
    
@@ -1354,7 +1354,7 @@ static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev)
        __s32 speed;
        __u8 bank;
        
-       self = (struct nsc_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
 
        IRDA_ASSERT(self != NULL, return 0;);
 
@@ -1427,7 +1427,7 @@ static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev)
        __u8 bank;
        int mtt, diff;
        
-       self = (struct nsc_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
        iobase = self->io.fir_base;
 
        netif_stop_queue(dev);
@@ -1896,7 +1896,6 @@ static int nsc_ircc_dma_receive_complete(struct nsc_ircc_cb *self, int iobase)
                        skb_reset_mac_header(skb);
                        skb->protocol = htons(ETH_P_IRDA);
                        netif_rx(skb);
-                       self->netdev->last_rx = jiffies;
                }
        }
        /* Restore bank register */
@@ -2085,7 +2084,7 @@ static irqreturn_t nsc_ircc_interrupt(int irq, void *dev_id)
        __u8 bsr, eir;
        int iobase;
 
-       self = dev->priv;
+       self = netdev_priv(dev);
 
        spin_lock(&self->lock); 
 
@@ -2166,7 +2165,7 @@ static int nsc_ircc_net_open(struct net_device *dev)
        IRDA_DEBUG(4, "%s()\n", __func__);
        
        IRDA_ASSERT(dev != NULL, return -1;);
-       self = (struct nsc_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
        
        IRDA_ASSERT(self != NULL, return 0;);
        
@@ -2229,7 +2228,7 @@ static int nsc_ircc_net_close(struct net_device *dev)
        
        IRDA_ASSERT(dev != NULL, return -1;);
 
-       self = (struct nsc_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
        IRDA_ASSERT(self != NULL, return 0;);
 
        /* Stop device */
@@ -2275,7 +2274,7 @@ static int nsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
        IRDA_ASSERT(dev != NULL, return -1;);
 
-       self = dev->priv;
+       self = netdev_priv(dev);
 
        IRDA_ASSERT(self != NULL, return -1;);
 
@@ -2310,7 +2309,7 @@ static int nsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
 static struct net_device_stats *nsc_ircc_net_get_stats(struct net_device *dev)
 {
-       struct nsc_ircc_cb *self = (struct nsc_ircc_cb *) dev->priv;
+       struct nsc_ircc_cb *self = netdev_priv(dev);
        
        return &self->stats;
 }
index c5b02b66f7560a570210f075e6d72eda219e97df..a0ee053181556bd4b600f5f001ae2eba236f901e 100644 (file)
@@ -225,7 +225,6 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
                        }
                        lsr = STLSR;
                }
-               dev->last_rx = jiffies;
                si->last_oscr = OSCR;
                break;
 
@@ -237,7 +236,6 @@ static irqreturn_t pxa_irda_sir_irq(int irq, void *dev_id)
                    si->stats.rx_bytes++;
                    async_unwrap_char(dev, &si->stats, &si->rx_buff, STRBR);
                } while (STLSR & LSR_DR);
-               dev->last_rx = jiffies;
                si->last_oscr = OSCR;
                break;
 
@@ -397,8 +395,6 @@ static void pxa_irda_fir_irq_eif(struct pxa_irda *si, struct net_device *dev, in
 
                si->stats.rx_packets++;
                si->stats.rx_bytes += len;
-
-               dev->last_rx = jiffies;
        }
 }
 
index a95188948de7b80a385ddeab5fe7b437e898aa33..ccde5829ba21139b6947e4218c9c00492487e0a1 100644 (file)
@@ -298,7 +298,7 @@ static int sa1100_irda_suspend(struct platform_device *pdev, pm_message_t state)
        if (!dev)
                return 0;
 
-       si = dev->priv;
+       si = netdev_priv(dev);
        if (si->open) {
                /*
                 * Stop the transmit queue
@@ -323,7 +323,7 @@ static int sa1100_irda_resume(struct platform_device *pdev)
        if (!dev)
                return 0;
 
-       si = dev->priv;
+       si = netdev_priv(dev);
        if (si->open) {
                /*
                 * If we missed a speed change, initialise at the new speed
@@ -359,7 +359,7 @@ static int sa1100_irda_resume(struct platform_device *pdev)
  */
 static void sa1100_irda_hpsir_irq(struct net_device *dev)
 {
-       struct sa1100_irda *si = dev->priv;
+       struct sa1100_irda *si = netdev_priv(dev);
        int status;
 
        status = Ser2UTSR0;
@@ -410,7 +410,6 @@ static void sa1100_irda_hpsir_irq(struct net_device *dev)
                                          Ser2UTDR);
                } while (Ser2UTSR1 & UTSR1_RNE);
 
-               dev->last_rx = jiffies;
        }
 
        if (status & UTSR0_TFS && si->tx_buff.len) {
@@ -515,7 +514,6 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev
                sa1100_irda_rx_alloc(si);
 
                netif_rx(skb);
-               dev->last_rx = jiffies;
        } else {
                /*
                 * Remap the buffer.
@@ -534,7 +532,7 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev
  */
 static void sa1100_irda_fir_irq(struct net_device *dev)
 {
-       struct sa1100_irda *si = dev->priv;
+       struct sa1100_irda *si = netdev_priv(dev);
 
        /*
         * Stop RX DMA
@@ -582,7 +580,7 @@ static void sa1100_irda_fir_irq(struct net_device *dev)
 static irqreturn_t sa1100_irda_irq(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
-       if (IS_FIR(((struct sa1100_irda *)dev->priv)))
+       if (IS_FIR(((struct sa1100_irda *)netdev_priv(dev))))
                sa1100_irda_fir_irq(dev);
        else
                sa1100_irda_hpsir_irq(dev);
@@ -595,7 +593,7 @@ static irqreturn_t sa1100_irda_irq(int irq, void *dev_id)
 static void sa1100_irda_txdma_irq(void *id)
 {
        struct net_device *dev = id;
-       struct sa1100_irda *si = dev->priv;
+       struct sa1100_irda *si = netdev_priv(dev);
        struct sk_buff *skb = si->txskb;
 
        si->txskb = NULL;
@@ -649,7 +647,7 @@ static void sa1100_irda_txdma_irq(void *id)
 
 static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct sa1100_irda *si = dev->priv;
+       struct sa1100_irda *si = netdev_priv(dev);
        int speed = irda_get_next_speed(skb);
 
        /*
@@ -724,7 +722,7 @@ static int
 sa1100_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
 {
        struct if_irda_req *rq = (struct if_irda_req *)ifreq;
-       struct sa1100_irda *si = dev->priv;
+       struct sa1100_irda *si = netdev_priv(dev);
        int ret = -EOPNOTSUPP;
 
        switch (cmd) {
@@ -766,13 +764,13 @@ sa1100_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
 
 static struct net_device_stats *sa1100_irda_stats(struct net_device *dev)
 {
-       struct sa1100_irda *si = dev->priv;
+       struct sa1100_irda *si = netdev_priv(dev);
        return &si->stats;
 }
 
 static int sa1100_irda_start(struct net_device *dev)
 {
-       struct sa1100_irda *si = dev->priv;
+       struct sa1100_irda *si = netdev_priv(dev);
        int err;
 
        si->speed = 9600;
@@ -835,7 +833,7 @@ err_irq:
 
 static int sa1100_irda_stop(struct net_device *dev)
 {
-       struct sa1100_irda *si = dev->priv;
+       struct sa1100_irda *si = netdev_priv(dev);
 
        disable_irq(dev->irq);
        sa1100_irda_shutdown(si);
@@ -908,7 +906,7 @@ static int sa1100_irda_probe(struct platform_device *pdev)
        if (!dev)
                goto err_mem_4;
 
-       si = dev->priv;
+       si = netdev_priv(dev);
        si->dev = &pdev->dev;
        si->pdata = pdev->dev.platform_data;
 
@@ -987,7 +985,7 @@ static int sa1100_irda_remove(struct platform_device *pdev)
        struct net_device *dev = platform_get_drvdata(pdev);
 
        if (dev) {
-               struct sa1100_irda *si = dev->priv;
+               struct sa1100_irda *si = netdev_priv(dev);
                unregister_netdev(dev);
                kfree(si->tx_buff.head);
                kfree(si->rx_buff.head);
index 3f32909c24c81ff61307bd7cb37f03937221aa33..ceef040aa76d2a63c9ad579a5eb463c9a98e8bd0 100644 (file)
@@ -584,14 +584,14 @@ EXPORT_SYMBOL(sirdev_receive);
 
 static struct net_device_stats *sirdev_get_stats(struct net_device *ndev)
 {
-       struct sir_dev *dev = ndev->priv;
+       struct sir_dev *dev = netdev_priv(ndev);
 
        return (dev) ? &dev->stats : NULL;
 }
 
 static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
-       struct sir_dev *dev = ndev->priv;
+       struct sir_dev *dev = netdev_priv(ndev);
        unsigned long flags;
        int actual = 0;
        int err;
@@ -683,7 +683,7 @@ static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
 static int sirdev_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 {
        struct if_irda_req *irq = (struct if_irda_req *) rq;
-       struct sir_dev *dev = ndev->priv;
+       struct sir_dev *dev = netdev_priv(ndev);
        int ret = 0;
 
        IRDA_ASSERT(dev != NULL, return -1;);
@@ -795,7 +795,7 @@ static void sirdev_free_buffers(struct sir_dev *dev)
 
 static int sirdev_open(struct net_device *ndev)
 {
-       struct sir_dev *dev = ndev->priv;
+       struct sir_dev *dev = netdev_priv(ndev);
        const struct sir_driver *drv = dev->drv;
 
        if (!drv)
@@ -840,7 +840,7 @@ errout_dec:
 
 static int sirdev_close(struct net_device *ndev)
 {
-       struct sir_dev *dev = ndev->priv;
+       struct sir_dev *dev = netdev_priv(ndev);
        const struct sir_driver *drv;
 
 //     IRDA_DEBUG(0, "%s\n", __func__);
@@ -896,7 +896,7 @@ struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *n
                IRDA_ERROR("%s - Can't allocate memory for IrDA control block!\n", __func__);
                goto out;
        }
-       dev = ndev->priv;
+       dev = netdev_priv(ndev);
 
        irda_init_max_qos_capabilies(&dev->qos);
        dev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
index 3575804fd7c644b4fe5202a289b80eb20b59a799..ca4cd9266e55ef45c97d77e0afada0eb67a8677e 100644 (file)
@@ -824,7 +824,6 @@ static void stir_rcv_irq(struct urb *urb)
                unwrap_chars(stir, urb->transfer_buffer,
                             urb->actual_length);
                
-               stir->netdev->last_rx = jiffies;
                do_gettimeofday(&stir->rx_time);
        }
 
index 84e609ea5fbbc1a5e1a25d72a60b9aa369ea9a73..74c78cf7a333c95b49ea7c2ecd0f2703266c3044 100644 (file)
@@ -334,7 +334,7 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
        if (dev == NULL) 
                return -ENOMEM;
 
-       self = dev->priv;
+       self = netdev_priv(dev);
        self->netdev = dev;
        spin_lock_init(&self->lock);
 
@@ -824,7 +824,7 @@ static int via_ircc_hard_xmit_sir(struct sk_buff *skb,
        u16 iobase;
        __u32 speed;
 
-       self = (struct via_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
        IRDA_ASSERT(self != NULL, return 0;);
        iobase = self->io.fir_base;
 
@@ -896,7 +896,7 @@ static int via_ircc_hard_xmit_fir(struct sk_buff *skb,
        __u32 speed;
        unsigned long flags;
 
-       self = (struct via_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
        iobase = self->io.fir_base;
 
        if (self->st_fifo.len)
@@ -1349,7 +1349,7 @@ static int RxTimerHandler(struct via_ircc_cb *self, int iobase)
 static irqreturn_t via_ircc_interrupt(int dummy, void *dev_id)
 {
        struct net_device *dev = dev_id;
-       struct via_ircc_cb *self = dev->priv;
+       struct via_ircc_cb *self = netdev_priv(dev);
        int iobase;
        u8 iHostIntType, iRxIntType, iTxIntType;
 
@@ -1522,7 +1522,7 @@ static int via_ircc_net_open(struct net_device *dev)
        IRDA_DEBUG(3, "%s()\n", __func__);
 
        IRDA_ASSERT(dev != NULL, return -1;);
-       self = (struct via_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
        self->stats.rx_packets = 0;
        IRDA_ASSERT(self != NULL, return 0;);
        iobase = self->io.fir_base;
@@ -1589,7 +1589,7 @@ static int via_ircc_net_close(struct net_device *dev)
        IRDA_DEBUG(3, "%s()\n", __func__);
 
        IRDA_ASSERT(dev != NULL, return -1;);
-       self = (struct via_ircc_cb *) dev->priv;
+       self = netdev_priv(dev);
        IRDA_ASSERT(self != NULL, return 0;);
 
        /* Stop device */
@@ -1628,7 +1628,7 @@ static int via_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq,
        int ret = 0;
 
        IRDA_ASSERT(dev != NULL, return -1;);
-       self = dev->priv;
+       self = netdev_priv(dev);
        IRDA_ASSERT(self != NULL, return -1;);
        IRDA_DEBUG(1, "%s(), %s, (cmd=0x%X)\n", __func__, dev->name,
                   cmd);
@@ -1663,7 +1663,7 @@ static int via_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq,
 static struct net_device_stats *via_ircc_net_get_stats(struct net_device
                                                       *dev)
 {
-       struct via_ircc_cb *self = (struct via_ircc_cb *) dev->priv;
+       struct via_ircc_cb *self = netdev_priv(dev);
 
        return &self->stats;
 }
index 9c926d205de971d69ee7873522ec4a657dfc8cfb..0d30f8d659a1995b083eb4e507833dd7fa92f0d7 100644 (file)
@@ -178,7 +178,7 @@ static void vlsi_proc_pdev(struct seq_file *seq, struct pci_dev *pdev)
                
 static void vlsi_proc_ndev(struct seq_file *seq, struct net_device *ndev)
 {
-       vlsi_irda_dev_t *idev = ndev->priv;
+       vlsi_irda_dev_t *idev = netdev_priv(ndev);
        u8 byte;
        u16 word;
        unsigned delta1, delta2;
@@ -346,7 +346,7 @@ static void vlsi_proc_ring(struct seq_file *seq, struct vlsi_ring *r)
 static int vlsi_seq_show(struct seq_file *seq, void *v)
 {
        struct net_device *ndev = seq->private;
-       vlsi_irda_dev_t *idev = ndev->priv;
+       vlsi_irda_dev_t *idev = netdev_priv(ndev);
        unsigned long flags;
 
        seq_printf(seq, "\n%s %s\n\n", DRIVER_NAME, DRIVER_VERSION);
@@ -543,7 +543,7 @@ static int vlsi_process_rx(struct vlsi_ring *r, struct ring_descr *rd)
        struct sk_buff  *skb;
        int             ret = 0;
        struct net_device *ndev = (struct net_device *)pci_get_drvdata(r->pdev);
-       vlsi_irda_dev_t *idev = ndev->priv;
+       vlsi_irda_dev_t *idev = netdev_priv(ndev);
 
        pci_dma_sync_single_for_cpu(r->pdev, rd_get_addr(rd), r->len, r->dir);
        /* dma buffer now owned by the CPU */
@@ -600,7 +600,6 @@ static int vlsi_process_rx(struct vlsi_ring *r, struct ring_descr *rd)
                netif_rx(skb);
        else
                netif_rx_ni(skb);
-       ndev->last_rx = jiffies;
 
 done:
        rd_set_status(rd, 0);
@@ -638,7 +637,7 @@ static void vlsi_fill_rx(struct vlsi_ring *r)
 
 static void vlsi_rx_interrupt(struct net_device *ndev)
 {
-       vlsi_irda_dev_t *idev = ndev->priv;
+       vlsi_irda_dev_t *idev = netdev_priv(ndev);
        struct vlsi_ring *r = idev->rx_ring;
        struct ring_descr *rd;
        int ret;
@@ -856,7 +855,7 @@ static int vlsi_set_baud(vlsi_irda_dev_t *idev, unsigned iobase)
 
 static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
-       vlsi_irda_dev_t *idev = ndev->priv;
+       vlsi_irda_dev_t *idev = netdev_priv(ndev);
        struct vlsi_ring        *r = idev->tx_ring;
        struct ring_descr *rd;
        unsigned long flags;
@@ -1063,7 +1062,7 @@ drop:
 
 static void vlsi_tx_interrupt(struct net_device *ndev)
 {
-       vlsi_irda_dev_t *idev = ndev->priv;
+       vlsi_irda_dev_t *idev = netdev_priv(ndev);
        struct vlsi_ring        *r = idev->tx_ring;
        struct ring_descr       *rd;
        unsigned        iobase;
@@ -1262,7 +1261,7 @@ static inline void vlsi_clear_regs(unsigned iobase)
 static int vlsi_init_chip(struct pci_dev *pdev)
 {
        struct net_device *ndev = pci_get_drvdata(pdev);
-       vlsi_irda_dev_t *idev = ndev->priv;
+       vlsi_irda_dev_t *idev = netdev_priv(ndev);
        unsigned        iobase;
        u16 ptr;
 
@@ -1376,14 +1375,14 @@ static int vlsi_stop_hw(vlsi_irda_dev_t *idev)
 
 static struct net_device_stats * vlsi_get_stats(struct net_device *ndev)
 {
-       vlsi_irda_dev_t *idev = ndev->priv;
+       vlsi_irda_dev_t *idev = netdev_priv(ndev);
 
        return &idev->stats;
 }
 
 static void vlsi_tx_timeout(struct net_device *ndev)
 {
-       vlsi_irda_dev_t *idev = ndev->priv;
+       vlsi_irda_dev_t *idev = netdev_priv(ndev);
 
 
        vlsi_reg_debug(ndev->base_addr, __func__);
@@ -1408,7 +1407,7 @@ static void vlsi_tx_timeout(struct net_device *ndev)
 
 static int vlsi_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 {
-       vlsi_irda_dev_t *idev = ndev->priv;
+       vlsi_irda_dev_t *idev = netdev_priv(ndev);
        struct if_irda_req *irq = (struct if_irda_req *) rq;
        unsigned long flags;
        u16 fifocnt;
@@ -1458,7 +1457,7 @@ static int vlsi_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 static irqreturn_t vlsi_interrupt(int irq, void *dev_instance)
 {
        struct net_device *ndev = dev_instance;
-       vlsi_irda_dev_t *idev = ndev->priv;
+       vlsi_irda_dev_t *idev = netdev_priv(ndev);
        unsigned        iobase;
        u8              irintr;
        int             boguscount = 5;
@@ -1499,7 +1498,7 @@ static irqreturn_t vlsi_interrupt(int irq, void *dev_instance)
 
 static int vlsi_open(struct net_device *ndev)
 {
-       vlsi_irda_dev_t *idev = ndev->priv;
+       vlsi_irda_dev_t *idev = netdev_priv(ndev);
        int     err = -EAGAIN;
        char    hwname[32];
 
@@ -1558,7 +1557,7 @@ errout:
 
 static int vlsi_close(struct net_device *ndev)
 {
-       vlsi_irda_dev_t *idev = ndev->priv;
+       vlsi_irda_dev_t *idev = netdev_priv(ndev);
 
        netif_stop_queue(ndev);
 
@@ -1581,7 +1580,7 @@ static int vlsi_close(struct net_device *ndev)
 
 static int vlsi_irda_init(struct net_device *ndev)
 {
-       vlsi_irda_dev_t *idev = ndev->priv;
+       vlsi_irda_dev_t *idev = netdev_priv(ndev);
        struct pci_dev *pdev = idev->pdev;
 
        ndev->irq = pdev->irq;
@@ -1656,7 +1655,7 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                goto out_disable;
        }
 
-       idev = ndev->priv;
+       idev = netdev_priv(ndev);
 
        spin_lock_init(&idev->lock);
        mutex_init(&idev->mtx);
@@ -1713,7 +1712,7 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev)
 
        unregister_netdev(ndev);
 
-       idev = ndev->priv;
+       idev = netdev_priv(ndev);
        mutex_lock(&idev->mtx);
        if (idev->proc_entry) {
                remove_proc_entry(ndev->name, vlsi_proc_root);
@@ -1748,7 +1747,7 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, pm_message_t state)
                           __func__, pci_name(pdev));
                return 0;
        }
-       idev = ndev->priv;      
+       idev = netdev_priv(ndev);
        mutex_lock(&idev->mtx);
        if (pdev->current_state != 0) {                 /* already suspended */
                if (state.event > pdev->current_state) {        /* simply go deeper */
@@ -1787,7 +1786,7 @@ static int vlsi_irda_resume(struct pci_dev *pdev)
                           __func__, pci_name(pdev));
                return 0;
        }
-       idev = ndev->priv;      
+       idev = netdev_priv(ndev);
        mutex_lock(&idev->mtx);
        if (pdev->current_state == 0) {
                mutex_unlock(&idev->mtx);
index 002a6d769f21f244912b6584c33e9e6a4cc92615..161d591aeb97459c2c05090b755f901464d46325 100644 (file)
@@ -178,7 +178,7 @@ int w83977af_open(int i, unsigned int iobase, unsigned int irq,
                goto err_out;
        }
 
-       self = dev->priv;
+       self = netdev_priv(dev);
        spin_lock_init(&self->lock);
    
 
@@ -497,7 +497,7 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev)
        __u8 set;
        int mtt;
        
-       self = (struct w83977af_ir *) dev->priv;
+       self = netdev_priv(dev);
 
        iobase = self->io.fir_base;
 
@@ -923,7 +923,6 @@ int w83977af_dma_receive_complete(struct w83977af_ir *self)
                        skb_reset_mac_header(skb);
                        skb->protocol = htons(ETH_P_IRDA);
                        netif_rx(skb);
-                       self->netdev->last_rx = jiffies;
                }
        }
        /* Restore set register */
@@ -1119,7 +1118,7 @@ static irqreturn_t w83977af_interrupt(int irq, void *dev_id)
        __u8 set, icr, isr;
        int iobase;
 
-       self = dev->priv;
+       self = netdev_priv(dev);
 
        iobase = self->io.fir_base;
 
@@ -1192,7 +1191,7 @@ static int w83977af_net_open(struct net_device *dev)
        IRDA_DEBUG(0, "%s()\n", __func__ );
        
        IRDA_ASSERT(dev != NULL, return -1;);
-       self = (struct w83977af_ir *) dev->priv;
+       self = netdev_priv(dev);
        
        IRDA_ASSERT(self != NULL, return 0;);
        
@@ -1256,7 +1255,7 @@ static int w83977af_net_close(struct net_device *dev)
 
        IRDA_ASSERT(dev != NULL, return -1;);
        
-       self = (struct w83977af_ir *) dev->priv;
+       self = netdev_priv(dev);
        
        IRDA_ASSERT(self != NULL, return 0;);
        
@@ -1303,7 +1302,7 @@ static int w83977af_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
        IRDA_ASSERT(dev != NULL, return -1;);
 
-       self = dev->priv;
+       self = netdev_priv(dev);
 
        IRDA_ASSERT(self != NULL, return -1;);
 
@@ -1339,7 +1338,7 @@ out:
 
 static struct net_device_stats *w83977af_net_get_stats(struct net_device *dev)
 {
-       struct w83977af_ir *self = (struct w83977af_ir *) dev->priv;
+       struct w83977af_ir *self = netdev_priv(dev);
        
        return &self->stats;
 }
index d6ff26af37b3e5c1dc5a60d5c979819855389e1b..15ebae9b98d4e720ee2e2df289debbbe17585360 100644 (file)
@@ -192,7 +192,6 @@ static int __init netcard_probe1(struct net_device *dev, int ioaddr)
        static unsigned version_printed;
        int i;
        int err = -ENODEV;
-       DECLARE_MAC_BUF(mac);
 
        /* Grab the region so that no one else tries to probe our ioports. */
        if (!request_region(ioaddr, NETCARD_IO_EXTENT, cardname))
@@ -220,7 +219,7 @@ static int __init netcard_probe1(struct net_device *dev, int ioaddr)
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = inb(ioaddr + i);
 
-       printk("%s", print_mac(mac, dev->dev_addr));
+       printk("%pM", dev->dev_addr);
 
        err = -EAGAIN;
 #ifdef jumpered_interrupts
@@ -584,7 +583,6 @@ net_rx(struct net_device *dev)
                        insw(ioaddr, skb->data, (pkt_len + 1) >> 1);
 
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        lp->stats.rx_packets++;
                        lp->stats.rx_bytes += pkt_len;
                }
index c46864d626b28e44b7e25669ea319d1f74a2dd53..c7457f97259d9ad9d60226b76f22d45108206d60 100644 (file)
@@ -952,7 +952,7 @@ static int veth_change_mtu(struct net_device *dev, int new_mtu)
 
 static void veth_set_multicast_list(struct net_device *dev)
 {
-       struct veth_port *port = (struct veth_port *) dev->priv;
+       struct veth_port *port = netdev_priv(dev);
        unsigned long flags;
 
        write_lock_irqsave(&port->mcast_gate, flags);
@@ -1044,7 +1044,7 @@ static struct net_device *veth_probe_one(int vlan,
                return NULL;
        }
 
-       port = (struct veth_port *) dev->priv;
+       port = netdev_priv(dev);
 
        spin_lock_init(&port->queue_lock);
        rwlock_init(&port->mcast_gate);
@@ -1102,7 +1102,7 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp,
                                struct net_device *dev)
 {
        struct veth_lpar_connection *cnx = veth_cnx[rlp];
-       struct veth_port *port = (struct veth_port *) dev->priv;
+       struct veth_port *port = netdev_priv(dev);
        HvLpEvent_Rc rc;
        struct veth_msg *msg = NULL;
        unsigned long flags;
@@ -1191,7 +1191,7 @@ static void veth_transmit_to_many(struct sk_buff *skb,
 static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        unsigned char *frame = skb->data;
-       struct veth_port *port = (struct veth_port *) dev->priv;
+       struct veth_port *port = netdev_priv(dev);
        HvLpIndexMap lpmask;
 
        if (! (frame[0] & 0x01)) {
@@ -1255,7 +1255,7 @@ static void veth_wake_queues(struct veth_lpar_connection *cnx)
                if (! dev)
                        continue;
 
-               port = (struct veth_port *)dev->priv;
+               port = netdev_priv(dev);
 
                if (! (port->lpar_map & (1<<cnx->remote_lp)))
                        continue;
@@ -1284,7 +1284,7 @@ static void veth_stop_queues(struct veth_lpar_connection *cnx)
                if (! dev)
                        continue;
 
-               port = (struct veth_port *)dev->priv;
+               port = netdev_priv(dev);
 
                /* If this cnx is not on the vlan for this port, continue */
                if (! (port->lpar_map & (1 << cnx->remote_lp)))
@@ -1506,7 +1506,7 @@ static void veth_receive(struct veth_lpar_connection *cnx,
                        continue;
                }
 
-               port = (struct veth_port *)dev->priv;
+               port = netdev_priv(dev);
                dest = *((u64 *) skb->data) & 0xFFFFFFFFFFFF0000;
 
                if ((vlan > HVMAXARCHITECTEDVIRTUALLANS) || !port) {
index be3c7dc96f633d2842d6394abd72a469b27e6dab..cb7d1a6d343452184caf41dadeca6d507c2ba358 100644 (file)
@@ -381,8 +381,7 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        adapter->hw.back = adapter;
        adapter->msg_enable = netif_msg_init(debug, DEFAULT_DEBUG_LEVEL_SHIFT);
 
-       adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, BAR_0),
-                                     pci_resource_len(pdev, BAR_0));
+       adapter->hw.hw_addr = pci_ioremap_bar(pdev, BAR_0);
        if (!adapter->hw.hw_addr) {
                err = -EIO;
                goto err_ioremap;
@@ -1981,7 +1980,6 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter, int *work_done, int work_to_do)
                } else {
                        netif_receive_skb(skb);
                }
-               netdev->last_rx = jiffies;
 
 rxdesc_done:
                /* clean up descriptor, might be written over by hw */
index e116d340dcc6e158b35160f43ccd76d92feaa796..132854f646baa41cab58ab30a85479fa3350fb61 100644 (file)
@@ -267,6 +267,7 @@ struct ixgbe_adapter {
 #define IXGBE_FLAG_RSS_CAPABLE                  (u32)(1 << 17)
 #define IXGBE_FLAG_VMDQ_CAPABLE                 (u32)(1 << 18)
 #define IXGBE_FLAG_VMDQ_ENABLED                 (u32)(1 << 19)
+#define IXGBE_FLAG_FAN_FAIL_CAPABLE             (u32)(1 << 20)
 #define IXGBE_FLAG_NEED_LINK_UPDATE             (u32)(1 << 22)
 #define IXGBE_FLAG_IN_WATCHDOG_TASK             (u32)(1 << 23)
 
index 7cddcfba809e73bbd86a6ae108951de1f21376d3..c2cdb042c481b1aed175b19614846e30a8fdf52d 100644 (file)
@@ -59,6 +59,11 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
 
        /* PHY Init */
        switch (phy->type) {
+       case ixgbe_phy_tn:
+               phy->ops.check_link = &ixgbe_check_phy_link_tnx;
+               phy->ops.get_firmware_version =
+                            &ixgbe_get_phy_firmware_version_tnx;
+               break;
        default:
                break;
        }
@@ -189,6 +194,9 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
        case IXGBE_DEV_ID_82598EB_XF_LR:
                media_type = ixgbe_media_type_fiber;
                break;
+       case IXGBE_DEV_ID_82598AT:
+               media_type = ixgbe_media_type_copper;
+               break;
        default:
                media_type = ixgbe_media_type_unknown;
                break;
@@ -872,6 +880,10 @@ s32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
        case IXGBE_DEV_ID_82598EB_XF_LR:
                physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
                break;
+       case IXGBE_DEV_ID_82598AT:
+               physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_T |
+                                 IXGBE_PHYSICAL_LAYER_1000BASE_T);
+               break;
 
        default:
                physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
index 81a9c4b8672683a8033ef5e73e3a4096e5e7a724..a610016a0172ae395434ea95140baa6976200657 100644 (file)
@@ -94,9 +94,9 @@ 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)))
+       ((((struct ixgbe_adapter *)netdev_priv(netdev))->num_tx_queues + \
+       ((struct ixgbe_adapter *)netdev_priv(netdev))->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)
@@ -149,6 +149,8 @@ static int ixgbe_set_settings(struct net_device *netdev,
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_hw *hw = &adapter->hw;
+       u32 advertised, old;
+       s32 err;
 
        switch (hw->phy.media_type) {
        case ixgbe_media_type_fiber:
@@ -157,6 +159,31 @@ static int ixgbe_set_settings(struct net_device *netdev,
                        return -EINVAL;
                /* in this case we currently only support 10Gb/FULL */
                break;
+       case ixgbe_media_type_copper:
+               /* 10000/copper and 1000/copper must autoneg
+                * this function does not support any duplex forcing, but can
+                * limit the advertising of the adapter to only 10000 or 1000 */
+               if (ecmd->autoneg == AUTONEG_DISABLE)
+                       return -EINVAL;
+
+               old = hw->phy.autoneg_advertised;
+               advertised = 0;
+               if (ecmd->advertising & ADVERTISED_10000baseT_Full)
+                       advertised |= IXGBE_LINK_SPEED_10GB_FULL;
+
+               if (ecmd->advertising & ADVERTISED_1000baseT_Full)
+                       advertised |= IXGBE_LINK_SPEED_1GB_FULL;
+
+               if (old == advertised)
+                       break;
+               /* this sets the link speed and restarts auto-neg */
+               err = hw->mac.ops.setup_link_speed(hw, advertised, true, true);
+               if (err) {
+                       DPRINTK(PROBE, INFO,
+                               "setup link failed with code %d\n", err);
+                       hw->mac.ops.setup_link_speed(hw, old, true, true);
+               }
+               break;
        default:
                break;
        }
index 7548fb7360d9a611827bd602262223d687dc3702..d1f80dd88bc9ff572812f52e190d249fd1949b4f 100644 (file)
@@ -68,6 +68,8 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
         board_82598 },
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT),
         board_82598 },
+       {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT),
+        board_82598 },
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4),
         board_82598 },
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT),
@@ -666,7 +668,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
 
                skb->protocol = eth_type_trans(skb, adapter->netdev);
                ixgbe_receive_skb(adapter, skb, staterr, rx_ring, rx_desc);
-               adapter->netdev->last_rx = jiffies;
 
 next_desc:
                rx_desc->wb.upper.status_error = 0;
@@ -904,6 +905,17 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
        return;
 }
 
+static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr)
+{
+       struct ixgbe_hw *hw = &adapter->hw;
+
+       if ((adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) &&
+           (eicr & IXGBE_EICR_GPI_SDP1)) {
+               DPRINTK(PROBE, CRIT, "Fan has stopped, replace the adapter\n");
+               /* write to clear the interrupt */
+               IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
+       }
+}
 
 static void ixgbe_check_lsc(struct ixgbe_adapter *adapter)
 {
@@ -928,6 +940,8 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
        if (eicr & IXGBE_EICR_LSC)
                ixgbe_check_lsc(adapter);
 
+       ixgbe_check_fan_failure(adapter, eicr);
+
        if (!test_bit(__IXGBE_DOWN, &adapter->state))
                IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
 
@@ -1316,6 +1330,8 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
        if (eicr & IXGBE_EICR_LSC)
                ixgbe_check_lsc(adapter);
 
+       ixgbe_check_fan_failure(adapter, eicr);
+
        if (netif_rx_schedule_prep(netdev, &adapter->q_vector[0].napi)) {
                adapter->tx_ring[0].total_packets = 0;
                adapter->tx_ring[0].total_bytes = 0;
@@ -1418,6 +1434,8 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
 {
        u32 mask;
        mask = IXGBE_EIMS_ENABLE_MASK;
+       if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
+               mask |= IXGBE_EIMS_GPI_SDP1;
        IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
        IXGBE_WRITE_FLUSH(&adapter->hw);
 }
@@ -1927,6 +1945,13 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
                IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE);
        }
 
+       /* Enable fan failure interrupt if media type is copper */
+       if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) {
+               gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
+               gpie |= IXGBE_SDP1_GPIEN;
+               IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
+       }
+
        mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
        if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) {
                mhadd &= ~IXGBE_MHADD_MFS_MASK;
@@ -1972,6 +1997,9 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
 
        ixgbe_irq_enable(adapter);
 
+       /* enable transmits */
+       netif_tx_start_all_queues(netdev);
+
        /* 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;
@@ -2564,6 +2592,9 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
        rss = min(IXGBE_MAX_RSS_INDICES, (int)num_online_cpus());
        adapter->ring_feature[RING_F_RSS].indices = rss;
        adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
+       if (hw->mac.ops.get_media_type &&
+           (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper))
+               adapter->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE;
 
        /* default flow control settings */
        hw->fc.original_type = ixgbe_fc_none;
@@ -3219,7 +3250,6 @@ static void ixgbe_watchdog_task(struct work_struct *work)
                                 (FLOW_TX ? "TX" : "None"))));
 
                        netif_carrier_on(netdev);
-                       netif_tx_wake_all_queues(netdev);
                } else {
                        /* Force detection of hung controller */
                        adapter->detect_tx_hung = true;
@@ -3230,7 +3260,6 @@ static void ixgbe_watchdog_task(struct work_struct *work)
                if (netif_carrier_ok(netdev)) {
                        DPRINTK(LINK, INFO, "NIC Link is Down\n");
                        netif_carrier_off(netdev);
-                       netif_tx_stop_all_queues(netdev);
                }
        }
 
@@ -3691,6 +3720,10 @@ static int ixgbe_link_config(struct ixgbe_hw *hw)
        /* must always autoneg for both 1G and 10G link */
        hw->mac.autoneg = true;
 
+       if ((hw->mac.type == ixgbe_mac_82598EB) &&
+           (hw->phy.media_type == ixgbe_media_type_copper))
+               autoneg = IXGBE_LINK_SPEED_82598_AUTONEG;
+
        return hw->mac.ops.setup_link_speed(hw, autoneg, true, true);
 }
 
@@ -3877,8 +3910,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        pci_read_config_word(pdev, IXGBE_PCI_LINK_STATUS, &link_status);
        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",
+       dev_info(&pdev->dev, "(PCI Express:%s:%s) %pM\n",
                ((link_speed == IXGBE_PCI_LINK_SPEED_5000) ? "5.0Gb/s" :
                 (link_speed == IXGBE_PCI_LINK_SPEED_2500) ? "2.5Gb/s" :
                 "Unknown"),
@@ -3887,8 +3919,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
                 (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]);
+               netdev->dev_addr);
        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,
@@ -3913,7 +3944,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        }
 
        netif_carrier_off(netdev);
-       netif_tx_stop_all_queues(netdev);
 
        ixgbe_napi_add_all(adapter);
 
@@ -4011,7 +4041,7 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
                                                 pci_channel_state_t state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct ixgbe_adapter *adapter = netdev->priv;
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
        netif_device_detach(netdev);
 
@@ -4032,7 +4062,7 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
 static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct ixgbe_adapter *adapter = netdev->priv;
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
        if (pci_enable_device(pdev)) {
                DPRINTK(PROBE, ERR,
@@ -4060,7 +4090,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
 static void ixgbe_io_resume(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct ixgbe_adapter *adapter = netdev->priv;
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
        if (netif_running(netdev)) {
                if (ixgbe_up(adapter)) {
index 764035a8c9a16b0d0ea99864899747ca2cb8c233..981e6d8495925e3ae52ad2dbfbffed1768a55485 100644 (file)
@@ -121,6 +121,9 @@ 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;
@@ -426,3 +429,68 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
        return 0;
 }
 
+/**
+ *  ixgbe_check_phy_link_tnx - 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_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *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);
+               status = hw->phy.ops.read_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;
+               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;
+               }
+       }
+
+       return status;
+}
+
+/**
+ *  ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version
+ *  @hw: pointer to hardware structure
+ *  @firmware_version: pointer to the PHY Firmware Version
+ **/
+s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
+                                       u16 *firmware_version)
+{
+       s32 status = 0;
+
+       status = hw->phy.ops.read_reg(hw, TNX_FW_REV,
+                                     IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+                                     firmware_version);
+
+       return status;
+}
+
index 9bfe3f2b1d8f499f743890a846790150b9c5757a..5cc063d027709fd84a5029ae3dc676276d1138eb 100644 (file)
@@ -77,4 +77,11 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
                                        bool autoneg,
                                        bool autoneg_wait_to_complete);
 
+/* PHY specific */
+s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw,
+                             ixgbe_link_speed *speed,
+                             bool *link_up);
+s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
+                                       u16 *firmware_version);
+
 #endif /* _IXGBE_PHY_H_ */
index c6f8fa1c4e597909065c6189958af703ccfb26b3..51df39dae81654ebaf1a84a6eb73c0d77136e9ad 100644 (file)
@@ -36,6 +36,7 @@
 /* Device IDs */
 #define IXGBE_DEV_ID_82598AF_DUAL_PORT   0x10C6
 #define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
+#define IXGBE_DEV_ID_82598AT             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
 #define IXGBE_MAX_PHY_ADDR             32
 
 /* PHY IDs*/
+#define TN1010_PHY_ID    0x00A19410
+#define TNX_FW_REV       0xB
 #define QT2022_PHY_ID    0x0043A400
 
 /* PHY Types */
@@ -1202,6 +1205,7 @@ enum ixgbe_mac_type {
 
 enum ixgbe_phy_type {
        ixgbe_phy_unknown = 0,
+       ixgbe_phy_tn,
        ixgbe_phy_qt,
        ixgbe_phy_xaui,
        ixgbe_phy_tw_tyco,
@@ -1396,6 +1400,8 @@ struct ixgbe_phy_operations {
        s32 (*setup_link)(struct ixgbe_hw *);
        s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool,
                                bool);
+       s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *);
+       s32 (*get_firmware_version)(struct ixgbe_hw *, u16 *);
        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 *);
index 7b70c66504a04fde3f177d92b085034486294349..bd96dbc8e0219c459587f0df9e640a67c8863254 100644 (file)
@@ -114,8 +114,6 @@ static int ixpdev_rx(struct net_device *dev, int processed, int budget)
                        skb_put(skb, desc->pkt_length);
                        skb->protocol = eth_type_trans(skb, nds[desc->channel]);
 
-                       dev->last_rx = jiffies;
-
                        netif_receive_skb(skb);
                }
 
index 07944820f74582b5230c4a362acac0b81eccbec6..334ff9e12cdd25c5aa131ce98e10fd485a435189 100644 (file)
@@ -208,7 +208,6 @@ static int __init jazz_sonic_probe(struct platform_device *pdev)
        struct sonic_local *lp;
        struct resource *res;
        int err = 0;
-       DECLARE_MAC_BUF(mac);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res)
@@ -233,8 +232,7 @@ static int __init jazz_sonic_probe(struct platform_device *pdev)
        if (err)
                goto out1;
 
-       printk("%s: MAC %s IRQ %d\n",
-              dev->name, print_mac(mac, dev->dev_addr), dev->irq);
+       printk("%s: MAC %pM IRQ %d\n", dev->name, dev->dev_addr, dev->irq);
 
        return 0;
 
index 81c6cdc3851f8afd54d3319df5e6e9b99d516a25..0796d0b0e3389f70ba964416e7094f01b7908750 100644 (file)
@@ -931,7 +931,6 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx)
                                RXWBFLAG_DEST_MUL)
                        ++(NET_STAT(jme).multicast);
 
-               jme->dev->last_rx = jiffies;
                NET_STAT(jme).rx_bytes += framesize;
                ++(NET_STAT(jme).rx_packets);
        }
@@ -2862,18 +2861,10 @@ jme_init_one(struct pci_dev *pdev,
                goto err_out_free_shadow;
        }
 
-       msg_probe(jme,
-               "JMC250 gigabit%s ver:%x rev:%x "
-               "macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
+       msg_probe(jme, "JMC250 gigabit%s ver:%x rev:%x macaddr:%pM\n",
                (jme->fpgaver != 0) ? " (FPGA)" : "",
                (jme->fpgaver != 0) ? jme->fpgaver : jme->chiprev,
-               jme->rev,
-               netdev->dev_addr[0],
-               netdev->dev_addr[1],
-               netdev->dev_addr[2],
-               netdev->dev_addr[3],
-               netdev->dev_addr[4],
-               netdev->dev_addr[5]);
+               jme->rev, netdev->dev_addr);
 
        return 0;
 
index e18576316bda93050cdd5849da80ef67cd85333a..63626953f07e471780e4ff831496e6c9348a6d6f 100644 (file)
@@ -409,7 +409,6 @@ static int korina_rx(struct net_device *dev, int limit)
 
                                /* Pass the packet to upper layers */
                                netif_receive_skb(skb);
-                               dev->last_rx = jiffies;
                                dev->stats.rx_packets++;
                                dev->stats.rx_bytes += pkt_len;
 
index 977ed3401bb34cd97d688800ba89340381d39e9e..f63789affb1a90f47a95f5723d3f6abd5a5aabdd 100644 (file)
@@ -466,7 +466,6 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
        unsigned long flags;
        int err = -ENOMEM;
        void __iomem *bios;
-       DECLARE_MAC_BUF(mac);
 
        /* First we look for special cases.
           Check for HP's on-board ethernet by looking for 'HP' in the BIOS.
@@ -529,7 +528,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
           The first six bytes are the station address. */
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = inb(ioaddr + i);
-       printk("%s", print_mac(mac, dev->dev_addr));
+       printk("%pM", dev->dev_addr);
 
        dev->base_addr = ioaddr;
        /* Make certain the data structures used by the LANCE are aligned and DMAble. */
@@ -1191,7 +1190,6 @@ lance_rx(struct net_device *dev)
                                        pkt_len);
                                skb->protocol=eth_type_trans(skb,dev);
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                                lp->stats.rx_packets++;
                                lp->stats.rx_bytes+=pkt_len;
                        }
index b59f442bbf36e38885e6bf35570fe7a5b9138104..7415f517491d73a6bfb7817e7f07c14f842a1923 100644 (file)
@@ -739,7 +739,6 @@ memory_squeeze:
                                skb->len = pkt_len;
                                skb->protocol = eth_type_trans(skb, dev);
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                                dev->stats.rx_packets++;
                                dev->stats.rx_bytes += pkt_len;
                        }
@@ -1034,12 +1033,8 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static void print_eth(unsigned char *add, char *str)
 {
-       DECLARE_MAC_BUF(mac);
-       DECLARE_MAC_BUF(mac2);
-
-       printk(KERN_DEBUG "i596 0x%p, %s --> %s %02X%02X, %s\n",
-              add, print_mac(mac, add + 6), print_mac(mac2, add),
-              add[12], add[13], str);
+       printk(KERN_DEBUG "i596 0x%p, %pM --> %pM %02X%02X, %s\n",
+              add, add + 6, add, add[12], add[13], str);
 }
 
 static int __devinit i82596_probe(struct net_device *dev)
@@ -1343,7 +1338,6 @@ static void set_multicast_list(struct net_device *dev)
        struct i596_private *lp = netdev_priv(dev);
        struct i596_dma *dma = lp->dma;
        int config = 0, cnt;
-       DECLARE_MAC_BUF(mac);
 
        DEB(DEB_MULTI,
            printk(KERN_DEBUG
@@ -1407,8 +1401,8 @@ static void set_multicast_list(struct net_device *dev)
                        if (i596_debug > 1)
                                DEB(DEB_MULTI,
                                    printk(KERN_DEBUG
-                                          "%s: Adding address %s\n",
-                                          dev->name, print_mac(mac, cp)));
+                                          "%s: Adding address %pM\n",
+                                          dev->name, cp));
                }
                DMA_WBACK_INV(dev, &dma->mc_cmd, sizeof(struct mc_cmd));
                i596_add_cmd(dev, &cmd->cmd);
index f80dcc11fe26bad7f594fff1407d0e036fc84935..9430167a3b130933e15cb24c825aca74d43ed1bc 100644 (file)
@@ -764,7 +764,6 @@ static void ei_receive(struct net_device *dev)
                                ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame));
                                skb->protocol=eth_type_trans(skb,dev);
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                                dev->stats.rx_packets++;
                                dev->stats.rx_bytes += pkt_len;
                                if (pkt_stat & ENRSR_PHY)
index b36989097883bc7b800bfd00269dd245b55323ff..bc70d5e79ab1727e5b74f1183d88f26a554388cd 100644 (file)
@@ -169,7 +169,6 @@ static int __init lne390_probe1(struct net_device *dev, int ioaddr)
 {
        int i, revision, ret;
        unsigned long eisa_id;
-       DECLARE_MAC_BUF(mac);
 
        if (inb_p(ioaddr + LNE390_ID_PORT) == 0xff) return -ENODEV;
 
@@ -203,8 +202,8 @@ static int __init lne390_probe1(struct net_device *dev, int ioaddr)
 
        for(i = 0; i < ETHER_ADDR_LEN; i++)
                dev->dev_addr[i] = inb(ioaddr + LNE390_SA_PROM + i);
-       printk("lne390.c: LNE390%X in EISA slot %d, address %s.\n",
-              0xa+revision, ioaddr/0x1000, print_mac(mac, dev->dev_addr));
+       printk("lne390.c: LNE390%X in EISA slot %d, address %pM.\n",
+              0xa+revision, ioaddr/0x1000, dev->dev_addr);
 
        printk("lne390.c: ");
 
index b1ac63ab8c16052abd00affc855e4971f0417066..c4516b580ba544f8d97876f01394bbe1e9b27ed0 100644 (file)
@@ -76,8 +76,6 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
 
        skb->protocol = eth_type_trans(skb,dev);
 
-       dev->last_rx = jiffies;
-
        /* it's OK to use per_cpu_ptr() because BHs are off */
        pcpu_lstats = dev->ml_priv;
        lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id());
@@ -206,17 +204,8 @@ static __net_exit void loopback_net_exit(struct net *net)
        unregister_netdev(dev);
 }
 
-static struct pernet_operations __net_initdata loopback_net_ops = {
+/* Registered in net/core/dev.c */
+struct pernet_operations __net_initdata loopback_net_ops = {
        .init = loopback_net_init,
        .exit = loopback_net_exit,
 };
-
-static int __init loopback_init(void)
-{
-       return register_pernet_device(&loopback_net_ops);
-}
-
-/* Loopback is special. It should be initialized before any other network
- * device and network subsystem.
- */
-fs_initcall(loopback_init);
index 83fa9d82a004830cecad296d2403cc1dce70c767..4d1a059921c6413d419257327cc382207298a9e7 100644 (file)
@@ -390,7 +390,7 @@ i596_timeout(struct net_device *dev, char *msg, int ct) {
        struct i596_private *lp;
        int boguscnt = ct;
 
-       lp = (struct i596_private *) dev->priv;
+       lp = netdev_priv(dev);
        while (lp->scb.command) {
                if (--boguscnt == 0) {
                        printk("%s: %s timed out - stat %4.4x, cmd %4.4x\n",
@@ -411,7 +411,7 @@ init_rx_bufs(struct net_device *dev, int num) {
        int i;
        // struct i596_rbd *rbd;
 
-       lp = (struct i596_private *) dev->priv;
+       lp = netdev_priv(dev);
        lp->scb.pa_rfd = I596_NULL;
 
        for (i = 0; i < num; i++) {
@@ -468,7 +468,7 @@ remove_rx_bufs(struct net_device *dev) {
        struct i596_private *lp;
        struct i596_rfd *rfd;
 
-       lp = (struct i596_private *) dev->priv;
+       lp = netdev_priv(dev);
        lp->rx_tail->pa_next = I596_NULL;
 
        do {
@@ -517,7 +517,7 @@ CLEAR_INT(void) {
 /* selftest or dump */
 static void
 i596_port_do(struct net_device *dev, int portcmd, char *cmdname) {
-       struct i596_private *lp = dev->priv;
+       struct i596_private *lp = netdev_priv(dev);
        u16 *outp;
        int i, m;
 
@@ -541,7 +541,7 @@ i596_port_do(struct net_device *dev, int portcmd, char *cmdname) {
 
 static int
 i596_scp_setup(struct net_device *dev) {
-       struct i596_private *lp = dev->priv;
+       struct i596_private *lp = netdev_priv(dev);
        int boguscnt;
 
        /* Setup SCP, ISCP, SCB */
@@ -622,7 +622,7 @@ init_i596(struct net_device *dev) {
        if (i596_scp_setup(dev))
                return 1;
 
-       lp = (struct i596_private *) dev->priv;
+       lp = netdev_priv(dev);
        lp->scb.command = 0;
 
        memcpy ((void *)lp->i596_config, init_setup, 14);
@@ -676,7 +676,6 @@ i596_rx_one(struct net_device *dev, struct i596_private *lp,
 
                skb->protocol = eth_type_trans(skb,dev);
                netif_rx(skb);
-               dev->last_rx = jiffies;
                dev->stats.rx_packets++;
        } else {
 #if 0
@@ -705,7 +704,7 @@ i596_rx_one(struct net_device *dev, struct i596_private *lp,
 
 static int
 i596_rx(struct net_device *dev) {
-       struct i596_private *lp = (struct i596_private *) dev->priv;
+       struct i596_private *lp = netdev_priv(dev);
        struct i596_rfd *rfd;
        int frames = 0;
 
@@ -738,7 +737,7 @@ i596_cleanup_cmd(struct net_device *dev) {
        struct i596_private *lp;
        struct i596_cmd *cmd;
 
-       lp = (struct i596_private *) dev->priv;
+       lp = netdev_priv(dev);
        while (lp->cmd_head) {
                cmd = (struct i596_cmd *)lp->cmd_head;
 
@@ -806,7 +805,7 @@ static void i596_reset(struct net_device *dev, struct i596_private *lp, int ioad
 }
 
 static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd) {
-       struct i596_private *lp = dev->priv;
+       struct i596_private *lp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
        unsigned long flags;
 
@@ -912,7 +911,7 @@ static int i596_start_xmit (struct sk_buff *skb, struct net_device *dev) {
 
 static void
 i596_tx_timeout (struct net_device *dev) {
-       struct i596_private *lp = dev->priv;
+       struct i596_private *lp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
 
        /* Transmitter timeout, serious problems. */
@@ -970,7 +969,7 @@ static int __init lp486e_probe(struct net_device *dev) {
                return -EBUSY;
        }
 
-       lp = (struct i596_private *) dev->priv;
+       lp = netdev_priv(dev);
        spin_lock_init(&lp->cmd_lock);
 
        /*
@@ -1147,7 +1146,7 @@ static irqreturn_t
 i596_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
-       struct i596_private *lp = dev->priv;
+       struct i596_private *lp = netdev_priv(dev);
        unsigned short status, ack_cmd = 0;
        int frames_in = 0;
 
@@ -1215,7 +1214,7 @@ i596_interrupt(int irq, void *dev_instance)
 }
 
 static int i596_close(struct net_device *dev) {
-       struct i596_private *lp = dev->priv;
+       struct i596_private *lp = netdev_priv(dev);
 
        netif_stop_queue(dev);
 
@@ -1242,7 +1241,7 @@ static int i596_close(struct net_device *dev) {
 */
 
 static void set_multicast_list(struct net_device *dev) {
-       struct i596_private *lp = dev->priv;
+       struct i596_private *lp = netdev_priv(dev);
        struct i596_cmd *cmd;
 
        if (i596_debug > 1)
index 4ce8afd481c3f13bd75caa570c5597c28b2a68cb..2ee477c84b06c97f3b09256cf194dde064aff981 100644 (file)
@@ -181,7 +181,6 @@ struct net_device * __init mac89x0_probe(int unit)
        unsigned long ioaddr;
        unsigned short sig;
        int err = -ENODEV;
-       DECLARE_MAC_BUF(mac);
 
        if (!MACH_IS_MAC)
                return ERR_PTR(-ENODEV);
@@ -279,8 +278,7 @@ struct net_device * __init mac89x0_probe(int unit)
 
        /* print the IRQ and ethernet address. */
 
-       printk(" IRQ %d ADDR %s\n",
-              dev->irq, print_mac(mac, dev->dev_addr));
+       printk(" IRQ %d ADDR %pM\n", dev->irq, dev->dev_addr);
 
        dev->open               = net_open;
        dev->stop               = net_close;
@@ -518,7 +516,6 @@ net_rx(struct net_device *dev)
 
         skb->protocol=eth_type_trans(skb,dev);
        netif_rx(skb);
-       dev->last_rx = jiffies;
        lp->stats.rx_packets++;
        lp->stats.rx_bytes += length;
 }
index 01f7a31bac764134f623352a3894456c7192b205..261b9507124b695e0ecf8fe91a5ea5cfae8e7f59 100644 (file)
@@ -435,7 +435,6 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
 
        bp->stats.rx_packets++;
        bp->stats.rx_bytes += len;
-       bp->dev->last_rx = jiffies;
        dev_dbg(&bp->pdev->dev, "received skb of length %u, csum: %08x\n",
                skb->len, skb->csum);
        netif_receive_skb(skb);
@@ -1104,7 +1103,6 @@ static int __init macb_probe(struct platform_device *pdev)
        unsigned long pclk_hz;
        u32 config;
        int err = -ENXIO;
-       DECLARE_MAC_BUF(mac);
 
        regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!regs) {
@@ -1223,10 +1221,8 @@ static int __init macb_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, dev);
 
-       printk(KERN_INFO "%s: Atmel MACB at 0x%08lx irq %d "
-              "(%s)\n",
-              dev->name, dev->base_addr, dev->irq,
-              print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: Atmel MACB at 0x%08lx irq %d (%pM)\n",
+              dev->name, dev->base_addr, dev->irq, dev->dev_addr);
 
        phydev = bp->phy_dev;
        printk(KERN_INFO "%s: attached PHY driver [%s] "
index 451acdca2a214a97068b46f597930b25d2e05f87..feebbd92aff2d3202d8e877cf31a6c6f13117140 100644 (file)
@@ -101,7 +101,6 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
        struct mace_data *mp;
        const unsigned char *addr;
        int j, rev, rc = -EBUSY;
-       DECLARE_MAC_BUF(mac);
 
        if (macio_resource_count(mdev) != 3 || macio_irq_count(mdev) != 3) {
                printk(KERN_ERR "can't use MACE %s: need 3 addrs and 3 irqs\n",
@@ -144,7 +143,7 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
        }
        SET_NETDEV_DEV(dev, &mdev->ofdev.dev);
 
-       mp = dev->priv;
+       mp = netdev_priv(dev);
        mp->mdev = mdev;
        macio_set_drvdata(mdev, dev);
 
@@ -165,7 +164,7 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
                        in_8(&mp->mace->chipid_lo);
 
 
-       mp = (struct mace_data *) dev->priv;
+       mp = netdev_priv(dev);
        mp->maccc = ENXMT | ENRCV;
 
        mp->tx_dma = ioremap(macio_resource_start(mdev, 1), 0x1000);
@@ -241,8 +240,8 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
                goto err_free_rx_irq;
        }
 
-       printk(KERN_INFO "%s: MACE at %s, chip revision %d.%d\n",
-              dev->name, print_mac(mac, dev->dev_addr),
+       printk(KERN_INFO "%s: MACE at %pM, chip revision %d.%d\n",
+              dev->name, dev->dev_addr,
               mp->chipid >> 8, mp->chipid & 0xff);
 
        return 0;
@@ -276,7 +275,7 @@ static int __devexit mace_remove(struct macio_dev *mdev)
 
        macio_set_drvdata(mdev, NULL);
 
-       mp = dev->priv;
+       mp = netdev_priv(dev);
 
        unregister_netdev(dev);
 
@@ -312,7 +311,7 @@ static void dbdma_reset(volatile struct dbdma_regs __iomem *dma)
 
 static void mace_reset(struct net_device *dev)
 {
-    struct mace_data *mp = (struct mace_data *) dev->priv;
+    struct mace_data *mp = netdev_priv(dev);
     volatile struct mace __iomem *mb = mp->mace;
     int i;
 
@@ -367,7 +366,7 @@ static void mace_reset(struct net_device *dev)
 
 static void __mace_set_address(struct net_device *dev, void *addr)
 {
-    struct mace_data *mp = (struct mace_data *) dev->priv;
+    struct mace_data *mp = netdev_priv(dev);
     volatile struct mace __iomem *mb = mp->mace;
     unsigned char *p = addr;
     int i;
@@ -388,7 +387,7 @@ static void __mace_set_address(struct net_device *dev, void *addr)
 
 static int mace_set_address(struct net_device *dev, void *addr)
 {
-    struct mace_data *mp = (struct mace_data *) dev->priv;
+    struct mace_data *mp = netdev_priv(dev);
     volatile struct mace __iomem *mb = mp->mace;
     unsigned long flags;
 
@@ -423,7 +422,7 @@ static inline void mace_clean_rings(struct mace_data *mp)
 
 static int mace_open(struct net_device *dev)
 {
-    struct mace_data *mp = (struct mace_data *) dev->priv;
+    struct mace_data *mp = netdev_priv(dev);
     volatile struct mace __iomem *mb = mp->mace;
     volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
     volatile struct dbdma_regs __iomem *td = mp->tx_dma;
@@ -493,7 +492,7 @@ static int mace_open(struct net_device *dev)
 
 static int mace_close(struct net_device *dev)
 {
-    struct mace_data *mp = (struct mace_data *) dev->priv;
+    struct mace_data *mp = netdev_priv(dev);
     volatile struct mace __iomem *mb = mp->mace;
     volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
     volatile struct dbdma_regs __iomem *td = mp->tx_dma;
@@ -513,7 +512,7 @@ static int mace_close(struct net_device *dev)
 
 static inline void mace_set_timeout(struct net_device *dev)
 {
-    struct mace_data *mp = (struct mace_data *) dev->priv;
+    struct mace_data *mp = netdev_priv(dev);
 
     if (mp->timeout_active)
        del_timer(&mp->tx_timeout);
@@ -526,7 +525,7 @@ static inline void mace_set_timeout(struct net_device *dev)
 
 static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
 {
-    struct mace_data *mp = (struct mace_data *) dev->priv;
+    struct mace_data *mp = netdev_priv(dev);
     volatile struct dbdma_regs __iomem *td = mp->tx_dma;
     volatile struct dbdma_cmd *cp, *np;
     unsigned long flags;
@@ -581,7 +580,7 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
 
 static void mace_set_multicast(struct net_device *dev)
 {
-    struct mace_data *mp = (struct mace_data *) dev->priv;
+    struct mace_data *mp = netdev_priv(dev);
     volatile struct mace __iomem *mb = mp->mace;
     int i, j;
     u32 crc;
@@ -656,7 +655,7 @@ static void mace_handle_misc_intrs(struct mace_data *mp, int intr, struct net_de
 static irqreturn_t mace_interrupt(int irq, void *dev_id)
 {
     struct net_device *dev = (struct net_device *) dev_id;
-    struct mace_data *mp = (struct mace_data *) dev->priv;
+    struct mace_data *mp = netdev_priv(dev);
     volatile struct mace __iomem *mb = mp->mace;
     volatile struct dbdma_regs __iomem *td = mp->tx_dma;
     volatile struct dbdma_cmd *cp;
@@ -802,7 +801,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
 static void mace_tx_timeout(unsigned long data)
 {
     struct net_device *dev = (struct net_device *) data;
-    struct mace_data *mp = (struct mace_data *) dev->priv;
+    struct mace_data *mp = netdev_priv(dev);
     volatile struct mace __iomem *mb = mp->mace;
     volatile struct dbdma_regs __iomem *td = mp->tx_dma;
     volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
@@ -873,7 +872,7 @@ static irqreturn_t mace_txdma_intr(int irq, void *dev_id)
 static irqreturn_t mace_rxdma_intr(int irq, void *dev_id)
 {
     struct net_device *dev = (struct net_device *) dev_id;
-    struct mace_data *mp = (struct mace_data *) dev->priv;
+    struct mace_data *mp = netdev_priv(dev);
     volatile struct dbdma_regs __iomem *rd = mp->rx_dma;
     volatile struct dbdma_cmd *cp, *np;
     int i, nb, stat, next;
@@ -929,7 +928,6 @@ static irqreturn_t mace_rxdma_intr(int irq, void *dev_id)
                skb->protocol = eth_type_trans(skb, dev);
                dev->stats.rx_bytes += skb->len;
                netif_rx(skb);
-               dev->last_rx = jiffies;
                mp->rx_bufs[i] = NULL;
                ++dev->stats.rx_packets;
            }
index 85587a6667b9f170d3b55686a6474c20754a4c15..274e99bb63ac28857b568e339a46088065ecf6e2 100644 (file)
@@ -194,7 +194,6 @@ static int __devinit mace_probe(struct platform_device *pdev)
        unsigned char checksum = 0;
        static int found = 0;
        int err;
-       DECLARE_MAC_BUF(mac);
 
        if (found || macintosh_config->ether_type != MAC_ETHER_MACE)
                return -ENODEV;
@@ -249,8 +248,8 @@ static int __devinit mace_probe(struct platform_device *pdev)
        dev->set_multicast_list = mace_set_multicast;
        dev->set_mac_address    = mace_set_address;
 
-       printk(KERN_INFO "%s: 68K MACE, hardware address %s\n",
-              dev->name, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: 68K MACE, hardware address %pM\n",
+              dev->name, dev->dev_addr);
 
        err = register_netdev(dev);
        if (!err)
@@ -674,7 +673,6 @@ static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf)
 
                skb->protocol = eth_type_trans(skb, dev);
                netif_rx(skb);
-               dev->last_rx = jiffies;
                dev->stats.rx_packets++;
                dev->stats.rx_bytes += frame_length;
        }
index e64c2086d33c7ea9fcd8834b408a34f46de79c67..205bb05c25d6f41a2eec0abfdb958348179d0e93 100644 (file)
@@ -220,7 +220,6 @@ static int __init mac_onboard_sonic_ethernet_addr(struct net_device *dev)
        struct sonic_local *lp = netdev_priv(dev);
        const int prom_addr = ONBOARD_SONIC_PROM_BASE;
        int i;
-       DECLARE_MAC_BUF(mac);
 
        /* On NuBus boards we can sometimes look in the ROM resources.
           No such luck for comm-slot/onboard. */
@@ -264,8 +263,8 @@ static int __init mac_onboard_sonic_ethernet_addr(struct net_device *dev)
                dev->dev_addr[1] = val >> 8;
                dev->dev_addr[0] = val & 0xff;
 
-               printk(KERN_INFO "HW Address from CAM 15: %s\n",
-                      print_mac(mac, dev->dev_addr));
+               printk(KERN_INFO "HW Address from CAM 15: %pM\n",
+                      dev->dev_addr);
        } else return 0;
 
        if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) &&
@@ -560,7 +559,6 @@ static int __init mac_sonic_probe(struct platform_device *pdev)
        struct net_device *dev;
        struct sonic_local *lp;
        int err;
-       DECLARE_MAC_BUF(mac);
 
        dev = alloc_etherdev(sizeof(struct sonic_local));
        if (!dev)
@@ -584,8 +582,7 @@ found:
        if (err)
                goto out;
 
-       printk("%s: MAC %s IRQ %d\n",
-              dev->name, print_mac(mac, dev->dev_addr), dev->irq);
+       printk("%s: MAC %pM IRQ %d\n", dev->name, dev->dev_addr, dev->irq);
 
        return 0;
 
index 42394505bb50b9a006b5d582eaef3378b1a9c5e6..cabde9ab0e4a8871b6f341d3a92fdaaccb8a74bb 100644 (file)
@@ -84,7 +84,6 @@ static void macvlan_broadcast(struct sk_buff *skb,
                        dev->stats.rx_bytes += skb->len + ETH_HLEN;
                        dev->stats.rx_packets++;
                        dev->stats.multicast++;
-                       dev->last_rx = jiffies;
 
                        nskb->dev = dev;
                        if (!compare_ether_addr(eth->h_dest, dev->broadcast))
@@ -133,7 +132,6 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
 
        dev->stats.rx_bytes += skb->len + ETH_HLEN;
        dev->stats.rx_packets++;
-       dev->last_rx = jiffies;
 
        skb->dev = dev;
        skb->pkt_type = PACKET_HOST;
@@ -333,10 +331,34 @@ static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev)
        return lowerdev->ethtool_ops->get_rx_csum(lowerdev);
 }
 
+static int macvlan_ethtool_get_settings(struct net_device *dev,
+                                       struct ethtool_cmd *cmd)
+{
+       const struct macvlan_dev *vlan = netdev_priv(dev);
+       struct net_device *lowerdev = vlan->lowerdev;
+
+       if (!lowerdev->ethtool_ops->get_settings)
+               return -EOPNOTSUPP;
+
+       return lowerdev->ethtool_ops->get_settings(lowerdev, cmd);
+}
+
+static u32 macvlan_ethtool_get_flags(struct net_device *dev)
+{
+       const struct macvlan_dev *vlan = netdev_priv(dev);
+       struct net_device *lowerdev = vlan->lowerdev;
+
+       if (!lowerdev->ethtool_ops->get_flags)
+               return 0;
+       return lowerdev->ethtool_ops->get_flags(lowerdev);
+}
+
 static const struct ethtool_ops macvlan_ethtool_ops = {
        .get_link               = ethtool_op_get_link,
+       .get_settings           = macvlan_ethtool_get_settings,
        .get_rx_csum            = macvlan_ethtool_get_rx_csum,
        .get_drvinfo            = macvlan_ethtool_get_drvinfo,
+       .get_flags              = macvlan_ethtool_get_flags,
 };
 
 static void macvlan_setup(struct net_device *dev)
index a1e22ed1f6ee5616ce9d88bde8a55940dc66fa16..c336a1f42510c09d5c9e690cc46c207f9f6880e3 100644 (file)
@@ -94,10 +94,9 @@ char o2meth_eaddr[8]={0,0,0,0,0,0,0,0};
 static inline void load_eaddr(struct net_device *dev)
 {
        int i;
-       DECLARE_MAC_BUF(mac);
        u64 macaddr;
 
-       DPRINTK("Loading MAC Address: %s\n", print_mac(mac, dev->dev_addr));
+       DPRINTK("Loading MAC Address: %pM\n", dev->dev_addr);
        macaddr = 0;
        for (i = 0; i < 6; i++)
                macaddr |= (u64)dev->dev_addr[i] << ((5 - i) * 8);
@@ -421,7 +420,6 @@ static void meth_rx(struct net_device* dev, unsigned long int_status)
                                        skb_put(skb_c, len);
                                        priv->rx_skbs[priv->rx_write] = skb;
                                        skb_c->protocol = eth_type_trans(skb_c, dev);
-                                       dev->last_rx = jiffies;
                                        dev->stats.rx_packets++;
                                        dev->stats.rx_bytes += len;
                                        netif_rx(skb_c);
index 6232227f56c33a8cfd66e59d3ffafe7589b74791..944ad47c9519f93e870c77e8f597c0dd73d8f38b 100644 (file)
@@ -776,8 +776,6 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
                } else
                        netif_receive_skb(skb);
 
-               dev->last_rx = jiffies;
-
 next:
                ++cq->mcq.cons_index;
                index = (cq->mcq.cons_index) & ring->size_mask;
index 592c01ae2c5dc119f6c6e213126099bf0557228e..b1622062b12db496cf5349fb13dcfc22d42d1a7f 100644 (file)
@@ -118,17 +118,7 @@ static int find_mgm(struct mlx4_dev *dev,
                return err;
 
        if (0)
-               mlx4_dbg(dev, "Hash for %04x:%04x:%04x:%04x:"
-                         "%04x:%04x:%04x:%04x is %04x\n",
-                         be16_to_cpu(((__be16 *) gid)[0]),
-                         be16_to_cpu(((__be16 *) gid)[1]),
-                         be16_to_cpu(((__be16 *) gid)[2]),
-                         be16_to_cpu(((__be16 *) gid)[3]),
-                         be16_to_cpu(((__be16 *) gid)[4]),
-                         be16_to_cpu(((__be16 *) gid)[5]),
-                         be16_to_cpu(((__be16 *) gid)[6]),
-                         be16_to_cpu(((__be16 *) gid)[7]),
-                         *hash);
+               mlx4_dbg(dev, "Hash for %pI6 is %04x\n", gid, *hash);
 
        *index = *hash;
        *prev  = -1;
@@ -277,16 +267,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16])
                goto out;
 
        if (index == -1) {
-               mlx4_err(dev, "MGID %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x "
-                         "not found\n",
-                         be16_to_cpu(((__be16 *) gid)[0]),
-                         be16_to_cpu(((__be16 *) gid)[1]),
-                         be16_to_cpu(((__be16 *) gid)[2]),
-                         be16_to_cpu(((__be16 *) gid)[3]),
-                         be16_to_cpu(((__be16 *) gid)[4]),
-                         be16_to_cpu(((__be16 *) gid)[5]),
-                         be16_to_cpu(((__be16 *) gid)[6]),
-                         be16_to_cpu(((__be16 *) gid)[7]));
+               mlx4_err(dev, "MGID %pI6 not found\n", gid);
                err = -EINVAL;
                goto out;
        }
index 98ddc0811f93e78b13bd37303dd2a3c572610c67..24f6d2585a6e199a8f87ed6fc7a096918bca68c6 100644 (file)
 #define mlx4_dbg(mlevel, priv, format, arg...) \
        if (NETIF_MSG_##mlevel & priv->msg_enable) \
        printk(KERN_DEBUG "%s %s: " format , DRV_NAME ,\
-               (&priv->mdev->pdev->dev)->bus_id , ## arg)
+               (dev_name(&priv->mdev->pdev->dev)) , ## arg)
 
 #define mlx4_err(mdev, format, arg...) \
        printk(KERN_ERR "%s %s: " format , DRV_NAME ,\
-               (&mdev->pdev->dev)->bus_id , ## arg)
+               (dev_name(&mdev->pdev->dev)) , ## arg)
 #define mlx4_info(mdev, format, arg...) \
        printk(KERN_INFO "%s %s: " format , DRV_NAME ,\
-               (&mdev->pdev->dev)->bus_id , ## arg)
+               (dev_name(&mdev->pdev->dev)) , ## arg)
 #define mlx4_warn(mdev, format, arg...) \
        printk(KERN_WARNING "%s %s: " format , DRV_NAME ,\
-               (&mdev->pdev->dev)->bus_id , ## arg)
+               (dev_name(&mdev->pdev->dev)) , ## arg)
 
 /*
  * Device constants
index b9dcdbd369f87b87e5e9e12650e50d7ada6d9465..b13fbc4ebd87d134eb4365180b767e83219d037a 100644 (file)
@@ -557,8 +557,6 @@ static int rxq_process(struct rx_queue *rxq, int budget)
                        skb->protocol = eth_type_trans(skb, mp->dev);
                        netif_receive_skb(skb);
                }
-
-               mp->dev->last_rx = jiffies;
        }
 
        if (rx < budget)
@@ -2592,7 +2590,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
        struct mv643xx_eth_private *mp;
        struct net_device *dev;
        struct resource *res;
-       DECLARE_MAC_BUF(mac);
        int err;
 
        pd = pdev->dev.platform_data;
@@ -2686,8 +2683,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
        if (err)
                goto out;
 
-       dev_printk(KERN_NOTICE, &dev->dev, "port %d with MAC address %s\n",
-                  mp->port_num, print_mac(mac, dev->dev_addr));
+       dev_printk(KERN_NOTICE, &dev->dev, "port %d with MAC address %pM\n",
+                  mp->port_num, dev->dev_addr);
 
        if (mp->tx_desc_sram_size > 0)
                dev_printk(KERN_NOTICE, &dev->dev, "configured with sram\n");
index 06ca4252155f40920902acae2900b76516533f0d..435e5a847c43c972cc24e9c5ab179191c113dc43 100644 (file)
@@ -67,7 +67,6 @@ struct net_device * __init mvme147lance_probe(int unit)
        u_long *addr;
        u_long address;
        int err;
-       DECLARE_MAC_BUF(mac);
 
        if (!MACH_IS_MVME147 || called)
                return ERR_PTR(-ENODEV);
@@ -102,11 +101,11 @@ struct net_device * __init mvme147lance_probe(int unit)
        dev->dev_addr[3]=address&0xff;
 
        printk("%s: MVME147 at 0x%08lx, irq %d, "
-              "Hardware Address %s\n",
+              "Hardware Address %pM\n",
               dev->name, dev->base_addr, MVME147_LANCE_IRQ,
-              print_mac(mac, dev->dev_addr));
+              dev->dev_addr);
 
-       lp = (struct m147lance_private *)dev->priv;
+       lp = netdev_priv(dev);
        lp->ram = __get_dma_pages(GFP_ATOMIC, 3);       /* 16K */
        if (!lp->ram)
        {
@@ -190,7 +189,7 @@ int __init init_module(void)
 
 void __exit cleanup_module(void)
 {
-       struct m147lance_private *lp = dev_mvme147_lance->priv;
+       struct m147lance_private *lp = netdev_priv(dev_mvme147_lance);
        unregister_netdev(dev_mvme147_lance);
        free_pages(lp->ram, 3);
        free_netdev(dev_mvme147_lance);
index b3786709730811c2b6467cabda06c55d2203ddb1..56c6f876042ce7b6a85efedd9e1adc3327deaaaa 100644 (file)
@@ -1334,7 +1334,6 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx,
                        myri10ge_vlan_ip_csum(skb, csum);
        }
        netif_receive_skb(skb);
-       dev->last_rx = jiffies;
        return 1;
 }
 
@@ -2985,7 +2984,6 @@ static void myri10ge_set_multicast_list(struct net_device *dev)
        struct dev_mc_list *mc_list;
        __be32 data[2] = { 0, 0 };
        int err;
-       DECLARE_MAC_BUF(mac);
 
        /* can be called from atomic contexts,
         * pass 1 to force atomicity in myri10ge_send_cmd() */
@@ -3032,8 +3030,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev)
                        printk(KERN_ERR "myri10ge: %s: Failed "
                               "MXGEFW_JOIN_MULTICAST_GROUP, error status:"
                               "%d\t", dev->name, err);
-                       printk(KERN_ERR "MAC %s\n",
-                              print_mac(mac, mc_list->dmi_addr));
+                       printk(KERN_ERR "MAC %pM\n", mc_list->dmi_addr);
                        goto abort;
                }
        }
index 3ad7589d6a1c36b341920e6a2c4548d34de3ff92..6833f65f8aeca2edbb67223f0ed88bf8e8e64aa4 100644 (file)
@@ -318,13 +318,10 @@ static void myri_is_not_so_happy(struct myri_eth *mp)
 #ifdef DEBUG_HEADER
 static void dump_ehdr(struct ethhdr *ehdr)
 {
-       DECLARE_MAC_BUF(mac);
-       DECLARE_MAC_BUF(mac2);
-       printk("ehdr[h_dst(%s)"
-              "h_source(%s)"
+       printk("ehdr[h_dst(%pM)"
+              "h_source(%pM)"
               "h_proto(%04x)]\n",
-              print_mac(mac, ehdr->h_dest), print_mac(mac2, ehdr->h_source),
-              ehdr->h_proto);
+              ehdr->h_dest, ehdr->h_source, ehdr->h_proto);
 }
 
 static void dump_ehdr_and_myripad(unsigned char *stuff)
@@ -528,7 +525,6 @@ static void myri_rx(struct myri_eth *mp, struct net_device *dev)
                DRX(("prot[%04x] netif_rx ", skb->protocol));
                netif_rx(skb);
 
-               dev->last_rx = jiffies;
                dev->stats.rx_packets++;
                dev->stats.rx_bytes += len;
        next:
@@ -540,7 +536,7 @@ static void myri_rx(struct myri_eth *mp, struct net_device *dev)
 static irqreturn_t myri_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev          = (struct net_device *) dev_id;
-       struct myri_eth *mp             = (struct myri_eth *) dev->priv;
+       struct myri_eth *mp             = netdev_priv(dev);
        void __iomem *lregs             = mp->lregs;
        struct myri_channel __iomem *chan = &mp->shmem->channel;
        unsigned long flags;
@@ -579,14 +575,14 @@ static irqreturn_t myri_interrupt(int irq, void *dev_id)
 
 static int myri_open(struct net_device *dev)
 {
-       struct myri_eth *mp = (struct myri_eth *) dev->priv;
+       struct myri_eth *mp = netdev_priv(dev);
 
        return myri_init(mp, in_interrupt());
 }
 
 static int myri_close(struct net_device *dev)
 {
-       struct myri_eth *mp = (struct myri_eth *) dev->priv;
+       struct myri_eth *mp = netdev_priv(dev);
 
        myri_clean_rings(mp);
        return 0;
@@ -594,7 +590,7 @@ static int myri_close(struct net_device *dev)
 
 static void myri_tx_timeout(struct net_device *dev)
 {
-       struct myri_eth *mp = (struct myri_eth *) dev->priv;
+       struct myri_eth *mp = netdev_priv(dev);
 
        printk(KERN_ERR "%s: transmit timed out, resetting\n", dev->name);
 
@@ -605,7 +601,7 @@ static void myri_tx_timeout(struct net_device *dev)
 
 static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct myri_eth *mp = (struct myri_eth *) dev->priv;
+       struct myri_eth *mp = netdev_priv(dev);
        struct sendq __iomem *sq = mp->sq;
        struct myri_txd __iomem *txd;
        unsigned long flags;
@@ -905,7 +901,6 @@ static int __devinit myri_sbus_probe(struct of_device *op, const struct of_devic
        struct device_node *dp = op->node;
        static unsigned version_printed;
        struct net_device *dev;
-       DECLARE_MAC_BUF(mac);
        struct myri_eth *mp;
        const void *prop;
        static int num;
@@ -1088,8 +1083,8 @@ static int __devinit myri_sbus_probe(struct of_device *op, const struct of_devic
 
        num++;
 
-       printk("%s: MyriCOM MyriNET Ethernet %s\n",
-              dev->name, print_mac(mac, dev->dev_addr));
+       printk("%s: MyriCOM MyriNET Ethernet %pM\n",
+              dev->name, dev->dev_addr);
 
        return 0;
 
index f7fa3944659bab47cac4e516c104dad5fd58890d..9f81fcb968824386efa12fe3fe97967c2dc02fdd 100644 (file)
@@ -792,7 +792,6 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
        const int pcibar = 1; /* PCI base address register */
        int prev_eedata;
        u32 tmp;
-       DECLARE_MAC_BUF(mac);
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -948,10 +947,10 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
 
        if (netif_msg_drv(np)) {
                printk(KERN_INFO "natsemi %s: %s at %#08llx "
-                      "(%s), %s, IRQ %d",
+                      "(%s), %pM, IRQ %d",
                       dev->name, natsemi_pci_info[chip_idx].name,
                       (unsigned long long)iostart, pci_name(np->pci_dev),
-                      print_mac(mac, dev->dev_addr), irq);
+                      dev->dev_addr, irq);
                if (dev->if_port == PORT_TP)
                        printk(", port TP.\n");
                else if (np->ignore_phy)
@@ -2362,7 +2361,6 @@ static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do)
                        }
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_receive_skb(skb);
-                       dev->last_rx = jiffies;
                        np->stats.rx_packets++;
                        np->stats.rx_bytes += pkt_len;
                }
index fbc7531d3c7d8aed647056c905e4aa74a476b0e8..aa99f5e09d374319a153392da72b1f254abdce2e 100644 (file)
@@ -204,7 +204,6 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
        static unsigned version_printed;
        struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
        unsigned char bus_width;
-       DECLARE_MAC_BUF(mac);
 
        if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME))
                return -EBUSY;
@@ -299,7 +298,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
 
        for(i = 0; i < ETHER_ADDR_LEN; i++)
                dev->dev_addr[i] = SA_prom[i];
-       printk(" %s\n", print_mac(mac, dev->dev_addr));
+       printk(" %pM\n", dev->dev_addr);
 
        printk("%s: %s found at %#x, using IRQ %d.\n",
                dev->name, name, ioaddr, dev->irq);
index eb681c0d51ba1ef61b7537bd6974a9413eabf66e..f708712a374a610aa8fb3725426fbbc312bfaf08 100644 (file)
@@ -297,7 +297,6 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
        int neX000, ctron, copam, bad_card;
        int reg0, ret;
        static unsigned version_printed;
-       DECLARE_MAC_BUF(mac);
 
        if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME))
                return -EBUSY;
@@ -517,7 +516,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
        }
 #endif
 
-       printk("%s\n", print_mac(mac, dev->dev_addr));
+       printk("%pM\n", dev->dev_addr);
 
        ei_status.name = name;
        ei_status.tx_start_page = start_page;
index 332df75a9ab66a06eb150ede9662d2f843807c0f..6f8f32603466384df3b2df1805fd2ce38cb6f4cc 100644 (file)
@@ -302,7 +302,6 @@ out:
 static int ne2_procinfo(char *buf, int slot, struct net_device *dev)
 {
        int len=0;
-       DECLARE_MAC_BUF(mac);
 
        len += sprintf(buf+len, "The NE/2 Ethernet Adapter\n" );
        len += sprintf(buf+len, "Driver written by Wim Dumon ");
@@ -313,7 +312,7 @@ static int ne2_procinfo(char *buf, int slot, struct net_device *dev)
        len += sprintf(buf+len, "Based on the original NE2000 drivers\n" );
        len += sprintf(buf+len, "Base IO: %#x\n", (unsigned int)dev->base_addr);
        len += sprintf(buf+len, "IRQ    : %d\n", dev->irq);
-       len += sprintf(buf+len, "HW addr : %s\n", print_mac(mac, dev->dev_addr));
+       len += sprintf(buf+len, "HW addr : %pM\n", dev->dev_addr);
 
        return len;
 }
@@ -326,7 +325,6 @@ static int __init ne2_probe1(struct net_device *dev, int slot)
        const char *name = "NE/2";
        int start_page, stop_page;
        static unsigned version_printed;
-       DECLARE_MAC_BUF(mac);
 
        if (ei_debug && version_printed++ == 0)
                printk(version);
@@ -469,7 +467,7 @@ static int __init ne2_probe1(struct net_device *dev, int slot)
        for(i = 0; i < ETHER_ADDR_LEN; i++)
                dev->dev_addr[i] = SA_prom[i];
 
-       printk(" %s\n", print_mac(mac, dev->dev_addr));
+       printk(" %pM\n", dev->dev_addr);
 
        printk("%s: %s found at %#x, using IRQ %d.\n",
                        dev->name, name, base_addr, dev->irq);
index de0de744a8fa4e1fe961cc89e301046b862a8e51..ea22ae268a5d66288e44d46f4792c9fb79a4dc12 100644 (file)
@@ -212,7 +212,6 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
        static unsigned int fnd_cnt;
        long ioaddr;
        int flags = pci_clone_list[chip_idx].flags;
-       DECLARE_MAC_BUF(mac);
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -368,9 +367,9 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
 
        for(i = 0; i < 6; i++)
                dev->dev_addr[i] = SA_prom[i];
-       printk("%s: %s found at %#lx, IRQ %d, %s.\n",
+       printk("%s: %s found at %#lx, IRQ %d, %pM.\n",
               dev->name, pci_clone_list[chip_idx].name, ioaddr, dev->irq,
-              print_mac(mac, dev->dev_addr));
+              dev->dev_addr);
 
        memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
@@ -626,7 +625,7 @@ static void ne2k_pci_block_output(struct net_device *dev, int count,
 static void ne2k_pci_get_drvinfo(struct net_device *dev,
                                 struct ethtool_drvinfo *info)
 {
-       struct ei_device *ei = dev->priv;
+       struct ei_device *ei = netdev_priv(dev);
        struct pci_dev *pci_dev = (struct pci_dev *) ei->priv;
 
        strcpy(info->driver, DRV_NAME);
index 425043a88db9e9409d958006a30fafddcd200fbe..6681ca748c74224e9e48ad0af562d009b894a8cd 100644 (file)
@@ -99,7 +99,6 @@ static int __init ne3210_eisa_probe (struct device *device)
        int i, retval, port_index;
        struct eisa_device *edev = to_eisa_device (device);
        struct net_device *dev;
-       DECLARE_MAC_BUF(mac);
 
        /* Allocate dev->priv and fill in 8390 specific dev fields. */
        if (!(dev = alloc_ei_netdev ())) {
@@ -131,8 +130,8 @@ static int __init ne3210_eisa_probe (struct device *device)
        port_index = inb(ioaddr + NE3210_CFG2) >> 6;
        for(i = 0; i < ETHER_ADDR_LEN; i++)
                dev->dev_addr[i] = inb(ioaddr + NE3210_SA_PROM + i);
-       printk("ne3210.c: NE3210 in EISA slot %d, media: %s, addr: %s.\n",
-               edev->slot, ifmap[port_index], print_mac(mac, dev->dev_addr));
+       printk("ne3210.c: NE3210 in EISA slot %d, media: %s, addr: %pM.\n",
+               edev->slot, ifmap[port_index], dev->dev_addr);
 
        /* Snarf the interrupt now. CFG file has them all listed as `edge' with share=NO */
        dev->irq = irq_map[(inb(ioaddr + NE3210_CFG2) >> 3) & 0x07];
index 9681618c32321912c522e9953cd71eac4db06443..d304d38cd5d1728c45587efa0a986ca207d21240 100644 (file)
@@ -307,17 +307,14 @@ static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf)
 static ssize_t show_local_mac(struct netconsole_target *nt, char *buf)
 {
        struct net_device *dev = nt->np.dev;
+       static const u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
-       DECLARE_MAC_BUF(mac);
-       return snprintf(buf, PAGE_SIZE, "%s\n", dev ?
-                       print_mac(mac, dev->dev_addr) : "ff:ff:ff:ff:ff:ff");
+       return snprintf(buf, PAGE_SIZE, "%pM\n", dev ? dev->dev_addr : bcast);
 }
 
 static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf)
 {
-       DECLARE_MAC_BUF(mac);
-       return snprintf(buf, PAGE_SIZE, "%s\n",
-                       print_mac(mac, nt->np.remote_mac));
+       return snprintf(buf, PAGE_SIZE, "%pM\n", nt->np.remote_mac);
 }
 
 /*
index b9bed82e1d214089f5b4e6682a965e11c781d6e5..b418771f68110154237436cd7aedcf5b7b3e51e2 100644 (file)
@@ -165,7 +165,6 @@ static void netx_eth_receive(struct net_device *ndev)
        pfifo_push(EMPTY_PTR_FIFO(priv->id),
                FIFO_PTR_SEGMENT(seg) | FIFO_PTR_FRAMENO(frameno));
 
-       ndev->last_rx = jiffies;
        skb->protocol = eth_type_trans(skb, ndev);
        netif_rx(skb);
        ndev->stats.rx_packets++;
index 84978f80f396e681eefa0e8cc76bac57e1ea232c..86379fdd8b0e1c377a0c51029efc69197d93f04f 100644 (file)
@@ -537,7 +537,7 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
 static int nx_p3_sre_macaddr_change(struct net_device *dev,
                u8 *addr, unsigned op)
 {
-       struct netxen_adapter *adapter = (struct netxen_adapter *)dev->priv;
+       struct netxen_adapter *adapter = netdev_priv(dev);
        nx_nic_req_t req;
        nx_mac_req_t mac_req;
        int rv;
index 5bba675d0504594fc340ab3223956d167d4ef0ea..d924468e506eb48af997a075ad3b51d69800b876 100644 (file)
@@ -1285,9 +1285,7 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
                }
                adapter->stats.rxdropped++;
        } else {
-
                netif_receive_skb(skb);
-               netdev->last_rx = jiffies;
 
                adapter->stats.no_rcv++;
                adapter->stats.rxbytes += length;
index 6ef3f0d84bcf45e8704aaf21958508086df52ee1..25bfb3acf5e462a8f0e58ddeac7c5e4d337467b1 100644 (file)
@@ -439,7 +439,6 @@ netxen_read_mac_addr(struct netxen_adapter *adapter)
        int i;
        unsigned char *p;
        __le64 mac_addr;
-       DECLARE_MAC_BUF(mac);
        struct net_device *netdev = adapter->netdev;
        struct pci_dev *pdev = adapter->pdev;
 
@@ -462,10 +461,9 @@ netxen_read_mac_addr(struct netxen_adapter *adapter)
 
        /* set station address */
 
-       if (!is_valid_ether_addr(netdev->perm_addr)) {
-               dev_warn(&pdev->dev, "Bad MAC address %s.\n",
-                               print_mac(mac, netdev->dev_addr));
-       } else
+       if (!is_valid_ether_addr(netdev->perm_addr))
+               dev_warn(&pdev->dev, "Bad MAC address %pM.\n", netdev->dev_addr);
+       else
                adapter->macaddr_set(adapter, netdev->dev_addr);
 
        return 0;
@@ -543,7 +541,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        SET_NETDEV_DEV(netdev, &pdev->dev);
 
-       adapter = netdev->priv;
+       adapter = netdev_priv(netdev);
        adapter->netdev  = netdev;
        adapter->pdev    = pdev;
        adapter->ahw.pci_func  = pci_func_id;
@@ -988,7 +986,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
  */
 static int netxen_nic_open(struct net_device *netdev)
 {
-       struct netxen_adapter *adapter = (struct netxen_adapter *)netdev->priv;
+       struct netxen_adapter *adapter = netdev_priv(netdev);
        int err = 0;
        int ctx, ring;
        irq_handler_t handler;
index 27f07f6a45b1229f8a53afd8c4026f59bbcdb055..c3b9c83b32fe5205925a4686e0874c2f4aa7e96b 100644 (file)
@@ -608,7 +608,6 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
        int phy = adapter->physical_port;
        unsigned char mac_addr[6];
        int i;
-       DECLARE_MAC_BUF(mac);
 
        if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
                return 0;
@@ -636,10 +635,8 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
        if (i == 10) {
                printk(KERN_ERR "%s: cannot set Mac addr for %s\n",
                       netxen_nic_driver_name, adapter->netdev->name);
-               printk(KERN_ERR "MAC address set: %s.\n",
-                      print_mac(mac, addr));
-               printk(KERN_ERR "MAC address get: %s.\n",
-                      print_mac(mac, mac_addr));
+               printk(KERN_ERR "MAC address set: %pM.\n", addr);
+               printk(KERN_ERR "MAC address get: %pM.\n", mac_addr);
        }
        return 0;
 }
index 8e0ca9f4e40479f3fa6ff43c429d45cb69da1b52..0cf6addbe40fb03975e5031ee22de94588fac3cb 100644 (file)
@@ -203,7 +203,6 @@ static int __init ni5010_probe1(struct net_device *dev, int ioaddr)
        unsigned int data = 0;
        int boguscount = 40;
        int err = -ENODEV;
-       DECLARE_MAC_BUF(mac);
 
        dev->base_addr = ioaddr;
        dev->irq = irq;
@@ -271,7 +270,7 @@ static int __init ni5010_probe1(struct net_device *dev, int ioaddr)
                outw(i, IE_GP);
                dev->dev_addr[i] = inb(IE_SAPROM);
        }
-       printk("%s ", print_mac(mac, dev->dev_addr));
+       printk("%pM ", dev->dev_addr);
 
        PRINTK2((KERN_DEBUG "%s: I/O #4 passed!\n", dev->name));
 
@@ -329,7 +328,7 @@ static int __init ni5010_probe1(struct net_device *dev, int ioaddr)
                outb(0, IE_RBUF);       /* set buffer byte 0 to 0 again */
        }
         printk("-> bufsize rcv/xmt=%d/%d\n", bufsize_rcv, NI5010_BUFSIZE);
-       memset(dev->priv, 0, sizeof(struct ni5010_local));
+       memset(netdev_priv(dev), 0, sizeof(struct ni5010_local));
 
        dev->open               = ni5010_open;
        dev->stop               = ni5010_close;
@@ -570,7 +569,6 @@ static void ni5010_rx(struct net_device *dev)
 
        skb->protocol = eth_type_trans(skb,dev);
        netif_rx(skb);
-       dev->last_rx = jiffies;
        dev->stats.rx_packets++;
        dev->stats.rx_bytes += i_pkt_size;
 
index b9a882d362da1f7bdbc34c76be0958815fc2c684..10cfd0f91fc081e1957f28ec997adf41c57351f2 100644 (file)
@@ -214,7 +214,7 @@ struct priv {
 /* wait for command with timeout: */
 static void wait_for_scb_cmd(struct net_device *dev)
 {
-       struct priv *p = dev->priv;
+       struct priv *p = netdev_priv(dev);
        int i;
        for (i = 0; i < 16384; i++) {
                if (readb(&p->scb->cmd_cuc) == 0)
@@ -233,7 +233,7 @@ static void wait_for_scb_cmd(struct net_device *dev)
 
 static void wait_for_scb_cmd_ruc(struct net_device *dev)
 {
-       struct priv *p = dev->priv;
+       struct priv *p = netdev_priv(dev);
        int i;
        for (i = 0; i < 16384; i++) {
                if (readb(&p->scb->cmd_ruc) == 0)
@@ -298,7 +298,7 @@ static int ni52_open(struct net_device *dev)
 static int check_iscp(struct net_device *dev, void __iomem *addr)
 {
        struct iscp_struct __iomem *iscp = addr;
-       struct priv *p = dev->priv;
+       struct priv *p = netdev_priv(dev);
        memset_io(iscp, 0, sizeof(struct iscp_struct));
 
        writel(make24(iscp), &p->scp->iscp);
@@ -318,7 +318,7 @@ static int check_iscp(struct net_device *dev, void __iomem *addr)
  */
 static int check586(struct net_device *dev, unsigned size)
 {
-       struct priv *p = dev->priv;
+       struct priv *p = netdev_priv(dev);
        int i;
 
        p->mapped = ioremap(dev->mem_start, size);
@@ -354,7 +354,7 @@ Enodev:
  */
 static void alloc586(struct net_device *dev)
 {
-       struct priv *p =        (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        ni_reset586();
        mdelay(32);
@@ -400,7 +400,7 @@ struct net_device * __init ni52_probe(int unit)
        if (!dev)
                return ERR_PTR(-ENOMEM);
 
-       p = dev->priv;
+       p = netdev_priv(dev);
 
        if (unit >= 0) {
                sprintf(dev->name, "eth%d", unit);
@@ -446,7 +446,7 @@ out:
 static int __init ni52_probe1(struct net_device *dev, int ioaddr)
 {
        int i, size, retval;
-       struct priv *priv = dev->priv;
+       struct priv *priv = netdev_priv(dev);
 
        dev->base_addr = ioaddr;
        dev->irq = irq;
@@ -588,7 +588,7 @@ static int init586(struct net_device *dev)
 {
        void __iomem *ptr;
        int i, result = 0;
-       struct priv *p = (struct priv *)dev->priv;
+       struct priv *p = netdev_priv(dev);
        struct configure_cmd_struct __iomem *cfg_cmd;
        struct iasetup_cmd_struct __iomem *ias_cmd;
        struct tdr_cmd_struct __iomem *tdr_cmd;
@@ -829,7 +829,7 @@ static void __iomem *alloc_rfa(struct net_device *dev, void __iomem *ptr)
        struct rfd_struct __iomem *rfd = ptr;
        struct rbd_struct __iomem *rbd;
        int i;
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        memset_io(rfd, 0,
                sizeof(struct rfd_struct) * (p->num_recv_buffs + rfdadd));
@@ -878,7 +878,7 @@ static irqreturn_t ni52_interrupt(int irq, void *dev_id)
        int cnt = 0;
        struct priv *p;
 
-       p = (struct priv *) dev->priv;
+       p = netdev_priv(dev);
 
        if (debuglevel > 1)
                printk("I");
@@ -950,7 +950,7 @@ static void ni52_rcv_int(struct net_device *dev)
        unsigned short totlen;
        struct sk_buff *skb;
        struct rbd_struct __iomem *rbd;
-       struct priv *p = (struct priv *)dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        if (debuglevel > 0)
                printk("R");
@@ -970,7 +970,6 @@ static void ni52_rcv_int(struct net_device *dev)
                                        memcpy_fromio(skb->data, p->base + readl(&rbd->buffer), totlen);
                                        skb->protocol = eth_type_trans(skb, dev);
                                        netif_rx(skb);
-                                       dev->last_rx = jiffies;
                                        p->stats.rx_packets++;
                                        p->stats.rx_bytes += totlen;
                                } else
@@ -1040,7 +1039,7 @@ static void ni52_rcv_int(struct net_device *dev)
 
 static void ni52_rnr_int(struct net_device *dev)
 {
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        p->stats.rx_errors++;
 
@@ -1065,7 +1064,7 @@ static void ni52_rnr_int(struct net_device *dev)
 static void ni52_xmt_int(struct net_device *dev)
 {
        int status;
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        if (debuglevel > 0)
                printk("X");
@@ -1113,7 +1112,7 @@ static void ni52_xmt_int(struct net_device *dev)
 
 static void startrecv586(struct net_device *dev)
 {
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        wait_for_scb_cmd(dev);
        wait_for_scb_cmd_ruc(dev);
@@ -1126,7 +1125,7 @@ static void startrecv586(struct net_device *dev)
 
 static void ni52_timeout(struct net_device *dev)
 {
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 #ifndef NO_NOPCOMMANDS
        if (readb(&p->scb->cus) & CU_ACTIVE) { /* COMMAND-UNIT active? */
                netif_wake_queue(dev);
@@ -1177,7 +1176,7 @@ static int ni52_send_packet(struct sk_buff *skb, struct net_device *dev)
 #ifndef NO_NOPCOMMANDS
        int next_nop;
 #endif
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        if (skb->len > XMIT_BUFF_SIZE) {
                printk(KERN_ERR "%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n", dev->name, XMIT_BUFF_SIZE, skb->len);
@@ -1274,7 +1273,7 @@ static int ni52_send_packet(struct sk_buff *skb, struct net_device *dev)
 
 static struct net_device_stats *ni52_get_stats(struct net_device *dev)
 {
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
        unsigned short crc, aln, rsc, ovrn;
 
        /* Get error-statistics from the ni82586 */
@@ -1337,7 +1336,7 @@ int __init init_module(void)
 
 void __exit cleanup_module(void)
 {
-       struct priv *p = dev_ni52->priv;
+       struct priv *p = netdev_priv(dev_ni52);
        unregister_netdev(dev_ni52);
        iounmap(p->mapped);
        release_region(dev_ni52->base_addr, NI52_TOTAL_SIZE);
index 3edc971d0ecabfba1ecfdee18af52bc5e1204682..24e393b3e0b7953bed2305470c96b0c0d5469ebe 100644 (file)
@@ -1113,7 +1113,6 @@ static void ni65_recv_intr(struct net_device *dev,int csr0)
                                p->stats.rx_bytes += len;
                                skb->protocol=eth_type_trans(skb,dev);
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                        }
                        else
                        {
index 1b6f548c4411203a7666e0f1703de8fcec4aabf5..5ddca4e3d27b44c9c2868f14a0f01f54fab71d78 100644 (file)
@@ -3392,8 +3392,6 @@ static int niu_process_rx_pkt(struct niu *np, struct rx_ring_info *rp)
        skb->protocol = eth_type_trans(skb, np->dev);
        netif_receive_skb(skb);
 
-       np->dev->last_rx = jiffies;
-
        return num_rcr;
 }
 
@@ -8909,10 +8907,8 @@ static void __devinit niu_assign_netdev_ops(struct net_device *dev)
 static void __devinit niu_device_announce(struct niu *np)
 {
        struct net_device *dev = np->dev;
-       DECLARE_MAC_BUF(mac);
 
-       pr_info("%s: NIU Ethernet %s\n",
-               dev->name, print_mac(mac, dev->dev_addr));
+       pr_info("%s: NIU Ethernet %pM\n", dev->name, dev->dev_addr);
 
        if (np->parent->plat_type == PLAT_TYPE_ATCA_CP3220) {
                pr_info("%s: Port type[%s] mode[%s:%s] XCVR[%s] phy[%s]\n",
index ff449619f047e57fd36be41805b33bf6b66ec113..4bb64415437f7f752324d98bedcb919c6dfb7d9d 100644 (file)
@@ -1955,7 +1955,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
        long addr;
        int err;
        int using_dac = 0;
-       DECLARE_MAC_BUF(mac);
 
        /* See if we can set the dma mask early on; failure is fatal. */
        if (sizeof(dma_addr_t) == 8 &&
@@ -2220,12 +2219,11 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
                ndev->features |= NETIF_F_HIGHDMA;
        }
 
-       printk(KERN_INFO "%s: ns83820 v" VERSION ": DP83820 v%u.%u: %s io=0x%08lx irq=%d f=%s\n",
+       printk(KERN_INFO "%s: ns83820 v" VERSION ": DP83820 v%u.%u: %pM io=0x%08lx irq=%d f=%s\n",
                ndev->name,
                (unsigned)readl(dev->base + SRR) >> 8,
                (unsigned)readl(dev->base + SRR) & 0xff,
-               print_mac(mac, ndev->dev_addr),
-               addr, pci_dev->irq,
+               ndev->dev_addr, addr, pci_dev->irq,
                (ndev->features & NETIF_F_HIGHDMA) ? "h,sg" : "sg"
                );
 
index edc0fd588985f51da906e325398ae36bac2f715c..fcbf6ccd0a85480125d63baef07b1a283abf9752 100644 (file)
@@ -1105,7 +1105,8 @@ static int pasemi_mac_phy_init(struct net_device *dev)
                goto err;
 
        phy_id = *prop;
-       snprintf(mac->phy_id, BUS_ID_SIZE, "%x:%02x", (int)r.start, phy_id);
+       snprintf(mac->phy_id, sizeof(mac->phy_id), "%x:%02x",
+                (int)r.start, phy_id);
 
        of_node_put(phy_dn);
 
@@ -1742,7 +1743,6 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        struct net_device *dev;
        struct pasemi_mac *mac;
        int err;
-       DECLARE_MAC_BUF(mac_buf);
 
        err = pci_enable_device(pdev);
        if (err)
@@ -1849,9 +1849,9 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                        err);
                goto out;
        } else if netif_msg_probe(mac)
-               printk(KERN_INFO "%s: PA Semi %s: intf %d, hw addr %s\n",
+               printk(KERN_INFO "%s: PA Semi %s: intf %d, hw addr %pM\n",
                       dev->name, mac->type == MAC_TYPE_GMAC ? "GMAC" : "XAUI",
-                      mac->dma_if, print_mac(mac_buf, dev->dev_addr));
+                      mac->dma_if, dev->dev_addr);
 
        return err;
 
index 5e8df3afea64e9fedaa15333910d970365bffd87..064a4fe1dd90efcee86a805ed6e94e1037385c2b 100644 (file)
@@ -109,7 +109,7 @@ static void
 pasemi_mac_ethtool_get_ringparam(struct net_device *netdev,
                                 struct ethtool_ringparam *ering)
 {
-       struct pasemi_mac *mac = netdev->priv;
+       struct pasemi_mac *mac = netdev_priv(netdev);
 
        ering->tx_max_pending = TX_RING_SIZE/2;
        ering->tx_pending = RING_USED(mac->tx)/2;
@@ -130,7 +130,7 @@ static int pasemi_mac_get_sset_count(struct net_device *netdev, int sset)
 static void pasemi_mac_get_ethtool_stats(struct net_device *netdev,
                struct ethtool_stats *stats, u64 *data)
 {
-       struct pasemi_mac *mac = netdev->priv;
+       struct pasemi_mac *mac = netdev_priv(netdev);
        int i;
 
        data[0] = pasemi_read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if))
index 0a575fef29e64521b727ce231ae0cd7510589795..b23b5c397b1d27410d3fc94576502504a7c1d5f0 100644 (file)
@@ -737,7 +737,6 @@ static int __devinit netdrv_init_one (struct pci_dev *pdev,
        int i, addr_len, option;
        void *ioaddr = NULL;
        static int board_idx = -1;
-       DECLARE_MAC_BUF(mac);
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -797,11 +796,11 @@ static int __devinit netdrv_init_one (struct pci_dev *pdev,
 
        tp->phys[0] = 32;
 
-       printk (KERN_INFO "%s: %s at 0x%lx, %sIRQ %d\n",
+       printk (KERN_INFO "%s: %s at 0x%lx, %pM IRQ %d\n",
                dev->name,
                board_info[ent->driver_data].name,
                dev->base_addr,
-               print_mac(mac, dev->dev_addr),
+               dev->dev_addr,
                dev->irq);
 
        printk (KERN_DEBUG "%s:  Identified 8139 chip type '%s'\n",
@@ -1566,7 +1565,6 @@ static void netdrv_rx_interrupt (struct net_device *dev,
 
                        skb->protocol = eth_type_trans (skb, dev);
                        netif_rx (skb);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_bytes += pkt_size;
                        dev->stats.rx_packets++;
                } else {
index 08c4dd896077b7199762821264c522cc721b065a..e5cb6b1f0ebd8be1aada0898403e79cb3a25d40f 100644 (file)
@@ -345,7 +345,6 @@ static int tc574_config(struct pcmcia_device *link)
        __be16 *phys_addr;
        char *cardname;
        __u32 config;
-       DECLARE_MAC_BUF(mac);
 
        phys_addr = (__be16 *)dev->dev_addr;
 
@@ -463,9 +462,9 @@ static int tc574_config(struct pcmcia_device *link)
        strcpy(lp->node.dev_name, dev->name);
 
        printk(KERN_INFO "%s: %s at io %#3lx, irq %d, "
-              "hw_addr %s.\n",
+              "hw_addr %pM.\n",
               dev->name, cardname, dev->base_addr, dev->irq,
-              print_mac(mac, dev->dev_addr));
+              dev->dev_addr);
        printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n",
                   8 << config & Ram_size,
                   ram_split[(config & Ram_split) >> Ram_split_shift],
@@ -1062,7 +1061,6 @@ static int el3_rx(struct net_device *dev, int worklimit)
                                                ((pkt_len+3)>>2));
                                skb->protocol = eth_type_trans(skb, dev);
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                                dev->stats.rx_packets++;
                                dev->stats.rx_bytes += pkt_len;
                        } else {
index c235cdba69c6384d11b83ace2b2a1aac2f4a1905..73ecc657999d69e899e4ddb2537e6aa1db376b1d 100644 (file)
@@ -255,7 +255,6 @@ static int tc589_config(struct pcmcia_device *link)
     int last_fn, last_ret, i, j, multi = 0, fifo;
     unsigned int ioaddr;
     char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
-    DECLARE_MAC_BUF(mac);
     
     DEBUG(0, "3c589_config(0x%p)\n", link);
 
@@ -333,9 +332,9 @@ static int tc589_config(struct pcmcia_device *link)
     strcpy(lp->node.dev_name, dev->name);
 
     printk(KERN_INFO "%s: 3Com 3c%s, io %#3lx, irq %d, "
-          "hw_addr %s\n",
+          "hw_addr %pM\n",
           dev->name, (multi ? "562" : "589"), dev->base_addr, dev->irq,
-          print_mac(mac, dev->dev_addr));
+          dev->dev_addr);
     printk(KERN_INFO "  %dK FIFO split %s Rx:Tx, %s xcvr\n",
           (fifo & 7) ? 32 : 8, ram_split[(fifo >> 16) & 3],
           if_names[dev->if_port]);
@@ -884,7 +883,6 @@ static int el3_rx(struct net_device *dev)
                        (pkt_len+3)>>2);
                skb->protocol = eth_type_trans(skb, dev);
                netif_rx(skb);
-               dev->last_rx = jiffies;
                dev->stats.rx_packets++;
                dev->stats.rx_bytes += pkt_len;
            } else {
index b37a498939ae7d1a16f6e1a5c0ad8545f6d32380..2aca8df34970f0276da54d4aad021c9d40967544 100644 (file)
@@ -321,7 +321,6 @@ static int axnet_config(struct pcmcia_device *link)
     struct net_device *dev = link->priv;
     axnet_dev_t *info = PRIV(dev);
     int i, j, last_ret, last_fn;
-    DECLARE_MAC_BUF(mac);
 
     DEBUG(0, "axnet_config(0x%p)\n", link);
 
@@ -397,10 +396,10 @@ static int axnet_config(struct pcmcia_device *link)
     strcpy(info->node.dev_name, dev->name);
 
     printk(KERN_INFO "%s: Asix AX88%d90: io %#3lx, irq %d, "
-          "hw_addr %s\n",
+          "hw_addr %pM\n",
           dev->name, ((info->flags & IS_AX88790) ? 7 : 1),
           dev->base_addr, dev->irq,
-          print_mac(mac, dev->dev_addr));
+          dev->dev_addr);
     if (info->phy_id != -1) {
        DEBUG(0, "  MII transceiver at index %d, status %x.\n", info->phy_id, j);
     } else {
@@ -1493,7 +1492,6 @@ static void ei_receive(struct net_device *dev)
                                ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame));
                                skb->protocol=eth_type_trans(skb,dev);
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                                dev->stats.rx_packets++;
                                dev->stats.rx_bytes += pkt_len;
                                if (pkt_stat & ENRSR_PHY)
index 831090c756220fcc86743067d62eb36683517b57..7b5c77b7bd27ebc9185a99da37ac7bc0871c96fb 100644 (file)
@@ -155,7 +155,7 @@ static int com20020_probe(struct pcmcia_device *p_dev)
     if (!dev)
        goto fail_alloc_dev;
 
-    lp = dev->priv;
+    lp = netdev_priv(dev);
     lp->timeout = timeout;
     lp->backplane = backplane;
     lp->clockp = clockp;
@@ -303,7 +303,7 @@ static int com20020_config(struct pcmcia_device *link)
        goto failed;
     }
     
-    lp = dev->priv;
+    lp = netdev_priv(dev);
     lp->card_name = "PCMCIA COM20020";
     lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
 
@@ -364,7 +364,7 @@ static int com20020_resume(struct pcmcia_device *link)
 
        if (link->open) {
                int ioaddr = dev->base_addr;
-               struct arcnet_local *lp = dev->priv;
+               struct arcnet_local *lp = netdev_priv(dev);
                ARCRESET;
        }
 
index 69d916daa7bbb313440dbd4c2827a6779a715376..69dcfbbabe825229ca4f709315b9e29c9049cd76 100644 (file)
@@ -125,6 +125,7 @@ typedef struct local_info_t {
     u_short tx_queue_len;
     cardtype_t cardtype;
     u_short sent;
+    u_char __iomem *base;
 } local_info_t;
 
 #define MC_FILTERBREAK 64
@@ -242,6 +243,7 @@ static int fmvj18x_probe(struct pcmcia_device *link)
     lp = netdev_priv(dev);
     link->priv = dev;
     lp->p_dev = link;
+    lp->base = NULL;
 
     /* The io structure describes IO port mapping */
     link->io.NumPorts1 = 32;
@@ -348,7 +350,6 @@ static int fmvj18x_config(struct pcmcia_device *link)
     cardtype_t cardtype;
     char *card_name = "unknown";
     u_char *node_id;
-    DECLARE_MAC_BUF(mac);
 
     DEBUG(0, "fmvj18x_config(0x%p)\n", link);
 
@@ -443,8 +444,10 @@ static int fmvj18x_config(struct pcmcia_device *link)
     dev->irq = link->irq.AssignedIRQ;
     dev->base_addr = link->io.BasePort1;
 
-    if (link->io.BasePort2 != 0)
-       fmvj18x_setup_mfc(link);
+    if (link->io.BasePort2 != 0) {
+       ret = fmvj18x_setup_mfc(link);
+       if (ret != 0) goto failed;
+    }
 
     ioaddr = dev->base_addr;
 
@@ -539,9 +542,9 @@ static int fmvj18x_config(struct pcmcia_device *link)
 
     /* print current configuration */
     printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, "
-          "hw_addr %s\n",
+          "hw_addr %pM\n",
           dev->name, card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2", 
-          dev->base_addr, dev->irq, print_mac(mac, dev->dev_addr));
+          dev->base_addr, dev->irq, dev->dev_addr);
 
     return 0;
     
@@ -611,10 +614,10 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
 {
     win_req_t req;
     memreq_t mem;
-    u_char __iomem *base;
-    int i, j;
+    int i;
     struct net_device *dev = link->priv;
     unsigned int ioaddr;
+    local_info_t *lp = netdev_priv(dev);
 
     /* Allocate a small memory window */
     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
@@ -626,25 +629,32 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
        return -1;
     }
 
-    base = ioremap(req.Base, req.Size);
+    lp->base = ioremap(req.Base, req.Size);
+    if (lp->base == NULL) {
+       printk(KERN_NOTICE "fmvj18x_cs: ioremap failed\n");
+       return -1;
+    }
+
     mem.Page = 0;
     mem.CardOffset = 0;
-    pcmcia_map_mem_page(link->win, &mem);
-
+    i = pcmcia_map_mem_page(link->win, &mem);
+    if (i != 0) {
+       iounmap(lp->base);
+       lp->base = NULL;
+       cs_error(link, MapMemPage, i);
+       return -1;
+    }
+    
     ioaddr = dev->base_addr;
-    writeb(0x47, base+0x800);  /* Config Option Register of LAN */
-    writeb(0x0, base+0x802);   /* Config and Status Register */
+    writeb(0x47, lp->base+0x800);      /* Config Option Register of LAN */
+    writeb(0x0,  lp->base+0x802);      /* Config and Status Register */
 
-    writeb(ioaddr & 0xff, base+0x80a);         /* I/O Base(Low) of LAN */
-    writeb((ioaddr >> 8) & 0xff, base+0x80c);  /* I/O Base(High) of LAN */
+    writeb(ioaddr & 0xff, lp->base+0x80a);       /* I/O Base(Low) of LAN */
+    writeb((ioaddr >> 8) & 0xff, lp->base+0x80c); /* I/O Base(High) of LAN */
    
-    writeb(0x45, base+0x820);  /* Config Option Register of Modem */
-    writeb(0x8, base+0x822);   /* Config and Status Register */
+    writeb(0x45, lp->base+0x820);      /* Config Option Register of Modem */
+    writeb(0x8,  lp->base+0x822);      /* Config and Status Register */
 
-    iounmap(base);
-    j = pcmcia_release_window(link->win);
-    if (j != 0)
-       cs_error(link, ReleaseWindow, j);
     return 0;
 
 }
@@ -652,8 +662,25 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
 
 static void fmvj18x_release(struct pcmcia_device *link)
 {
-       DEBUG(0, "fmvj18x_release(0x%p)\n", link);
-       pcmcia_disable_device(link);
+
+    struct net_device *dev = link->priv;
+    local_info_t *lp = netdev_priv(dev);
+    u_char __iomem *tmp;
+    int j;
+
+    DEBUG(0, "fmvj18x_release(0x%p)\n", link);
+
+    if (lp->base != NULL) {
+       tmp = lp->base;
+       lp->base = NULL;    /* set NULL before iounmap */
+       iounmap(tmp);
+       j = pcmcia_release_window(link->win);
+       if (j != 0)
+           cs_error(link, ReleaseWindow, j);
+    }
+
+    pcmcia_disable_device(link);
+
 }
 
 static int fmvj18x_suspend(struct pcmcia_device *link)
@@ -784,6 +811,13 @@ static irqreturn_t fjn_interrupt(int dummy, void *dev_id)
 
     outb(D_TX_INTR, ioaddr + TX_INTR);
     outb(D_RX_INTR, ioaddr + RX_INTR);
+
+    if (lp->base != NULL) {
+       /* Ack interrupt for multifunction card */
+       writeb(0x01, lp->base+0x802);
+       writeb(0x09, lp->base+0x822);
+    }
+
     return IRQ_HANDLED;
 
 } /* fjn_interrupt */
@@ -1036,7 +1070,6 @@ static void fjn_rx(struct net_device *dev)
 #endif
 
            netif_rx(skb);
-           dev->last_rx = jiffies;
            lp->stats.rx_packets++;
            lp->stats.rx_bytes += pkt_len;
        }
index 448cd40aeba5ab37c2c913db34745ac87b2857fd..ec7c588c9ae5cf77eec416fa1c929a0f152a13af 100644 (file)
@@ -659,7 +659,6 @@ static int nmclan_config(struct pcmcia_device *link)
   u_char buf[64];
   int i, last_ret, last_fn;
   unsigned int ioaddr;
-  DECLARE_MAC_BUF(mac);
 
   DEBUG(0, "nmclan_config(0x%p)\n", link);
 
@@ -719,9 +718,9 @@ static int nmclan_config(struct pcmcia_device *link)
   strcpy(lp->node.dev_name, dev->name);
 
   printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port,"
-        " hw_addr %s\n",
+        " hw_addr %pM\n",
         dev->name, dev->base_addr, dev->irq, if_names[dev->if_port],
-        print_mac(mac, dev->dev_addr));
+        dev->dev_addr);
   return 0;
 
 cs_failed:
@@ -1193,7 +1192,6 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
        
        netif_rx(skb); /* Send the packet to the upper (protocol) layers. */
 
-       dev->last_rx = jiffies;
        lp->linux_stats.rx_packets++;
        lp->linux_stats.rx_bytes += pkt_len;
        outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */
index e40d6301aa7aaf1084b9e0cef1bfbf7588d692c3..69625373a8ed0b8066891f4ed5c5adcf1f92e227 100644 (file)
@@ -554,7 +554,6 @@ static int pcnet_config(struct pcmcia_device *link)
     int last_ret, last_fn, start_pg, stop_pg, cm_offset;
     int has_shmem = 0;
     hw_info_t *local_hw_info;
-    DECLARE_MAC_BUF(mac);
 
     DEBUG(0, "pcnet_config(0x%p)\n", link);
 
@@ -675,7 +674,7 @@ static int pcnet_config(struct pcmcia_device *link)
        printk (" mem %#5lx,", dev->mem_start);
     if (info->flags & HAS_MISC_REG)
        printk(" %s xcvr,", if_names[dev->if_port]);
-    printk(" hw_addr %s\n", print_mac(mac, dev->dev_addr));
+    printk(" hw_addr %pM\n", dev->dev_addr);
     return 0;
 
 cs_failed:
index c74d6656d2662bcf5b2d91dcea374c062404b4b1..fccd53ef3c64738c2cb7d5141895f3c5e3251d30 100644 (file)
@@ -949,7 +949,6 @@ static int smc91c92_config(struct pcmcia_device *link)
     int i, j, rev;
     unsigned int ioaddr;
     u_long mir;
-    DECLARE_MAC_BUF(mac);
 
     DEBUG(0, "smc91c92_config(0x%p)\n", link);
 
@@ -1062,9 +1061,9 @@ static int smc91c92_config(struct pcmcia_device *link)
     strcpy(smc->node.dev_name, dev->name);
 
     printk(KERN_INFO "%s: smc91c%s rev %d: io %#3lx, irq %d, "
-          "hw_addr %s\n",
+          "hw_addr %pM\n",
           dev->name, name, (rev & 0x0f), dev->base_addr, dev->irq,
-          print_mac(mac, dev->dev_addr));
+          dev->dev_addr);
 
     if (rev > 0) {
        if (mir & 0x3ff)
index e1fd585e71315ea15ec07a6ed9b2e675db1df4d2..fef7e1861d6a3fbf25922e92ed68b7f4e8924138 100644 (file)
@@ -772,7 +772,6 @@ xirc2ps_config(struct pcmcia_device * link)
     int err, i;
     u_char buf[64];
     cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
-    DECLARE_MAC_BUF(mac);
 
     local->dingo_ccr = NULL;
 
@@ -1051,9 +1050,9 @@ xirc2ps_config(struct pcmcia_device * link)
     strcpy(local->node.dev_name, dev->name);
 
     /* give some infos about the hardware */
-    printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr %s\n",
+    printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr %pM\n",
           dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq,
-          print_mac(mac, dev->dev_addr));
+          dev->dev_addr);
 
     return 0;
 
@@ -1243,7 +1242,6 @@ xirc2ps_interrupt(int irq, void *dev_id)
                }
                skb->protocol = eth_type_trans(skb, dev);
                netif_rx(skb);
-               dev->last_rx = jiffies;
                lp->stats.rx_packets++;
                lp->stats.rx_bytes += pktlen;
                if (!(rsr & PhyPkt))
index ca8c0e03740027980ded217605ea394f5c5c3ca0..f2b192c80e175b5dc06e8c215e8f00a4184a2dbe 100644 (file)
@@ -1246,7 +1246,6 @@ static void pcnet32_rx_entry(struct net_device *dev,
        dev->stats.rx_bytes += skb->len;
        skb->protocol = eth_type_trans(skb, dev);
        netif_receive_skb(skb);
-       dev->last_rx = jiffies;
        dev->stats.rx_packets++;
        return;
 }
@@ -1747,8 +1746,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
                memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
 
        if (pcnet32_debug & NETIF_MSG_PROBE) {
-               DECLARE_MAC_BUF(mac);
-               printk(" %s", print_mac(mac, dev->dev_addr));
+               printk(" %pM", dev->dev_addr);
 
                /* Version 0x2623 and 0x2624 */
                if (((chip_version + 1) & 0xfffe) == 0x2624) {
index d55932acd887fc3b41c32a359c92077e9dfbd7b8..c4c5a2f8ec745c1300c9078b7aad3d3cec2fe84d 100644 (file)
@@ -84,10 +84,13 @@ config MDIO_BITBANG
 
          If in doubt, say N.
 
-config MDIO_OF_GPIO
+config MDIO_GPIO
        tristate "Support for GPIO lib-based bitbanged MDIO buses"
-       depends on MDIO_BITBANG && OF_GPIO
+       depends on MDIO_BITBANG && GENERIC_GPIO
        ---help---
          Supports GPIO lib-based MDIO busses.
 
+         To compile this driver as a module, choose M here: the module
+         will be called mdio-gpio.
+
 endif # PHYLIB
index eee329fa6f5355dfa1ef0817aa6ebc080553f8c5..9ae5d30b5f4ec5ca2a08a88724410d2d49aaa126 100644 (file)
@@ -15,4 +15,4 @@ obj-$(CONFIG_ICPLUS_PHY)      += icplus.o
 obj-$(CONFIG_REALTEK_PHY)      += realtek.o
 obj-$(CONFIG_FIXED_PHY)                += fixed.o
 obj-$(CONFIG_MDIO_BITBANG)     += mdio-bitbang.o
-obj-$(CONFIG_MDIO_OF_GPIO)     += mdio-ofgpio.o
+obj-$(CONFIG_MDIO_GPIO)                += mdio-gpio.o
index 4b4dc98ad165df01b96dcd9753419d383132461d..fd4fc66b6d6e702d2b72052c9804a6d215263a53 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/module.h>
 #include <linux/phy.h>
 
+#define PHY_ID_BCM50610                0x0143bd60
+
 #define MII_BCM54XX_ECR                0x10    /* BCM54xx extended control register */
 #define MII_BCM54XX_ECR_IM     0x1000  /* Interrupt mask */
 #define MII_BCM54XX_ECR_IF     0x0800  /* Interrupt force */
 #define MII_BCM54XX_SHD_VAL(x) ((x & 0x1f) << 10)
 #define MII_BCM54XX_SHD_DATA(x)        ((x & 0x3ff) << 0)
 
+/*
+ * AUXILIARY CONTROL SHADOW ACCESS REGISTERS.  (PHY REG 0x18)
+ */
+#define MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL      0x0000
+#define MII_BCM54XX_AUXCTL_ACTL_TX_6DB         0x0400
+#define MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA      0x0800
+
+#define MII_BCM54XX_AUXCTL_MISC_WREN   0x8000
+#define MII_BCM54XX_AUXCTL_MISC_FORCE_AMDIX    0x0200
+#define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC     0x7000
+#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC        0x0007
+
+#define MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL      0x0000
+
+
 /*
  * Broadcom LED source encodings.  These are used in BCM5461, BCM5481,
  * BCM5482, and possibly some others.
 #define BCM5482_SHD_MODE       0x1f    /* 11111: Mode Control Register */
 #define BCM5482_SHD_MODE_1000BX        0x0001  /* Enable 1000BASE-X registers */
 
+/*
+ * EXPANSION SHADOW ACCESS REGISTERS.  (PHY REG 0x15, 0x16, and 0x17)
+ */
+#define MII_BCM54XX_EXP_AADJ1CH0               0x001f
+#define  MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN 0x0200
+#define  MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF   0x0100
+#define MII_BCM54XX_EXP_AADJ1CH3               0x601f
+#define  MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ     0x0002
+#define MII_BCM54XX_EXP_EXP08                  0x0F08
+#define  MII_BCM54XX_EXP_EXP08_RJCT_2MHZ       0x0001
+#define  MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE  0x0200
+#define MII_BCM54XX_EXP_EXP75                  0x0f75
+#define  MII_BCM54XX_EXP_EXP75_VDACCTRL                0x003c
+#define MII_BCM54XX_EXP_EXP96                  0x0f96
+#define  MII_BCM54XX_EXP_EXP96_MYST            0x0010
+#define MII_BCM54XX_EXP_EXP97                  0x0f97
+#define  MII_BCM54XX_EXP_EXP97_MYST            0x0c0c
+
 /*
  * BCM5482: Secondary SerDes registers
  */
@@ -128,40 +163,93 @@ static int bcm54xx_shadow_write(struct phy_device *phydev, u16 shadow, u16 val)
                         MII_BCM54XX_SHD_DATA(val));
 }
 
-/*
- * Indirect register access functions for the Expansion Registers
- * and Secondary SerDes registers (when sec_serdes=1).
- */
-static int bcm54xx_exp_read(struct phy_device *phydev,
-                           int sec_serdes, u8 regnum)
+/* Indirect register access functions for the Expansion Registers */
+static int bcm54xx_exp_read(struct phy_device *phydev, u8 regnum)
 {
        int val;
 
-       phy_write(phydev, MII_BCM54XX_EXP_SEL,
-                 (sec_serdes ? MII_BCM54XX_EXP_SEL_SSD :
-                               MII_BCM54XX_EXP_SEL_ER) |
-                 regnum);
+       val = phy_write(phydev, MII_BCM54XX_EXP_SEL, regnum);
+       if (val < 0)
+               return val;
+
        val = phy_read(phydev, MII_BCM54XX_EXP_DATA);
-       phy_write(phydev, MII_BCM54XX_EXP_SEL, regnum);
+
+       /* Restore default value.  It's O.K. if this write fails. */
+       phy_write(phydev, MII_BCM54XX_EXP_SEL, 0);
 
        return val;
 }
 
-static int bcm54xx_exp_write(struct phy_device *phydev,
-                            int sec_serdes, u8 regnum, u16 val)
+static int bcm54xx_exp_write(struct phy_device *phydev, u16 regnum, u16 val)
 {
        int ret;
 
-       phy_write(phydev, MII_BCM54XX_EXP_SEL,
-                 (sec_serdes ? MII_BCM54XX_EXP_SEL_SSD :
-                               MII_BCM54XX_EXP_SEL_ER) |
-                 regnum);
+       ret = phy_write(phydev, MII_BCM54XX_EXP_SEL, regnum);
+       if (ret < 0)
+               return ret;
+
        ret = phy_write(phydev, MII_BCM54XX_EXP_DATA, val);
-       phy_write(phydev, MII_BCM54XX_EXP_SEL, regnum);
+
+       /* Restore default value.  It's O.K. if this write fails. */
+       phy_write(phydev, MII_BCM54XX_EXP_SEL, 0);
 
        return ret;
 }
 
+static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
+{
+       return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
+}
+
+static int bcm50610_a0_workaround(struct phy_device *phydev)
+{
+       int err;
+
+       err = bcm54xx_auxctl_write(phydev,
+                                  MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
+                                  MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
+                                  MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
+       if (err < 0)
+               return err;
+
+       err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP08,
+                               MII_BCM54XX_EXP_EXP08_RJCT_2MHZ |
+                               MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE);
+       if (err < 0)
+               goto error;
+
+       err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_AADJ1CH0,
+                               MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN |
+                               MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF);
+       if (err < 0)
+               goto error;
+
+       err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_AADJ1CH3,
+                                       MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ);
+       if (err < 0)
+               goto error;
+
+       err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP75,
+                               MII_BCM54XX_EXP_EXP75_VDACCTRL);
+       if (err < 0)
+               goto error;
+
+       err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP96,
+                               MII_BCM54XX_EXP_EXP96_MYST);
+       if (err < 0)
+               goto error;
+
+       err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP97,
+                               MII_BCM54XX_EXP_EXP97_MYST);
+
+error:
+       bcm54xx_auxctl_write(phydev,
+                            MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
+                            MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
+
+       return err;
+}
+
 static int bcm54xx_config_init(struct phy_device *phydev)
 {
        int reg, err;
@@ -183,6 +271,13 @@ static int bcm54xx_config_init(struct phy_device *phydev)
        err = phy_write(phydev, MII_BCM54XX_IMR, reg);
        if (err < 0)
                return err;
+
+       if (phydev->drv->phy_id == PHY_ID_BCM50610) {
+               err = bcm50610_a0_workaround(phydev);
+               if (err < 0)
+                       return err;
+       }
+
        return 0;
 }
 
@@ -205,18 +300,27 @@ static int bcm5482_config_init(struct phy_device *phydev)
                /*
                 * Enable SGMII slave mode and auto-detection
                 */
-               reg = bcm54xx_exp_read(phydev, 1, BCM5482_SSD_SGMII_SLAVE);
-               bcm54xx_exp_write(phydev, 1, BCM5482_SSD_SGMII_SLAVE,
-                                 reg |
-                                 BCM5482_SSD_SGMII_SLAVE_EN |
-                                 BCM5482_SSD_SGMII_SLAVE_AD);
+               reg = BCM5482_SSD_SGMII_SLAVE | MII_BCM54XX_EXP_SEL_SSD;
+               err = bcm54xx_exp_read(phydev, reg);
+               if (err < 0)
+                       return err;
+               err = bcm54xx_exp_write(phydev, reg, err |
+                                       BCM5482_SSD_SGMII_SLAVE_EN |
+                                       BCM5482_SSD_SGMII_SLAVE_AD);
+               if (err < 0)
+                       return err;
 
                /*
                 * Disable secondary SerDes powerdown
                 */
-               reg = bcm54xx_exp_read(phydev, 1, BCM5482_SSD_1000BX_CTL);
-               bcm54xx_exp_write(phydev, 1, BCM5482_SSD_1000BX_CTL,
-                                 reg & ~BCM5482_SSD_1000BX_CTL_PWRDOWN);
+               reg = BCM5482_SSD_1000BX_CTL | MII_BCM54XX_EXP_SEL_SSD;
+               err = bcm54xx_exp_read(phydev, reg);
+               if (err < 0)
+                       return err;
+               err = bcm54xx_exp_write(phydev, reg,
+                                       err & ~BCM5482_SSD_1000BX_CTL_PWRDOWN);
+               if (err < 0)
+                       return err;
 
                /*
                 * Select 1000BASE-X register set (primary SerDes)
@@ -335,7 +439,8 @@ static struct phy_driver bcm5411_driver = {
        .phy_id         = 0x00206070,
        .phy_id_mask    = 0xfffffff0,
        .name           = "Broadcom BCM5411",
-       .features       = PHY_GBIT_FEATURES,
+       .features       = PHY_GBIT_FEATURES |
+                         SUPPORTED_Pause | SUPPORTED_Asym_Pause,
        .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
        .config_init    = bcm54xx_config_init,
        .config_aneg    = genphy_config_aneg,
@@ -349,7 +454,8 @@ static struct phy_driver bcm5421_driver = {
        .phy_id         = 0x002060e0,
        .phy_id_mask    = 0xfffffff0,
        .name           = "Broadcom BCM5421",
-       .features       = PHY_GBIT_FEATURES,
+       .features       = PHY_GBIT_FEATURES |
+                         SUPPORTED_Pause | SUPPORTED_Asym_Pause,
        .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
        .config_init    = bcm54xx_config_init,
        .config_aneg    = genphy_config_aneg,
@@ -363,7 +469,8 @@ static struct phy_driver bcm5461_driver = {
        .phy_id         = 0x002060c0,
        .phy_id_mask    = 0xfffffff0,
        .name           = "Broadcom BCM5461",
-       .features       = PHY_GBIT_FEATURES,
+       .features       = PHY_GBIT_FEATURES |
+                         SUPPORTED_Pause | SUPPORTED_Asym_Pause,
        .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
        .config_init    = bcm54xx_config_init,
        .config_aneg    = genphy_config_aneg,
@@ -377,7 +484,8 @@ static struct phy_driver bcm5464_driver = {
        .phy_id         = 0x002060b0,
        .phy_id_mask    = 0xfffffff0,
        .name           = "Broadcom BCM5464",
-       .features       = PHY_GBIT_FEATURES,
+       .features       = PHY_GBIT_FEATURES |
+                         SUPPORTED_Pause | SUPPORTED_Asym_Pause,
        .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
        .config_init    = bcm54xx_config_init,
        .config_aneg    = genphy_config_aneg,
@@ -391,7 +499,8 @@ static struct phy_driver bcm5481_driver = {
        .phy_id         = 0x0143bca0,
        .phy_id_mask    = 0xfffffff0,
        .name           = "Broadcom BCM5481",
-       .features       = PHY_GBIT_FEATURES,
+       .features       = PHY_GBIT_FEATURES |
+                         SUPPORTED_Pause | SUPPORTED_Asym_Pause,
        .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
        .config_init    = bcm54xx_config_init,
        .config_aneg    = bcm5481_config_aneg,
@@ -405,7 +514,8 @@ static struct phy_driver bcm5482_driver = {
        .phy_id         = 0x0143bcb0,
        .phy_id_mask    = 0xfffffff0,
        .name           = "Broadcom BCM5482",
-       .features       = PHY_GBIT_FEATURES,
+       .features       = PHY_GBIT_FEATURES |
+                         SUPPORTED_Pause | SUPPORTED_Asym_Pause,
        .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
        .config_init    = bcm5482_config_init,
        .config_aneg    = genphy_config_aneg,
@@ -415,6 +525,21 @@ static struct phy_driver bcm5482_driver = {
        .driver         = { .owner = THIS_MODULE },
 };
 
+static struct phy_driver bcm50610_driver = {
+       .phy_id         = PHY_ID_BCM50610,
+       .phy_id_mask    = 0xfffffff0,
+       .name           = "Broadcom BCM50610",
+       .features       = PHY_GBIT_FEATURES |
+                         SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+       .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
+       .config_init    = bcm54xx_config_init,
+       .config_aneg    = genphy_config_aneg,
+       .read_status    = genphy_read_status,
+       .ack_interrupt  = bcm54xx_ack_interrupt,
+       .config_intr    = bcm54xx_config_intr,
+       .driver         = { .owner = THIS_MODULE },
+};
+
 static int __init broadcom_init(void)
 {
        int ret;
@@ -437,8 +562,13 @@ static int __init broadcom_init(void)
        ret = phy_driver_register(&bcm5482_driver);
        if (ret)
                goto out_5482;
+       ret = phy_driver_register(&bcm50610_driver);
+       if (ret)
+               goto out_50610;
        return ret;
 
+out_50610:
+       phy_driver_unregister(&bcm5482_driver);
 out_5482:
        phy_driver_unregister(&bcm5481_driver);
 out_5481:
@@ -455,6 +585,7 @@ out_5411:
 
 static void __exit broadcom_exit(void)
 {
+       phy_driver_unregister(&bcm50610_driver);
        phy_driver_unregister(&bcm5482_driver);
        phy_driver_unregister(&bcm5481_driver);
        phy_driver_unregister(&bcm5464_driver);
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
new file mode 100644 (file)
index 0000000..a439ebe
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * GPIO based MDIO bitbang driver.
+ * Supports OpenFirmware.
+ *
+ * Copyright (c) 2008 CSE Semaphore Belgium.
+ *  by Laurent Pinchart <laurentp@cse-semaphore.com>
+ *
+ * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on earlier work by
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ *  by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/mdio-gpio.h>
+
+#ifdef CONFIG_OF_GPIO
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+#endif
+
+struct mdio_gpio_info {
+       struct mdiobb_ctrl ctrl;
+       int mdc, mdio;
+};
+
+static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir)
+{
+       struct mdio_gpio_info *bitbang =
+               container_of(ctrl, struct mdio_gpio_info, ctrl);
+
+       if (dir)
+               gpio_direction_output(bitbang->mdio, 1);
+       else
+               gpio_direction_input(bitbang->mdio);
+}
+
+static int mdio_get(struct mdiobb_ctrl *ctrl)
+{
+       struct mdio_gpio_info *bitbang =
+               container_of(ctrl, struct mdio_gpio_info, ctrl);
+
+       return gpio_get_value(bitbang->mdio);
+}
+
+static void mdio_set(struct mdiobb_ctrl *ctrl, int what)
+{
+       struct mdio_gpio_info *bitbang =
+               container_of(ctrl, struct mdio_gpio_info, ctrl);
+
+       gpio_set_value(bitbang->mdio, what);
+}
+
+static void mdc_set(struct mdiobb_ctrl *ctrl, int what)
+{
+       struct mdio_gpio_info *bitbang =
+               container_of(ctrl, struct mdio_gpio_info, ctrl);
+
+       gpio_set_value(bitbang->mdc, what);
+}
+
+static struct mdiobb_ops mdio_gpio_ops = {
+       .owner = THIS_MODULE,
+       .set_mdc = mdc_set,
+       .set_mdio_dir = mdio_dir,
+       .set_mdio_data = mdio_set,
+       .get_mdio_data = mdio_get,
+};
+
+static int __devinit mdio_gpio_bus_init(struct device *dev,
+                                       struct mdio_gpio_platform_data *pdata,
+                                       int bus_id)
+{
+       struct mii_bus *new_bus;
+       struct mdio_gpio_info *bitbang;
+       int ret = -ENOMEM;
+       int i;
+
+       bitbang = kzalloc(sizeof(*bitbang), GFP_KERNEL);
+       if (!bitbang)
+               goto out;
+
+       bitbang->ctrl.ops = &mdio_gpio_ops;
+       bitbang->mdc = pdata->mdc;
+       bitbang->mdio = pdata->mdio;
+
+       new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
+       if (!new_bus)
+               goto out_free_bitbang;
+
+       new_bus->name = "GPIO Bitbanged MDIO",
+
+       ret = -ENODEV;
+
+       new_bus->phy_mask = pdata->phy_mask;
+       new_bus->irq = pdata->irqs;
+       new_bus->parent = dev;
+
+       if (new_bus->phy_mask == ~0)
+               goto out_free_bus;
+
+       for (i = 0; i < PHY_MAX_ADDR; i++)
+               if (!new_bus->irq[i])
+                       new_bus->irq[i] = PHY_POLL;
+
+       snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", bus_id);
+
+       if (gpio_request(bitbang->mdc, "mdc"))
+               goto out_free_bus;
+
+       if (gpio_request(bitbang->mdio, "mdio"))
+               goto out_free_mdc;
+
+       dev_set_drvdata(dev, new_bus);
+
+       ret = mdiobus_register(new_bus);
+       if (ret)
+               goto out_free_all;
+
+       return 0;
+
+out_free_all:
+       dev_set_drvdata(dev, NULL);
+       gpio_free(bitbang->mdio);
+out_free_mdc:
+       gpio_free(bitbang->mdc);
+out_free_bus:
+       free_mdio_bitbang(new_bus);
+out_free_bitbang:
+       kfree(bitbang);
+out:
+       return ret;
+}
+
+static void __devexit mdio_gpio_bus_destroy(struct device *dev)
+{
+       struct mii_bus *bus = dev_get_drvdata(dev);
+       struct mdio_gpio_info *bitbang = bus->priv;
+
+       mdiobus_unregister(bus);
+       free_mdio_bitbang(bus);
+       dev_set_drvdata(dev, NULL);
+       gpio_free(bitbang->mdc);
+       gpio_free(bitbang->mdio);
+       kfree(bitbang);
+}
+
+static int __devinit mdio_gpio_probe(struct platform_device *pdev)
+{
+       struct mdio_gpio_platform_data *pdata = pdev->dev.platform_data;
+
+       if (!pdata)
+               return -ENODEV;
+
+       return mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id);
+}
+
+static int __devexit mdio_gpio_remove(struct platform_device *pdev)
+{
+       mdio_gpio_bus_destroy(&pdev->dev);
+
+       return 0;
+}
+
+#ifdef CONFIG_OF_GPIO
+static void __devinit add_phy(struct mdio_gpio_platform_data *pdata,
+                             struct device_node *np)
+{
+       const u32 *data;
+       int len, id, irq;
+
+       data = of_get_property(np, "reg", &len);
+       if (!data || len != 4)
+               return;
+
+       id = *data;
+       pdata->phy_mask &= ~(1 << id);
+
+       irq = of_irq_to_resource(np, 0, NULL);
+       if (irq)
+               pdata->irqs[id] = irq;
+}
+
+static int __devinit mdio_ofgpio_probe(struct of_device *ofdev,
+                                        const struct of_device_id *match)
+{
+       struct device_node *np = NULL;
+       struct mdio_gpio_platform_data *pdata;
+
+       pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
+
+       pdata->mdc = of_get_gpio(ofdev->node, 0);
+       pdata->mdio = of_get_gpio(ofdev->node, 1);
+
+       if (pdata->mdc < 0 || pdata->mdio < 0)
+               goto out_free;
+
+       while ((np = of_get_next_child(ofdev->node, np)))
+               if (!strcmp(np->type, "ethernet-phy"))
+                       add_phy(pdata, np);
+
+       return mdio_gpio_bus_init(&ofdev->dev, pdata, pdata->mdc);
+
+out_free:
+       kfree(pdata);
+       return -ENODEV;
+}
+
+static int __devexit mdio_ofgpio_remove(struct of_device *ofdev)
+{
+       mdio_gpio_bus_destroy(&ofdev->dev);
+       kfree(ofdev->dev.platform_data);
+
+       return 0;
+}
+
+static struct of_device_id mdio_ofgpio_match[] = {
+       {
+               .compatible = "virtual,mdio-gpio",
+       },
+       {},
+};
+
+static struct of_platform_driver mdio_ofgpio_driver = {
+       .name = "mdio-gpio",
+       .match_table = mdio_ofgpio_match,
+       .probe = mdio_ofgpio_probe,
+       .remove = __devexit_p(mdio_ofgpio_remove),
+};
+
+static inline int __init mdio_ofgpio_init(void)
+{
+       return of_register_platform_driver(&mdio_ofgpio_driver);
+}
+
+static inline void __exit mdio_ofgpio_exit(void)
+{
+       of_unregister_platform_driver(&mdio_ofgpio_driver);
+}
+#else
+static inline int __init mdio_ofgpio_init(void) { return 0; }
+static inline void __exit mdio_ofgpio_exit(void) { }
+#endif /* CONFIG_OF_GPIO */
+
+static struct platform_driver mdio_gpio_driver = {
+       .probe = mdio_gpio_probe,
+       .remove = __devexit_p(mdio_gpio_remove),
+       .driver         = {
+               .name   = "mdio-gpio",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init mdio_gpio_init(void)
+{
+       int ret;
+
+       ret = mdio_ofgpio_init();
+       if (ret)
+               return ret;
+
+       ret = platform_driver_register(&mdio_gpio_driver);
+       if (ret)
+               mdio_ofgpio_exit();
+
+       return ret;
+}
+module_init(mdio_gpio_init);
+
+static void __exit mdio_gpio_exit(void)
+{
+       platform_driver_unregister(&mdio_gpio_driver);
+       mdio_ofgpio_exit();
+}
+module_exit(mdio_gpio_exit);
+
+MODULE_ALIAS("platform:mdio-gpio");
+MODULE_AUTHOR("Laurent Pinchart, Paulius Zaleckas");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic driver for MDIO bus emulation using GPIO");
diff --git a/drivers/net/phy/mdio-ofgpio.c b/drivers/net/phy/mdio-ofgpio.c
deleted file mode 100644 (file)
index 2ff9775..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * OpenFirmware GPIO based MDIO bitbang driver.
- *
- * Copyright (c) 2008 CSE Semaphore Belgium.
- *  by Laurent Pinchart <laurentp@cse-semaphore.com>
- *
- * Based on earlier work by
- *
- * Copyright (c) 2003 Intracom S.A.
- *  by Pantelis Antoniou <panto@intracom.gr>
- *
- * 2005 (c) MontaVista Software, Inc.
- * Vitaly Bordug <vbordug@ru.mvista.com>
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/mdio-bitbang.h>
-#include <linux/of_gpio.h>
-#include <linux/of_platform.h>
-
-struct mdio_gpio_info {
-       struct mdiobb_ctrl ctrl;
-       int mdc, mdio;
-};
-
-static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir)
-{
-       struct mdio_gpio_info *bitbang =
-               container_of(ctrl, struct mdio_gpio_info, ctrl);
-
-       if (dir)
-               gpio_direction_output(bitbang->mdio, 1);
-       else
-               gpio_direction_input(bitbang->mdio);
-}
-
-static int mdio_read(struct mdiobb_ctrl *ctrl)
-{
-       struct mdio_gpio_info *bitbang =
-               container_of(ctrl, struct mdio_gpio_info, ctrl);
-
-       return gpio_get_value(bitbang->mdio);
-}
-
-static void mdio(struct mdiobb_ctrl *ctrl, int what)
-{
-       struct mdio_gpio_info *bitbang =
-               container_of(ctrl, struct mdio_gpio_info, ctrl);
-
-       gpio_set_value(bitbang->mdio, what);
-}
-
-static void mdc(struct mdiobb_ctrl *ctrl, int what)
-{
-       struct mdio_gpio_info *bitbang =
-               container_of(ctrl, struct mdio_gpio_info, ctrl);
-
-       gpio_set_value(bitbang->mdc, what);
-}
-
-static struct mdiobb_ops mdio_gpio_ops = {
-       .owner = THIS_MODULE,
-       .set_mdc = mdc,
-       .set_mdio_dir = mdio_dir,
-       .set_mdio_data = mdio,
-       .get_mdio_data = mdio_read,
-};
-
-static int __devinit mdio_ofgpio_bitbang_init(struct mii_bus *bus,
-                                         struct device_node *np)
-{
-       struct mdio_gpio_info *bitbang = bus->priv;
-
-       bitbang->mdc = of_get_gpio(np, 0);
-       bitbang->mdio = of_get_gpio(np, 1);
-
-       if (bitbang->mdc < 0 || bitbang->mdio < 0)
-               return -ENODEV;
-
-       snprintf(bus->id, MII_BUS_ID_SIZE, "%x", bitbang->mdc);
-       return 0;
-}
-
-static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
-{
-       const u32 *data;
-       int len, id, irq;
-
-       data = of_get_property(np, "reg", &len);
-       if (!data || len != 4)
-               return;
-
-       id = *data;
-       bus->phy_mask &= ~(1 << id);
-
-       irq = of_irq_to_resource(np, 0, NULL);
-       if (irq != NO_IRQ)
-               bus->irq[id] = irq;
-}
-
-static int __devinit mdio_ofgpio_probe(struct of_device *ofdev,
-                                        const struct of_device_id *match)
-{
-       struct device_node *np = NULL;
-       struct mii_bus *new_bus;
-       struct mdio_gpio_info *bitbang;
-       int ret = -ENOMEM;
-       int i;
-
-       bitbang = kzalloc(sizeof(struct mdio_gpio_info), GFP_KERNEL);
-       if (!bitbang)
-               goto out;
-
-       bitbang->ctrl.ops = &mdio_gpio_ops;
-
-       new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
-       if (!new_bus)
-               goto out_free_bitbang;
-
-       new_bus->name = "GPIO Bitbanged MII",
-
-       ret = mdio_ofgpio_bitbang_init(new_bus, ofdev->node);
-       if (ret)
-               goto out_free_bus;
-
-       new_bus->phy_mask = ~0;
-       new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
-       if (!new_bus->irq)
-               goto out_free_bus;
-
-       for (i = 0; i < PHY_MAX_ADDR; i++)
-               new_bus->irq[i] = -1;
-
-       while ((np = of_get_next_child(ofdev->node, np)))
-               if (!strcmp(np->type, "ethernet-phy"))
-                       add_phy(new_bus, np);
-
-       new_bus->parent = &ofdev->dev;
-       dev_set_drvdata(&ofdev->dev, new_bus);
-
-       ret = mdiobus_register(new_bus);
-       if (ret)
-               goto out_free_irqs;
-
-       return 0;
-
-out_free_irqs:
-       dev_set_drvdata(&ofdev->dev, NULL);
-       kfree(new_bus->irq);
-out_free_bus:
-       free_mdio_bitbang(new_bus);
-out_free_bitbang:
-       kfree(bitbang);
-out:
-       return ret;
-}
-
-static int mdio_ofgpio_remove(struct of_device *ofdev)
-{
-       struct mii_bus *bus = dev_get_drvdata(&ofdev->dev);
-       struct mdio_gpio_info *bitbang = bus->priv;
-
-       mdiobus_unregister(bus);
-       kfree(bus->irq);
-       free_mdio_bitbang(bus);
-       dev_set_drvdata(&ofdev->dev, NULL);
-       kfree(bitbang);
-
-       return 0;
-}
-
-static struct of_device_id mdio_ofgpio_match[] = {
-       {
-               .compatible = "virtual,mdio-gpio",
-       },
-       {},
-};
-
-static struct of_platform_driver mdio_ofgpio_driver = {
-       .name = "mdio-gpio",
-       .match_table = mdio_ofgpio_match,
-       .probe = mdio_ofgpio_probe,
-       .remove = mdio_ofgpio_remove,
-};
-
-static int mdio_ofgpio_init(void)
-{
-       return of_register_platform_driver(&mdio_ofgpio_driver);
-}
-
-static void mdio_ofgpio_exit(void)
-{
-       of_unregister_platform_driver(&mdio_ofgpio_driver);
-}
-
-module_init(mdio_ofgpio_init);
-module_exit(mdio_ofgpio_exit);
index 536bda1f428b6c09360be41448f7b0b7d4c16679..868812ff6de858f6ccd9420d44840cd6abe4e221 100644 (file)
@@ -97,7 +97,7 @@ int mdiobus_register(struct mii_bus *bus)
        bus->dev.parent = bus->parent;
        bus->dev.class = &mdio_bus_class;
        bus->dev.groups = NULL;
-       memcpy(bus->dev.bus_id, bus->id, MII_BUS_ID_SIZE);
+       dev_set_name(&bus->dev, bus->id);
 
        err = device_register(&bus->dev);
        if (err) {
@@ -191,7 +191,7 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
 
        phydev->dev.parent = bus->parent;
        phydev->dev.bus = &mdio_bus_type;
-       snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, addr);
+       dev_set_name(&phydev->dev, PHY_ID_FMT, bus->id, addr);
 
        phydev->bus = bus;
 
index df4e6257d4a77e3e9bba739db57dec8543315d79..e4ede6080c9dcd327acfa37530263c6382d050db 100644 (file)
@@ -45,7 +45,7 @@
  */
 void phy_print_status(struct phy_device *phydev)
 {
-       pr_info("PHY: %s - Link is %s", phydev->dev.bus_id,
+       pr_info("PHY: %s - Link is %s", dev_name(&phydev->dev),
                        phydev->link ? "Up" : "Down");
        if (phydev->link)
                printk(" - %d/%s", phydev->speed,
index 8fb1faca883aef9126b547f09ecf830e4feb1562..bce918bd3cdd06f0e7f15465009a51a0ba82509a 100644 (file)
@@ -74,7 +74,7 @@ int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask,
        if (!fixup)
                return -ENOMEM;
 
-       strncpy(fixup->bus_id, bus_id, BUS_ID_SIZE);
+       strlcpy(fixup->bus_id, bus_id, sizeof(fixup->bus_id));
        fixup->phy_uid = phy_uid;
        fixup->phy_uid_mask = phy_uid_mask;
        fixup->run = run;
@@ -109,7 +109,7 @@ EXPORT_SYMBOL(phy_register_fixup_for_id);
  */
 static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup)
 {
-       if (strcmp(fixup->bus_id, phydev->dev.bus_id) != 0)
+       if (strcmp(fixup->bus_id, dev_name(&phydev->dev)) != 0)
                if (strcmp(fixup->bus_id, PHY_ANY_ID) != 0)
                        return 0;
 
index 73baa7a3bb0ee3c9d43e69bb01d45908ef3340f0..c05d38d4635042d539f50705becfa9149109a137 100644 (file)
@@ -126,6 +126,27 @@ static struct phy_driver lan8700_driver = {
        .driver         = { .owner = THIS_MODULE, }
 };
 
+static struct phy_driver lan911x_int_driver = {
+       .phy_id         = 0x0007c0d0, /* OUI=0x00800f, Model#=0x0d */
+       .phy_id_mask    = 0xfffffff0,
+       .name           = "SMSC LAN911x Internal PHY",
+
+       .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause
+                               | SUPPORTED_Asym_Pause),
+       .flags          = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
+
+       /* basic functions */
+       .config_aneg    = genphy_config_aneg,
+       .read_status    = genphy_read_status,
+       .config_init    = smsc_phy_config_init,
+
+       /* IRQ related */
+       .ack_interrupt  = smsc_phy_ack_interrupt,
+       .config_intr    = smsc_phy_config_intr,
+
+       .driver         = { .owner = THIS_MODULE, }
+};
+
 static int __init smsc_init(void)
 {
        int ret;
@@ -142,8 +163,14 @@ static int __init smsc_init(void)
        if (ret)
                goto err3;
 
+       ret = phy_driver_register (&lan911x_int_driver);
+       if (ret)
+               goto err4;
+
        return 0;
 
+err4:
+       phy_driver_unregister (&lan8700_driver);
 err3:
        phy_driver_unregister (&lan8187_driver);
 err2:
@@ -154,6 +181,7 @@ err1:
 
 static void __exit smsc_exit(void)
 {
+       phy_driver_unregister (&lan911x_int_driver);
        phy_driver_unregister (&lan8700_driver);
        phy_driver_unregister (&lan8187_driver);
        phy_driver_unregister (&lan83c185_driver);
index 1e965427b0e987faae6ae26bfe3d07e1aad8bfa7..d544d4a086dccaf4f7e51defd0c8d259d77f8732 100644 (file)
@@ -229,7 +229,7 @@ static inline void enable_parport_interrupts (struct net_device *dev)
        if (dev->irq != -1)
        {
                struct parport *port =
-                  ((struct net_local *)dev->priv)->pardev->port;
+                  ((struct net_local *)netdev_priv(dev))->pardev->port;
                port->ops->enable_irq (port);
        }
 }
@@ -239,7 +239,7 @@ static inline void disable_parport_interrupts (struct net_device *dev)
        if (dev->irq != -1)
        {
                struct parport *port =
-                  ((struct net_local *)dev->priv)->pardev->port;
+                  ((struct net_local *)netdev_priv(dev))->pardev->port;
                port->ops->disable_irq (port);
        }
 }
@@ -247,7 +247,7 @@ static inline void disable_parport_interrupts (struct net_device *dev)
 static inline void write_data (struct net_device *dev, unsigned char data)
 {
        struct parport *port =
-          ((struct net_local *)dev->priv)->pardev->port;
+          ((struct net_local *)netdev_priv(dev))->pardev->port;
 
        port->ops->write_data (port, data);
 }
@@ -255,7 +255,7 @@ static inline void write_data (struct net_device *dev, unsigned char data)
 static inline unsigned char read_status (struct net_device *dev)
 {
        struct parport *port =
-          ((struct net_local *)dev->priv)->pardev->port;
+          ((struct net_local *)netdev_priv(dev))->pardev->port;
 
        return port->ops->read_status (port);
 }
@@ -664,7 +664,6 @@ plip_receive_packet(struct net_device *dev, struct net_local *nl,
                /* Inform the upper layer for the arrival of a packet. */
                rcv->skb->protocol=plip_type_trans(rcv->skb, dev);
                netif_rx_ni(rcv->skb);
-               dev->last_rx = jiffies;
                dev->stats.rx_bytes += rcv->length.h;
                dev->stats.rx_packets++;
                rcv->skb = NULL;
index 7e857e938adb582ae432b26d35114e8099d51eb2..274d495a1c507e992cc277a5df42e09b26f9e4ec 100644 (file)
@@ -1684,7 +1684,6 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
                        skb->protocol = htons(npindex_to_ethertype[npi]);
                        skb_reset_mac_header(skb);
                        netif_rx(skb);
-                       ppp->dev->last_rx = jiffies;
                }
        }
        return;
index b646e92134dc79a6bbfe6e55f7c80fd0ea19d3f1..c22b30533a14cb89eeeda69a83317f80e8c383b3 100644 (file)
@@ -958,7 +958,6 @@ static int pppoe_seq_show(struct seq_file *seq, void *v)
 {
        struct pppox_sock *po;
        char *dev_name;
-       DECLARE_MAC_BUF(mac);
 
        if (v == SEQ_START_TOKEN) {
                seq_puts(seq, "Id       Address              Device\n");
@@ -968,8 +967,8 @@ static int pppoe_seq_show(struct seq_file *seq, void *v)
        po = v;
        dev_name = po->pppoe_pa.dev;
 
-       seq_printf(seq, "%08X %s %8s\n",
-                  po->pppoe_pa.sid, print_mac(mac, po->pppoe_pa.remote), dev_name);
+       seq_printf(seq, "%08X %pM %8s\n",
+                  po->pppoe_pa.sid, po->pppoe_pa.remote, dev_name);
 out:
        return 0;
 }
index 2eb54fd7bed532153f4aafef049a97f5459caa02..4b564eda5bd932ef67f8b850c4b947761da31628 100644 (file)
@@ -1443,7 +1443,6 @@ int gelic_net_setup_netdev(struct net_device *netdev, struct gelic_card *card)
 {
        int status;
        u64 v1, v2;
-       DECLARE_MAC_BUF(mac);
 
        netdev->features = NETIF_F_IP_CSUM;
 
@@ -1474,9 +1473,8 @@ int gelic_net_setup_netdev(struct net_device *netdev, struct gelic_card *card)
                        __func__, netdev->name, status);
                return status;
        }
-       dev_info(ctodev(card), "%s: MAC addr %s\n",
-                netdev->name,
-                print_mac(mac, netdev->dev_addr));
+       dev_info(ctodev(card), "%s: MAC addr %pM\n",
+                netdev->name, netdev->dev_addr);
 
        return 0;
 }
index a834b52a6a2c4019a36bb752b812566ae89c57c9..ec2314246682af0946bbe97475b3947670401383 100644 (file)
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <linux/if_arp.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <net/iw_handler.h>
-#include <net/ieee80211.h>
 
 #include <linux/dma-mapping.h>
 #include <net/checksum.h>
@@ -449,9 +450,9 @@ static size_t gelic_wl_synthesize_ie(u8 *buf,
 
        /* element id */
        if (rsn)
-               *buf++ = MFIE_TYPE_RSN;
+               *buf++ = WLAN_EID_RSN;
        else
-               *buf++ = MFIE_TYPE_GENERIC;
+               *buf++ = WLAN_EID_GENERIC;
 
        /* length filed; set later */
        buf++;
@@ -539,7 +540,7 @@ static void gelic_wl_parse_ie(u8 *data, size_t len,
                        break;
 
                switch (item_id) {
-               case MFIE_TYPE_GENERIC:
+               case WLAN_EID_GENERIC:
                        if ((OUI_LEN + 1 <= item_len) &&
                            !memcmp(pos, wpa_oui, OUI_LEN) &&
                            pos[OUI_LEN] == 0x01) {
@@ -547,7 +548,7 @@ static void gelic_wl_parse_ie(u8 *data, size_t len,
                                ie_info->wpa.len = item_len + 2;
                        }
                        break;
-               case MFIE_TYPE_RSN:
+               case WLAN_EID_RSN:
                        ie_info->rsn.data = pos - 2;
                        /* length includes the header */
                        ie_info->rsn.len = item_len + 2;
@@ -581,7 +582,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
        char *tmp;
        u8 rate;
        unsigned int i, j, len;
-       u8 buf[MAX_WPA_IE_LEN];
+       u8 buf[64]; /* arbitrary size large enough */
 
        pr_debug("%s: <-\n", __func__);
 
@@ -763,7 +764,6 @@ static void scan_list_dump(struct gelic_wl_info *wl)
 {
        struct gelic_wl_scan_info *scan_info;
        int i;
-       DECLARE_MAC_BUF(mac);
 
        i = 0;
        list_for_each_entry(scan_info, &wl->network_list, list) {
@@ -775,8 +775,7 @@ static void scan_list_dump(struct gelic_wl_info *wl)
                         scan_info->rate_len, scan_info->rate_ext_len,
                         scan_info->essid_len);
                /* -- */
-               pr_debug("bssid=%s\n",
-                        print_mac(mac, &scan_info->hwinfo->bssid[2]));
+               pr_debug("bssid=%pM\n", &scan_info->hwinfo->bssid[2]);
                pr_debug("essid=%s\n", scan_info->hwinfo->essid);
        }
 }
@@ -1167,11 +1166,7 @@ static int gelic_wl_set_ap(struct net_device *netdev,
                       ETH_ALEN);
                set_bit(GELIC_WL_STAT_BSSID_SET, &wl->stat);
                set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat);
-               pr_debug("%s: bss=%02x:%02x:%02x:%02x:%02x:%02x\n",
-                        __func__,
-                        wl->bssid[0], wl->bssid[1],
-                        wl->bssid[2], wl->bssid[3],
-                        wl->bssid[4], wl->bssid[5]);
+               pr_debug("%s: bss=%pM\n", __func__, wl->bssid);
        } else {
                pr_debug("%s: clear bssid\n", __func__);
                clear_bit(GELIC_WL_STAT_BSSID_SET, &wl->stat);
@@ -1632,7 +1627,6 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
        unsigned long this_time = jiffies;
        unsigned int data_len, i, found, r;
        void *buf;
-       DECLARE_MAC_BUF(mac);
 
        pr_debug("%s:start\n", __func__);
        mutex_lock(&wl->scan_lock);
@@ -1684,9 +1678,9 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
             scan_info_size < data_len;
             i++, scan_info_size += be16_to_cpu(scan_info->size),
             scan_info = (void *)scan_info + be16_to_cpu(scan_info->size)) {
-               pr_debug("%s:size=%d bssid=%s scan_info=%p\n", __func__,
+               pr_debug("%s:size=%d bssid=%pM scan_info=%p\n", __func__,
                         be16_to_cpu(scan_info->size),
-                        print_mac(mac, &scan_info->bssid[2]), scan_info);
+                        &scan_info->bssid[2], scan_info);
 
                /*
                 * The wireless firmware may return invalid channel 0 and/or
@@ -1741,14 +1735,14 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
                target->essid_len = strnlen(scan_info->essid,
                                            sizeof(scan_info->essid));
                target->rate_len = 0;
-               for (r = 0; r < MAX_RATES_LENGTH; r++)
+               for (r = 0; r < 12; r++)
                        if (scan_info->rate[r])
                                target->rate_len++;
                if (8 < target->rate_len)
                        pr_info("%s: AP returns %d rates\n", __func__,
                                target->rate_len);
                target->rate_ext_len = 0;
-               for (r = 0; r < MAX_RATES_EX_LENGTH; r++)
+               for (r = 0; r < 16; r++)
                        if (scan_info->ext_rate[r])
                                target->rate_ext_len++;
                list_move_tail(&target->list, &wl->network_list);
@@ -1787,7 +1781,6 @@ struct gelic_wl_scan_info *gelic_wl_find_best_bss(struct gelic_wl_info *wl)
        struct gelic_wl_scan_info *best_bss;
        int weight, best_weight;
        u16 security;
-       DECLARE_MAC_BUF(mac);
 
        pr_debug("%s: <-\n", __func__);
 
@@ -1857,8 +1850,8 @@ struct gelic_wl_scan_info *gelic_wl_find_best_bss(struct gelic_wl_info *wl)
 #ifdef DEBUG
        pr_debug("%s: -> bss=%p\n", __func__, best_bss);
        if (best_bss) {
-               pr_debug("%s:addr=%s\n", __func__,
-                        print_mac(mac, &best_bss->hwinfo->bssid[2]));
+               pr_debug("%s:addr=%pM\n", __func__,
+                        &best_bss->hwinfo->bssid[2]);
        }
 #endif
        return best_bss;
index 5339e0078d180a885f53a622dddac4c4743c50ee..5b631c6c97759ec36f4d2296549f10b979a89158 100644 (file)
@@ -164,8 +164,8 @@ struct gelic_eurus_scan_info {
        __be16 security;
        u8  bssid[8]; /* last ETH_ALEN are valid. bssid[0],[1] are unused */
        u8  essid[32]; /* IW_ESSID_MAX_SIZE */
-       u8  rate[16]; /* first MAX_RATES_LENGTH(12) are valid */
-       u8  ext_rate[16]; /* first MAX_RATES_EX_LENGTH(16) are valid */
+       u8  rate[16]; /* first 12 are valid */
+       u8  ext_rate[16]; /* first 16 are valid */
        __be32 reserved1;
        __be32 reserved2;
        __be32 reserved3;
index 508452c0215144343a2aacbe37f44d20caedfbf3..f188736028d78c7107cba111c9935f1f16cca788 100644 (file)
@@ -2127,7 +2127,6 @@ static void ql_process_mac_rx_intr(struct ql3_adapter *qdev,
        skb->protocol = eth_type_trans(skb, qdev->ndev);
 
        netif_receive_skb(skb);
-       qdev->ndev->last_rx = jiffies;
        lrg_buf_cb2->skb = NULL;
 
        if (qdev->device_id == QL3022_DEVICE_ID)
@@ -2201,7 +2200,6 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev,
        netif_receive_skb(skb2);
        ndev->stats.rx_packets++;
        ndev->stats.rx_bytes += length;
-       ndev->last_rx = jiffies;
        lrg_buf_cb2->skb = NULL;
 
        if (qdev->device_id == QL3022_DEVICE_ID)
@@ -3520,7 +3518,6 @@ static void ql_display_dev_info(struct net_device *ndev)
 {
        struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev);
        struct pci_dev *pdev = qdev->pdev;
-       DECLARE_MAC_BUF(mac);
 
        printk(KERN_INFO PFX
               "\n%s Adapter %d RevisionID %d found %s on PCI slot %d.\n",
@@ -3546,8 +3543,8 @@ static void ql_display_dev_info(struct net_device *ndev)
 
        if (netif_msg_probe(qdev))
                printk(KERN_INFO PFX
-                      "%s: MAC address %s\n",
-                      ndev->name, print_mac(mac, ndev->dev_addr));
+                      "%s: MAC address %pM\n",
+                      ndev->name, ndev->dev_addr);
 }
 
 static int ql_adapter_down(struct ql3_adapter *qdev, int do_reset)
@@ -3969,9 +3966,7 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
        if (qdev->device_id == QL3032_DEVICE_ID)
                ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
 
-       qdev->mem_map_registers =
-           ioremap_nocache(pci_resource_start(pdev, 1),
-                           pci_resource_len(qdev->pdev, 1));
+       qdev->mem_map_registers = pci_ioremap_bar(pdev, 1);
        if (!qdev->mem_map_registers) {
                printk(KERN_ERR PFX "%s: cannot map device registers\n",
                       pci_name(pdev));
index b83a9c9b6a9799e73d2cd3efdf4c5177734baa80..3a6d3ac25f12f9c12f3f80927d38c292e76442f8 100644 (file)
@@ -336,12 +336,11 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
                            (addr[5]);
 
                        QPRINTK(qdev, IFUP, INFO,
-                               "Adding %s address %02x:%02x:%02x:%02x:%02x:%02x"
+                               "Adding %s address %pM"
                                " at index %d in the CAM.\n",
                                ((type ==
                                  MAC_ADDR_TYPE_MULTI_MAC) ? "MULTICAST" :
-                                "UNICAST"), addr[0], addr[1], addr[2], addr[3],
-                               addr[4], addr[5], index);
+                                "UNICAST"), addr, index);
 
                        status =
                            ql_wait_reg_rdy(qdev,
@@ -1452,7 +1451,6 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
                        "Passing a normal packet upstream.\n");
                netif_rx(skb);
        }
-       ndev->last_rx = jiffies;
 }
 
 /* Process an outbound completion from an rx ring. */
@@ -3127,11 +3125,7 @@ static void ql_display_dev_info(struct net_device *ndev)
                qdev->chip_rev_id >> 4 & 0x0000000f,
                qdev->chip_rev_id >> 8 & 0x0000000f,
                qdev->chip_rev_id >> 12 & 0x0000000f);
-       QPRINTK(qdev, PROBE, INFO,
-               "MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
-               ndev->dev_addr[0], ndev->dev_addr[1],
-               ndev->dev_addr[2], ndev->dev_addr[3], ndev->dev_addr[4],
-               ndev->dev_addr[5]);
+       QPRINTK(qdev, PROBE, INFO, "MAC address %pM\n", ndev->dev_addr);
 }
 
 static int ql_adapter_down(struct ql_adapter *qdev)
index 34fe7ef8e5edf637c1f3c5f301c944e08f598076..d9a6e920fd62d6dba095590e7832fd5688771903 100644 (file)
@@ -598,7 +598,6 @@ static int r6040_rx(struct net_device *dev, int limit)
                
                /* Send to upper layer */
                netif_receive_skb(skb_ptr);
-               dev->last_rx = jiffies;
                dev->stats.rx_packets++;
                dev->stats.rx_bytes += descptr->len - 4;
 
index 4b7cb389dc4989edaf2f70ce9da55420484767bd..cb5042ef6dc77bc9652c3c5612c95c58c28feb68 100644 (file)
@@ -3484,7 +3484,6 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
                        if (rtl8169_rx_vlan_skb(tp, desc, skb) < 0)
                                netif_receive_skb(skb);
 
-                       dev->last_rx = jiffies;
                        dev->stats.rx_bytes += pkt_size;
                        dev->stats.rx_packets++;
                }
index 2b8fd68bc5163b49a09b373fb1913d6793bc051e..a6fd27a2cc3d25b4808ae5c85ba8c7a8e6e9da4b 100644 (file)
@@ -94,7 +94,7 @@ static int rionet_rx_clean(struct net_device *ndev)
 {
        int i;
        int error = 0;
-       struct rionet_private *rnet = ndev->priv;
+       struct rionet_private *rnet = netdev_priv(ndev);
        void *data;
 
        i = rnet->rx_slot;
@@ -132,7 +132,7 @@ static int rionet_rx_clean(struct net_device *ndev)
 static void rionet_rx_fill(struct net_device *ndev, int end)
 {
        int i;
-       struct rionet_private *rnet = ndev->priv;
+       struct rionet_private *rnet = netdev_priv(ndev);
 
        i = rnet->rx_slot;
        do {
@@ -151,7 +151,7 @@ static void rionet_rx_fill(struct net_device *ndev, int end)
 static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev,
                               struct rio_dev *rdev)
 {
-       struct rionet_private *rnet = ndev->priv;
+       struct rionet_private *rnet = netdev_priv(ndev);
 
        rio_add_outb_message(rnet->mport, rdev, 0, skb->data, skb->len);
        rnet->tx_skb[rnet->tx_slot] = skb;
@@ -175,7 +175,7 @@ static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev,
 static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
        int i;
-       struct rionet_private *rnet = ndev->priv;
+       struct rionet_private *rnet = netdev_priv(ndev);
        struct ethhdr *eth = (struct ethhdr *)skb->data;
        u16 destid;
        unsigned long flags;
@@ -215,7 +215,7 @@ static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u
                               u16 info)
 {
        struct net_device *ndev = dev_id;
-       struct rionet_private *rnet = ndev->priv;
+       struct rionet_private *rnet = netdev_priv(ndev);
        struct rionet_peer *peer;
 
        if (netif_msg_intr(rnet))
@@ -243,7 +243,7 @@ static void rionet_inb_msg_event(struct rio_mport *mport, void *dev_id, int mbox
 {
        int n;
        struct net_device *ndev = dev_id;
-       struct rionet_private *rnet = (struct rionet_private *)ndev->priv;
+       struct rionet_private *rnet = netdev_priv(ndev);
 
        if (netif_msg_intr(rnet))
                printk(KERN_INFO "%s: inbound message event, mbox %d slot %d\n",
@@ -258,7 +258,7 @@ static void rionet_inb_msg_event(struct rio_mport *mport, void *dev_id, int mbox
 static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
 {
        struct net_device *ndev = dev_id;
-       struct rionet_private *rnet = ndev->priv;
+       struct rionet_private *rnet = netdev_priv(ndev);
 
        spin_lock(&rnet->lock);
 
@@ -287,7 +287,7 @@ static int rionet_open(struct net_device *ndev)
        int i, rc = 0;
        struct rionet_peer *peer, *tmp;
        u32 pwdcsr;
-       struct rionet_private *rnet = ndev->priv;
+       struct rionet_private *rnet = netdev_priv(ndev);
 
        if (netif_msg_ifup(rnet))
                printk(KERN_INFO "%s: open\n", DRV_NAME);
@@ -351,7 +351,7 @@ static int rionet_open(struct net_device *ndev)
 
 static int rionet_close(struct net_device *ndev)
 {
-       struct rionet_private *rnet = (struct rionet_private *)ndev->priv;
+       struct rionet_private *rnet = netdev_priv(ndev);
        struct rionet_peer *peer, *tmp;
        int i;
 
@@ -400,7 +400,7 @@ static void rionet_remove(struct rio_dev *rdev)
 static void rionet_get_drvinfo(struct net_device *ndev,
                               struct ethtool_drvinfo *info)
 {
-       struct rionet_private *rnet = ndev->priv;
+       struct rionet_private *rnet = netdev_priv(ndev);
 
        strcpy(info->driver, DRV_NAME);
        strcpy(info->version, DRV_VERSION);
@@ -410,14 +410,14 @@ static void rionet_get_drvinfo(struct net_device *ndev,
 
 static u32 rionet_get_msglevel(struct net_device *ndev)
 {
-       struct rionet_private *rnet = ndev->priv;
+       struct rionet_private *rnet = netdev_priv(ndev);
 
        return rnet->msg_enable;
 }
 
 static void rionet_set_msglevel(struct net_device *ndev, u32 value)
 {
-       struct rionet_private *rnet = ndev->priv;
+       struct rionet_private *rnet = netdev_priv(ndev);
 
        rnet->msg_enable = value;
 }
@@ -435,7 +435,6 @@ static int rionet_setup_netdev(struct rio_mport *mport)
        struct net_device *ndev = NULL;
        struct rionet_private *rnet;
        u16 device_id;
-       DECLARE_MAC_BUF(mac);
 
        /* Allocate our net_device structure */
        ndev = alloc_etherdev(sizeof(struct rionet_private));
@@ -456,7 +455,7 @@ static int rionet_setup_netdev(struct rio_mport *mport)
                                RIO_MAX_ROUTE_ENTRIES(mport->sys_size));
 
        /* Set up private area */
-       rnet = (struct rionet_private *)ndev->priv;
+       rnet = netdev_priv(ndev);
        rnet->mport = mport;
 
        /* Set the default MAC address */
@@ -485,12 +484,12 @@ static int rionet_setup_netdev(struct rio_mport *mport)
        if (rc != 0)
                goto out;
 
-       printk("%s: %s %s Version %s, MAC %s\n",
+       printk("%s: %s %s Version %s, MAC %pM\n",
               ndev->name,
               DRV_NAME,
               DRV_DESC,
               DRV_VERSION,
-              print_mac(mac, ndev->dev_addr));
+              ndev->dev_addr);
 
       out:
        return rc;
index 3dd8f1342f70c58eb83ffb01cbb0f40576666076..6e4131f9a9339cd2a400ad3f57af238f1a773b55 100644 (file)
@@ -511,7 +511,6 @@ static int __devinit rr_init(struct net_device *dev)
        struct rr_private *rrpriv;
        struct rr_regs __iomem *regs;
        u32 sram_size, rev;
-       DECLARE_MAC_BUF(mac);
 
        rrpriv = netdev_priv(dev);
        regs = rrpriv->regs;
@@ -549,7 +548,7 @@ static int __devinit rr_init(struct net_device *dev)
        *(__be32 *)(dev->dev_addr+2) =
          htonl(rr_read_eeprom_word(rrpriv, offsetof(struct eeprom, manf.BoardULA[4])));
 
-       printk("  MAC: %s\n", print_mac(mac, dev->dev_addr));
+       printk("  MAC: %pM\n", dev->dev_addr);
 
        sram_size = rr_read_eeprom_word(rrpriv, 8);
        printk("  SRAM size 0x%06x\n", sram_size);
@@ -1006,7 +1005,6 @@ static void rx_int(struct net_device *dev, u32 rxlimit, u32 index)
 
                        netif_rx(skb);          /* send it up */
 
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                        dev->stats.rx_bytes += pkt_len;
                }
index 6a1375f9cbb81e2c627f2fe1f6606839b9c0c16c..62369341cb2c24a65519596d48ddf820b9d8cbab 100644 (file)
@@ -357,7 +357,7 @@ static void s2io_vlan_rx_register(struct net_device *dev,
                                        struct vlan_group *grp)
 {
        int i;
-       struct s2io_nic *nic = dev->priv;
+       struct s2io_nic *nic = netdev_priv(dev);
        unsigned long flags[MAX_TX_FIFOS];
        struct mac_info *mac_control = &nic->mac_control;
        struct config_param *config = &nic->config;
@@ -375,7 +375,7 @@ static void s2io_vlan_rx_register(struct net_device *dev,
 static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid)
 {
        int i;
-       struct s2io_nic *nic = dev->priv;
+       struct s2io_nic *nic = netdev_priv(dev);
        unsigned long flags[MAX_TX_FIFOS];
        struct mac_info *mac_control = &nic->mac_control;
        struct config_param *config = &nic->config;
@@ -2837,7 +2837,7 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget)
        int pkts_processed = 0;
        u8 __iomem *addr = NULL;
        u8 val8 = 0;
-       struct s2io_nic *nic = dev->priv;
+       struct s2io_nic *nic = netdev_priv(dev);
        struct XENA_dev_config __iomem *bar0 = nic->bar0;
        int budget_org = budget;
 
@@ -2909,7 +2909,7 @@ static int s2io_poll_inta(struct napi_struct *napi, int budget)
  */
 static void s2io_netpoll(struct net_device *dev)
 {
-       struct s2io_nic *nic = dev->priv;
+       struct s2io_nic *nic = netdev_priv(dev);
        struct mac_info *mac_control;
        struct config_param *config;
        struct XENA_dev_config __iomem *bar0 = nic->bar0;
@@ -3171,7 +3171,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
 static void s2io_mdio_write(u32 mmd_type, u64 addr, u16 value, struct net_device *dev)
 {
        u64 val64 = 0x0;
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
 
        //address transaction
@@ -3220,7 +3220,7 @@ static u64 s2io_mdio_read(u32 mmd_type, u64 addr, struct net_device *dev)
 {
        u64 val64 = 0x0;
        u64 rval64 = 0x0;
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
 
        /* address transaction */
@@ -3324,7 +3324,7 @@ static void s2io_updt_xpak_counter(struct net_device *dev)
        u64 val64 = 0x0;
        u64 addr  = 0x0;
 
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        struct stat_block *stat_info = sp->mac_control.stats_info;
 
        /* Check the communication with the MDIO slave */
@@ -3990,7 +3990,7 @@ static void remove_inta_isr(struct s2io_nic *sp)
 
 static int s2io_open(struct net_device *dev)
 {
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        int err = 0;
 
        /*
@@ -4048,7 +4048,7 @@ hw_init_failed:
 
 static int s2io_close(struct net_device *dev)
 {
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        struct config_param *config = &sp->config;
        u64 tmp64;
        int offset;
@@ -4087,7 +4087,7 @@ static int s2io_close(struct net_device *dev)
 
 static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off;
        register u64 val64;
        struct TxD *txdp;
@@ -4485,7 +4485,7 @@ static int do_s2io_chk_alarm_bit(u64 value, void __iomem * addr,
 static void s2io_handle_errors(void * dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
        u64 temp64 = 0,val64=0;
        int i = 0;
@@ -4752,7 +4752,7 @@ reset:
 static irqreturn_t s2io_isr(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *) dev_id;
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
        int i;
        u64 reason = 0;
@@ -4881,7 +4881,7 @@ static void s2io_updt_stats(struct s2io_nic *sp)
 
 static struct net_device_stats *s2io_get_stats(struct net_device *dev)
 {
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        struct mac_info *mac_control;
        struct config_param *config;
        int i;
@@ -4948,7 +4948,7 @@ static void s2io_set_multicast(struct net_device *dev)
 {
        int i, j, prev_cnt;
        struct dev_mc_list *mclist;
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
        u64 val64 = 0, multi_mac = 0x010203040506ULL, mask =
            0xfeffffffffffULL;
@@ -5277,7 +5277,7 @@ static int s2io_set_mac_addr(struct net_device *dev, void *p)
 
 static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr)
 {
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        register u64 mac_addr = 0, perm_addr = 0;
        int i;
        u64 tmp64;
@@ -5336,7 +5336,7 @@ static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr)
 static int s2io_ethtool_sset(struct net_device *dev,
                             struct ethtool_cmd *info)
 {
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        if ((info->autoneg == AUTONEG_ENABLE) ||
            (info->speed != SPEED_10000) || (info->duplex != DUPLEX_FULL))
                return -EINVAL;
@@ -5362,7 +5362,7 @@ static int s2io_ethtool_sset(struct net_device *dev,
 
 static int s2io_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
 {
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        info->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
        info->advertising = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
        info->port = PORT_FIBRE;
@@ -5397,7 +5397,7 @@ static int s2io_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
 static void s2io_ethtool_gdrvinfo(struct net_device *dev,
                                  struct ethtool_drvinfo *info)
 {
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
 
        strncpy(info->driver, s2io_driver_name, sizeof(info->driver));
        strncpy(info->version, s2io_driver_version, sizeof(info->version));
@@ -5427,7 +5427,7 @@ static void s2io_ethtool_gregs(struct net_device *dev,
        int i;
        u64 reg;
        u8 *reg_space = (u8 *) space;
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
 
        regs->len = XENA_REG_SPACE;
        regs->version = sp->pdev->subsystem_device;
@@ -5487,7 +5487,7 @@ static void s2io_phy_id(unsigned long data)
 static int s2io_ethtool_idnic(struct net_device *dev, u32 data)
 {
        u64 val64 = 0, last_gpio_ctrl_val;
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
        u16 subid;
 
@@ -5525,7 +5525,7 @@ static int s2io_ethtool_idnic(struct net_device *dev, u32 data)
 static void s2io_ethtool_gringparam(struct net_device *dev,
                                     struct ethtool_ringparam *ering)
 {
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        int i,tx_desc_count=0,rx_desc_count=0;
 
        if (sp->rxd_mode == RXD_MODE_1)
@@ -5568,7 +5568,7 @@ static void s2io_ethtool_getpause_data(struct net_device *dev,
                                       struct ethtool_pauseparam *ep)
 {
        u64 val64;
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
 
        val64 = readq(&bar0->rmac_pause_cfg);
@@ -5595,7 +5595,7 @@ static int s2io_ethtool_setpause_data(struct net_device *dev,
                               struct ethtool_pauseparam *ep)
 {
        u64 val64;
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
 
        val64 = readq(&bar0->rmac_pause_cfg);
@@ -5825,7 +5825,7 @@ static int s2io_ethtool_geeprom(struct net_device *dev,
 {
        u32 i, valid;
        u64 data;
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
 
        eeprom->magic = sp->pdev->vendor | (sp->pdev->device << 16);
 
@@ -5863,7 +5863,7 @@ static int s2io_ethtool_seeprom(struct net_device *dev,
 {
        int len = eeprom->len, cnt = 0;
        u64 valid = 0, data;
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
 
        if (eeprom->magic != (sp->pdev->vendor | (sp->pdev->device << 16))) {
                DBG_PRINT(ERR_DBG,
@@ -6243,7 +6243,7 @@ static void s2io_ethtool_test(struct net_device *dev,
                              struct ethtool_test *ethtest,
                              uint64_t * data)
 {
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        int orig_state = netif_running(sp->dev);
 
        if (ethtest->flags == ETH_TEST_FL_OFFLINE) {
@@ -6299,7 +6299,7 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
                                   u64 * tmp_stats)
 {
        int i = 0, k;
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        struct stat_block *stat_info = sp->mac_control.stats_info;
 
        s2io_updt_stats(sp);
@@ -6578,14 +6578,14 @@ static int s2io_ethtool_get_regs_len(struct net_device *dev)
 
 static u32 s2io_ethtool_get_rx_csum(struct net_device * dev)
 {
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
 
        return (sp->rx_csum);
 }
 
 static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
 {
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
 
        if (data)
                sp->rx_csum = 1;
@@ -6602,7 +6602,7 @@ static int s2io_get_eeprom_len(struct net_device *dev)
 
 static int s2io_get_sset_count(struct net_device *dev, int sset)
 {
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
 
        switch (sset) {
        case ETH_SS_TEST:
@@ -6625,7 +6625,7 @@ static void s2io_ethtool_get_strings(struct net_device *dev,
                                     u32 stringset, u8 * data)
 {
        int stat_size = 0;
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
 
        switch (stringset) {
        case ETH_SS_TEST:
@@ -6727,7 +6727,7 @@ static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
 static int s2io_change_mtu(struct net_device *dev, int new_mtu)
 {
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
        int ret = 0;
 
        if ((new_mtu < MIN_MTU) || (new_mtu > S2IO_JUMBO_SIZE)) {
@@ -7331,7 +7331,7 @@ out_unlock:
 
 static void s2io_tx_watchdog(struct net_device *dev)
 {
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
 
        if (netif_carrier_ok(dev)) {
                sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt++;
@@ -7544,7 +7544,6 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
        sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
 send_up:
        queue_rx_frame(skb, RXD_GET_VLAN_TAG(rxdp->Control_2));
-       dev->last_rx = jiffies;
 aggregate:
        sp->mac_control.rings[ring_no].rx_bufs_left -= 1;
        return SUCCESS;
@@ -7748,7 +7747,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        int mode;
        u8 dev_intr_type = intr_type;
        u8 dev_multiq = 0;
-       DECLARE_MAC_BUF(mac);
 
        ret = s2io_verify_parm(pdev, &dev_intr_type, &dev_multiq);
        if (ret)
@@ -7798,7 +7796,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        SET_NETDEV_DEV(dev, &pdev->dev);
 
        /*  Private member variable initialized to s2io NIC structure */
-       sp = dev->priv;
+       sp = netdev_priv(dev);
        memset(sp, 0, sizeof(struct s2io_nic));
        sp->dev = dev;
        sp->pdev = pdev;
@@ -7918,8 +7916,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
                goto mem_alloc_failed;
        }
 
-       sp->bar0 = ioremap(pci_resource_start(pdev, 0),
-                                    pci_resource_len(pdev, 0));
+       sp->bar0 = pci_ioremap_bar(pdev, 0);
        if (!sp->bar0) {
                DBG_PRINT(ERR_DBG, "%s: Neterion: cannot remap io mem1\n",
                          dev->name);
@@ -7927,8 +7924,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
                goto bar0_remap_failed;
        }
 
-       sp->bar1 = ioremap(pci_resource_start(pdev, 2),
-                                    pci_resource_len(pdev, 2));
+       sp->bar1 = pci_ioremap_bar(pdev, 2);
        if (!sp->bar1) {
                DBG_PRINT(ERR_DBG, "%s: Neterion: cannot remap io mem2\n",
                          dev->name);
@@ -8125,8 +8121,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
                  sp->product_name, pdev->revision);
        DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name,
                  s2io_driver_version);
-       DBG_PRINT(ERR_DBG, "%s: MAC ADDR: %s\n",
-                 dev->name, print_mac(mac, dev->dev_addr));
+       DBG_PRINT(ERR_DBG, "%s: MAC ADDR: %pM\n", dev->name, dev->dev_addr);
        DBG_PRINT(ERR_DBG, "SERIAL NUMBER: %s\n", sp->serial_num);
        if (sp->device_type & XFRAME_II_DEVICE) {
                mode = s2io_print_pci_mode(sp);
@@ -8255,7 +8250,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev)
 
        flush_scheduled_work();
 
-       sp = dev->priv;
+       sp = netdev_priv(dev);
        unregister_netdev(dev);
 
        free_shared_mem(sp);
@@ -8590,7 +8585,7 @@ static void clear_lro_session(struct lro *lro)
 static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag)
 {
        struct net_device *dev = skb->dev;
-       struct s2io_nic *sp = dev->priv;
+       struct s2io_nic *sp = netdev_priv(dev);
 
        skb->protocol = eth_type_trans(skb, dev);
        if (sp->vlgrp && vlan_tag
@@ -8639,7 +8634,7 @@ static pci_ers_result_t s2io_io_error_detected(struct pci_dev *pdev,
                                                pci_channel_state_t state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct s2io_nic *sp = netdev->priv;
+       struct s2io_nic *sp = netdev_priv(netdev);
 
        netif_device_detach(netdev);
 
@@ -8664,7 +8659,7 @@ static pci_ers_result_t s2io_io_error_detected(struct pci_dev *pdev,
 static pci_ers_result_t s2io_io_slot_reset(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct s2io_nic *sp = netdev->priv;
+       struct s2io_nic *sp = netdev_priv(netdev);
 
        if (pci_enable_device(pdev)) {
                printk(KERN_ERR "s2io: "
@@ -8688,7 +8683,7 @@ static pci_ers_result_t s2io_io_slot_reset(struct pci_dev *pdev)
 static void s2io_io_resume(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct s2io_nic *sp = netdev->priv;
+       struct s2io_nic *sp = netdev_priv(netdev);
 
        if (netif_running(netdev)) {
                if (s2io_card_up(sp)) {
index 5986cec17f19eff6b3aa06ba9f4d500ef953b8bd..be3025310e90c1eb3e3c2f15316b24fda8d8cd42 100644 (file)
@@ -869,7 +869,6 @@ printk("cm0: IP identification: %02x%02x  fragment offset: %02x%02x\n", buffer[3
        /* datagram completed: send to upper level */
        skb_trim(skb, dlen);
        netif_rx(skb);
-       dev->last_rx = jiffies;
        stats->rx_bytes+=dlen;
        stats->rx_packets++;
        lp->rx_skb[ns] = NULL;
index 2615d46e6e503c08fdcdbad4fcb1b8a3873d16e8..480caec1e0248ecc163c990f9f5a3a1dcab415b5 100644 (file)
@@ -2292,7 +2292,6 @@ static int sbmac_init(struct platform_device *pldev, long long base)
        uint64_t ea_reg;
        int i;
        int err;
-       DECLARE_MAC_BUF(mac);
 
        sc->sbm_dev = dev;
        sc->sbe_idx = idx;
@@ -2373,8 +2372,8 @@ static int sbmac_init(struct platform_device *pldev, long long base)
         * process so we need to finish off the config message that
         * was being displayed)
         */
-       pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %s\n",
-              dev->name, base, print_mac(mac, eaddr));
+       pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %pM\n",
+              dev->name, base, eaddr);
 
        sc->mii_bus->name = sbmac_mdio_string;
        snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx);
index 61955f8d80119705806b9fd8ab9714cd56bcff2c..590f2175e9e0af8dcaf9a6afee90f5033d056d9f 100644 (file)
@@ -816,7 +816,6 @@ static void _sc92031_rx_tasklet(struct net_device *dev)
                }
 
                skb->protocol = eth_type_trans(skb, dev);
-               dev->last_rx = jiffies;
                netif_rx(skb);
 
                dev->stats.rx_bytes += pkt_size;
index 48c64fb20eecf164b9022aae727e6dc86e8f5290..2fbc8f1e8b48c2992b389e8916b1583100efb48a 100644 (file)
@@ -158,7 +158,6 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr)
        int old_dmaar;
        int old_rear;
        int retval;
-       DECLARE_MAC_BUF(mac);
 
        if (!request_region(ioaddr, SEEQ8005_IO_EXTENT, "seeq8005"))
                return -ENODEV;
@@ -303,7 +302,7 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr)
        /* Retrieve and print the ethernet address. */
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = SA_prom[i+6];
-       printk("%s", print_mac(mac, dev->dev_addr));
+       printk("%pM", dev->dev_addr);
 
        if (dev->irq == 0xff)
                ;                       /* Do nothing: a user-level program will set it. */
@@ -564,7 +563,6 @@ static void seeq8005_rx(struct net_device *dev)
 
                        skb->protocol=eth_type_trans(skb,dev);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                        dev->stats.rx_bytes += pkt_len;
                }
index 3be13b592b4dbb0f7c1382ec745d8684f57c8cb6..3e25fb38f7392ac2aa97f2c20db68d4fc2cd6609 100644 (file)
@@ -12,3 +12,11 @@ config SFC
 
          To compile this driver as a module, choose M here.  The module
          will be called sfc.
+config SFC_MTD
+       bool "Solarflare Solarstorm SFC4000 flash MTD support"
+       depends on SFC && MTD
+       default y
+       help
+         This exposes the on-board flash memory as an MTD device (e.g.
+          /dev/mtd1).  This makes it possible to upload new boot code
+          to the NIC.
index c8f5704c8fb18adf946e8b1bc66afea50c76a12b..e507daa4f0e81e40baa2739e1eda77f5750c4075 100644 (file)
@@ -1,5 +1,6 @@
 sfc-y                  += efx.o falcon.o tx.o rx.o falcon_xmac.o \
                           selftest.o ethtool.o xfp_phy.o \
                           mdio_10g.o tenxpress.o boards.o sfe4001.o
+sfc-$(CONFIG_SFC_MTD)  += mtd.o
 
 obj-$(CONFIG_SFC)      += sfc.o
index 99e6023732691c08cf6060abff318b2331201b35..edf026280bec204e165c0556a67bdf0f983fa6f3 100644 (file)
@@ -11,6 +11,7 @@
 #include "phy.h"
 #include "boards.h"
 #include "efx.h"
+#include "workarounds.h"
 
 /* Macros for unpacking the board revision */
 /* The revision info is in host byte order. */
@@ -51,10 +52,129 @@ static void board_blink(struct efx_nic *efx, bool blink)
        }
 }
 
+/*****************************************************************************
+ * Support for LM87 sensor chip used on several boards
+ */
+#define LM87_REG_ALARMS1               0x41
+#define LM87_REG_ALARMS2               0x42
+#define LM87_IN_LIMITS(nr, _min, _max)                 \
+       0x2B + (nr) * 2, _max, 0x2C + (nr) * 2, _min
+#define LM87_AIN_LIMITS(nr, _min, _max)                        \
+       0x3B + (nr), _max, 0x1A + (nr), _min
+#define LM87_TEMP_INT_LIMITS(_min, _max)               \
+       0x39, _max, 0x3A, _min
+#define LM87_TEMP_EXT1_LIMITS(_min, _max)              \
+       0x37, _max, 0x38, _min
+
+#define LM87_ALARM_TEMP_INT            0x10
+#define LM87_ALARM_TEMP_EXT1           0x20
+
+#if defined(CONFIG_SENSORS_LM87) || defined(CONFIG_SENSORS_LM87_MODULE)
+
+static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
+                        const u8 *reg_values)
+{
+       struct i2c_client *client = i2c_new_device(&efx->i2c_adap, info);
+       int rc;
+
+       if (!client)
+               return -EIO;
+
+       while (*reg_values) {
+               u8 reg = *reg_values++;
+               u8 value = *reg_values++;
+               rc = i2c_smbus_write_byte_data(client, reg, value);
+               if (rc)
+                       goto err;
+       }
+
+       efx->board_info.hwmon_client = client;
+       return 0;
+
+err:
+       i2c_unregister_device(client);
+       return rc;
+}
+
+static void efx_fini_lm87(struct efx_nic *efx)
+{
+       i2c_unregister_device(efx->board_info.hwmon_client);
+}
+
+static int efx_check_lm87(struct efx_nic *efx, unsigned mask)
+{
+       struct i2c_client *client = efx->board_info.hwmon_client;
+       s32 alarms1, alarms2;
+
+       /* If link is up then do not monitor temperature */
+       if (EFX_WORKAROUND_7884(efx) && efx->link_up)
+               return 0;
+
+       alarms1 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS1);
+       alarms2 = i2c_smbus_read_byte_data(client, LM87_REG_ALARMS2);
+       if (alarms1 < 0)
+               return alarms1;
+       if (alarms2 < 0)
+               return alarms2;
+       alarms1 &= mask;
+       alarms2 &= mask >> 8;
+       if (alarms1 || alarms2) {
+               EFX_ERR(efx,
+                       "LM87 detected a hardware failure (status %02x:%02x)"
+                       "%s%s\n",
+                       alarms1, alarms2,
+                       (alarms1 & LM87_ALARM_TEMP_INT) ? " INTERNAL" : "",
+                       (alarms1 & LM87_ALARM_TEMP_EXT1) ? " EXTERNAL" : "");
+               return -ERANGE;
+       }
+
+       return 0;
+}
+
+#else /* !CONFIG_SENSORS_LM87 */
+
+static inline int
+efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info,
+             const u8 *reg_values)
+{
+       return 0;
+}
+static inline void efx_fini_lm87(struct efx_nic *efx)
+{
+}
+static inline int efx_check_lm87(struct efx_nic *efx, unsigned mask)
+{
+       return 0;
+}
+
+#endif /* CONFIG_SENSORS_LM87 */
+
 /*****************************************************************************
  * Support for the SFE4002
  *
  */
+static u8 sfe4002_lm87_channel = 0x03; /* use AIN not FAN inputs */
+
+static const u8 sfe4002_lm87_regs[] = {
+       LM87_IN_LIMITS(0, 0x83, 0x91),          /* 2.5V:  1.8V +/- 5% */
+       LM87_IN_LIMITS(1, 0x51, 0x5a),          /* Vccp1: 1.2V +/- 5% */
+       LM87_IN_LIMITS(2, 0xb6, 0xca),          /* 3.3V:  3.3V +/- 5% */
+       LM87_IN_LIMITS(3, 0xb0, 0xc9),          /* 5V:    4.6-5.2V */
+       LM87_IN_LIMITS(4, 0xb0, 0xe0),          /* 12V:   11-14V */
+       LM87_IN_LIMITS(5, 0x44, 0x4b),          /* Vccp2: 1.0V +/- 5% */
+       LM87_AIN_LIMITS(0, 0xa0, 0xb2),         /* AIN1:  1.66V +/- 5% */
+       LM87_AIN_LIMITS(1, 0x91, 0xa1),         /* AIN2:  1.5V +/- 5% */
+       LM87_TEMP_INT_LIMITS(10, 60),           /* board */
+       LM87_TEMP_EXT1_LIMITS(10, 70),          /* Falcon */
+       0
+};
+
+static struct i2c_board_info sfe4002_hwmon_info = {
+       I2C_BOARD_INFO("lm87", 0x2e),
+       .platform_data  = &sfe4002_lm87_channel,
+       .irq            = -1,
+};
+
 /****************************************************************************/
 /* LED allocations. Note that on rev A0 boards the schematic and the reality
  * differ: red and green are swapped. Below is the fixed (A1) layout (there
@@ -84,11 +204,27 @@ static void sfe4002_fault_led(struct efx_nic *efx, bool state)
                        QUAKE_LED_OFF);
 }
 
+static int sfe4002_check_hw(struct efx_nic *efx)
+{
+       /* A0 board rev. 4002s report a temperature fault the whole time
+        * (bad sensor) so we mask it out. */
+       unsigned alarm_mask =
+               (efx->board_info.major == 0 && efx->board_info.minor == 0) ?
+               ~LM87_ALARM_TEMP_EXT1 : ~0;
+
+       return efx_check_lm87(efx, alarm_mask);
+}
+
 static int sfe4002_init(struct efx_nic *efx)
 {
+       int rc = efx_init_lm87(efx, &sfe4002_hwmon_info, sfe4002_lm87_regs);
+       if (rc)
+               return rc;
+       efx->board_info.monitor = sfe4002_check_hw;
        efx->board_info.init_leds = sfe4002_init_leds;
        efx->board_info.set_fault_led = sfe4002_fault_led;
        efx->board_info.blink = board_blink;
+       efx->board_info.fini = efx_fini_lm87;
        return 0;
 }
 
index 06ea71c7e34ecb58bd117781eab7c09360381294..ac7bdbf3fd4abf7e9a562cfd3e4e122d005ad5a4 100644 (file)
@@ -77,11 +77,6 @@ static int napi_weight = 64;
  */
 unsigned int efx_monitor_interval = 1 * HZ;
 
-/* This controls whether or not the hardware monitor will trigger a
- * reset when it detects an error condition.
- */
-static unsigned int monitor_reset = true;
-
 /* This controls whether or not the driver will initialise devices
  * with invalid MAC addresses stored in the EEPROM or flash.  If true,
  * such devices will be initialised with a random locally-generated
@@ -612,17 +607,15 @@ static int efx_probe_port(struct efx_nic *efx)
        if (is_valid_ether_addr(efx->mac_address)) {
                memcpy(efx->net_dev->dev_addr, efx->mac_address, ETH_ALEN);
        } else {
-               DECLARE_MAC_BUF(mac);
-
-               EFX_ERR(efx, "invalid MAC address %s\n",
-                       print_mac(mac, efx->mac_address));
+               EFX_ERR(efx, "invalid MAC address %pM\n",
+                       efx->mac_address);
                if (!allow_bad_hwaddr) {
                        rc = -EINVAL;
                        goto err;
                }
                random_ether_addr(efx->net_dev->dev_addr);
-               EFX_INFO(efx, "using locally-generated MAC %s\n",
-                        print_mac(mac, efx->net_dev->dev_addr));
+               EFX_INFO(efx, "using locally-generated MAC %pM\n",
+                        efx->net_dev->dev_addr);
        }
 
        return 0;
@@ -1178,17 +1171,6 @@ static void efx_monitor(struct work_struct *data)
                rc = falcon_check_xmac(efx);
        mutex_unlock(&efx->mac_lock);
 
-       if (rc) {
-               if (monitor_reset) {
-                       EFX_ERR(efx, "hardware monitor detected a fault: "
-                               "triggering reset\n");
-                       efx_schedule_reset(efx, RESET_TYPE_MONITOR);
-               } else {
-                       EFX_ERR(efx, "hardware monitor detected a fault, "
-                               "skipping reset\n");
-               }
-       }
-
        queue_delayed_work(efx->workqueue, &efx->monitor_work,
                           efx_monitor_interval);
 }
@@ -1360,12 +1342,11 @@ static void efx_watchdog(struct net_device *net_dev)
 {
        struct efx_nic *efx = netdev_priv(net_dev);
 
-       EFX_ERR(efx, "TX stuck with stop_count=%d port_enabled=%d: %s\n",
-               atomic_read(&efx->netif_stop_count), efx->port_enabled,
-               monitor_reset ? "resetting channels" : "skipping reset");
+       EFX_ERR(efx, "TX stuck with stop_count=%d port_enabled=%d:"
+               " resetting channels\n",
+               atomic_read(&efx->netif_stop_count), efx->port_enabled);
 
-       if (monitor_reset)
-               efx_schedule_reset(efx, RESET_TYPE_MONITOR);
+       efx_schedule_reset(efx, RESET_TYPE_TX_WATCHDOG);
 }
 
 
@@ -1401,9 +1382,8 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data)
        EFX_ASSERT_RESET_SERIALISED(efx);
 
        if (!is_valid_ether_addr(new_addr)) {
-               DECLARE_MAC_BUF(mac);
-               EFX_ERR(efx, "invalid ethernet MAC address requested: %s\n",
-                       print_mac(mac, new_addr));
+               EFX_ERR(efx, "invalid ethernet MAC address requested: %pM\n",
+                       new_addr);
                return -EINVAL;
        }
 
@@ -1462,6 +1442,7 @@ static int efx_netdev_event(struct notifier_block *this,
                struct efx_nic *efx = netdev_priv(net_dev);
 
                strcpy(efx->name, net_dev->name);
+               efx_mtd_rename(efx);
        }
 
        return NOTIFY_DONE;
@@ -1553,6 +1534,7 @@ void efx_reset_down(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 
        efx_stop_all(efx);
        mutex_lock(&efx->mac_lock);
+       mutex_lock(&efx->spi_lock);
 
        rc = falcon_xmac_get_settings(efx, ecmd);
        if (rc)
@@ -1585,6 +1567,7 @@ int efx_reset_up(struct efx_nic *efx, struct ethtool_cmd *ecmd, bool ok)
                        EFX_ERR(efx, "could not restore PHY settings\n");
        }
 
+       mutex_unlock(&efx->spi_lock);
        mutex_unlock(&efx->mac_lock);
 
        if (ok) {
@@ -1780,6 +1763,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
        memset(efx, 0, sizeof(*efx));
        spin_lock_init(&efx->biu_lock);
        spin_lock_init(&efx->phy_lock);
+       mutex_init(&efx->spi_lock);
        INIT_WORK(&efx->reset_work, efx_reset_work);
        INIT_DELAYED_WORK(&efx->monitor_work, efx_monitor);
        efx->pci_dev = pci_dev;
@@ -1914,6 +1898,8 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
        if (!efx)
                return;
 
+       efx_mtd_remove(efx);
+
        /* Mark the NIC as fini, then stop the interface */
        rtnl_lock();
        efx->state = STATE_FINI;
@@ -2080,6 +2066,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
 
        EFX_LOG(efx, "initialisation successful\n");
 
+       efx_mtd_probe(efx); /* allowed to fail */
        return 0;
 
  fail5:
index d02937b70eeefc504e49e2cdff620c3fa656df58..dd0d45b9e71f2d4a7dc76fc87f28844dd25ad815 100644 (file)
@@ -58,6 +58,16 @@ extern int efx_port_dummy_op_int(struct efx_nic *efx);
 extern void efx_port_dummy_op_void(struct efx_nic *efx);
 extern void efx_port_dummy_op_blink(struct efx_nic *efx, bool blink);
 
+/* MTD */
+#ifdef CONFIG_SFC_MTD
+extern int efx_mtd_probe(struct efx_nic *efx);
+extern void efx_mtd_rename(struct efx_nic *efx);
+extern void efx_mtd_remove(struct efx_nic *efx);
+#else
+static inline int efx_mtd_probe(struct efx_nic *efx) { return 0; }
+static inline void efx_mtd_rename(struct efx_nic *efx) {}
+static inline void efx_mtd_remove(struct efx_nic *efx) {}
+#endif
 
 extern unsigned int efx_monitor_interval;
 
index cec15dbb88e474b4705d0141e6b264d2c79ec606..41e758e8fdb18438b88ed577675dbe546de3c67d 100644 (file)
@@ -72,7 +72,7 @@ extern const char *efx_loopback_mode_names[];
  * @RESET_TYPE_ALL: reset everything but PCI core blocks
  * @RESET_TYPE_WORLD: reset everything, save & restore PCI config
  * @RESET_TYPE_DISABLE: disable NIC
- * @RESET_TYPE_MONITOR: reset due to hardware monitor
+ * @RESET_TYPE_TX_WATCHDOG: reset due to TX watchdog
  * @RESET_TYPE_INT_ERROR: reset due to internal error
  * @RESET_TYPE_RX_RECOVERY: reset to recover from RX datapath errors
  * @RESET_TYPE_RX_DESC_FETCH: pcie error during rx descriptor fetch
@@ -86,7 +86,7 @@ enum reset_type {
        RESET_TYPE_WORLD = 2,
        RESET_TYPE_DISABLE = 3,
        RESET_TYPE_MAX_METHOD,
-       RESET_TYPE_MONITOR,
+       RESET_TYPE_TX_WATCHDOG,
        RESET_TYPE_INT_ERROR,
        RESET_TYPE_RX_RECOVERY,
        RESET_TYPE_RX_DESC_FETCH,
index cd0d0873d9782a358e1c835c6a51967071a780d5..abd8fcd6e62d749c2e3a91b3651c43d6186c1b95 100644 (file)
@@ -172,10 +172,7 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = {
 /* Number of ethtool statistics */
 #define EFX_ETHTOOL_NUM_STATS ARRAY_SIZE(efx_ethtool_stats)
 
-/* EEPROM range with gPXE configuration */
 #define EFX_ETHTOOL_EEPROM_MAGIC 0xEFAB
-#define EFX_ETHTOOL_EEPROM_MIN 0x800U
-#define EFX_ETHTOOL_EEPROM_MAX 0x1800U
 
 /**************************************************************************
  *
@@ -545,8 +542,8 @@ static int efx_ethtool_get_eeprom_len(struct net_device *net_dev)
 
        if (!spi)
                return 0;
-       return min(spi->size, EFX_ETHTOOL_EEPROM_MAX) -
-               min(spi->size, EFX_ETHTOOL_EEPROM_MIN);
+       return min(spi->size, EFX_EEPROM_BOOTCONFIG_END) -
+               min(spi->size, EFX_EEPROM_BOOTCONFIG_START);
 }
 
 static int efx_ethtool_get_eeprom(struct net_device *net_dev,
@@ -557,8 +554,10 @@ static int efx_ethtool_get_eeprom(struct net_device *net_dev,
        size_t len;
        int rc;
 
-       rc = falcon_spi_read(spi, eeprom->offset + EFX_ETHTOOL_EEPROM_MIN,
+       mutex_lock(&efx->spi_lock);
+       rc = falcon_spi_read(spi, eeprom->offset + EFX_EEPROM_BOOTCONFIG_START,
                             eeprom->len, &len, buf);
+       mutex_unlock(&efx->spi_lock);
        eeprom->magic = EFX_ETHTOOL_EEPROM_MAGIC;
        eeprom->len = len;
        return rc;
@@ -575,8 +574,10 @@ static int efx_ethtool_set_eeprom(struct net_device *net_dev,
        if (eeprom->magic != EFX_ETHTOOL_EEPROM_MAGIC)
                return -EINVAL;
 
-       rc = falcon_spi_write(spi, eeprom->offset + EFX_ETHTOOL_EEPROM_MIN,
+       mutex_lock(&efx->spi_lock);
+       rc = falcon_spi_write(spi, eeprom->offset + EFX_EEPROM_BOOTCONFIG_START,
                              eeprom->len, &len, buf);
+       mutex_unlock(&efx->spi_lock);
        eeprom->len = len;
        return rc;
 }
index 31ed1f49de008a547e61828174a39331d00c2512..71e0bed6061650596df3503bd197d7bf84d64d76 100644 (file)
@@ -1628,9 +1628,9 @@ static int falcon_spi_wait(struct efx_nic *efx)
        }
 }
 
-static int falcon_spi_cmd(const struct efx_spi_device *spi,
-                         unsigned int command, int address,
-                         const void *in, void *out, unsigned int len)
+int falcon_spi_cmd(const struct efx_spi_device *spi,
+                  unsigned int command, int address,
+                  const void *in, void *out, unsigned int len)
 {
        struct efx_nic *efx = spi->efx;
        bool addressed = (address >= 0);
@@ -1641,6 +1641,7 @@ static int falcon_spi_cmd(const struct efx_spi_device *spi,
        /* Input validation */
        if (len > FALCON_SPI_MAX_LEN)
                return -EINVAL;
+       BUG_ON(!mutex_is_locked(&efx->spi_lock));
 
        /* Check SPI not currently being accessed */
        rc = falcon_spi_wait(efx);
@@ -1699,8 +1700,7 @@ efx_spi_munge_command(const struct efx_spi_device *spi,
        return command | (((address >> 8) & spi->munge_address) << 3);
 }
 
-
-static int falcon_spi_fast_wait(const struct efx_spi_device *spi)
+int falcon_spi_fast_wait(const struct efx_spi_device *spi)
 {
        u8 status;
        int i, rc;
@@ -2253,13 +2253,15 @@ int falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out)
        __le16 *word, *limit;
        u32 csum;
 
-       region = kmalloc(NVCONFIG_END, GFP_KERNEL);
+       region = kmalloc(FALCON_NVCONFIG_END, GFP_KERNEL);
        if (!region)
                return -ENOMEM;
        nvconfig = region + NVCONFIG_OFFSET;
 
        spi = efx->spi_flash ? efx->spi_flash : efx->spi_eeprom;
-       rc = falcon_spi_read(spi, 0, NVCONFIG_END, NULL, region);
+       mutex_lock(&efx->spi_lock);
+       rc = falcon_spi_read(spi, 0, FALCON_NVCONFIG_END, NULL, region);
+       mutex_unlock(&efx->spi_lock);
        if (rc) {
                EFX_ERR(efx, "Failed to read %s\n",
                        efx->spi_flash ? "flash" : "EEPROM");
@@ -2283,7 +2285,7 @@ int falcon_read_nvram(struct efx_nic *efx, struct falcon_nvconfig *nvconfig_out)
                limit = (__le16 *) (nvconfig + 1);
        } else {
                word = region;
-               limit = region + NVCONFIG_END;
+               limit = region + FALCON_NVCONFIG_END;
        }
        for (csum = 0; word < limit; ++word)
                csum += le16_to_cpu(*word);
@@ -2555,6 +2557,11 @@ static int falcon_spi_device_init(struct efx_nic *efx,
                        SPI_DEV_TYPE_FIELD(device_type, SPI_DEV_TYPE_ADDR_LEN);
                spi_device->munge_address = (spi_device->size == 1 << 9 &&
                                             spi_device->addr_len == 1);
+               spi_device->erase_command =
+                       SPI_DEV_TYPE_FIELD(device_type, SPI_DEV_TYPE_ERASE_CMD);
+               spi_device->erase_size =
+                       1 << SPI_DEV_TYPE_FIELD(device_type,
+                                               SPI_DEV_TYPE_ERASE_SIZE);
                spi_device->block_size =
                        1 << SPI_DEV_TYPE_FIELD(device_type,
                                                SPI_DEV_TYPE_BLOCK_SIZE);
index 5d584b0dbb517043c05ce3d7050ffd999932ce2f..040e70ed4ec7caff41f018762551c1b38be5838b 100644 (file)
@@ -1150,7 +1150,6 @@ struct falcon_nvconfig_board_v3 {
        (((type) >> EFX_LOW_BIT(field)) & EFX_MASK32(EFX_WIDTH(field)))
 
 #define NVCONFIG_OFFSET 0x300
-#define NVCONFIG_END 0x400
 
 #define NVCONFIG_BOARD_MAGIC_NUM 0xFA1C
 struct falcon_nvconfig {
index 003e48dcb2f3f67ea28f94d3731f3a7cbd9f7e88..19e25210b687c34f701a16739c67ffa4626ba561 100644 (file)
@@ -260,6 +260,41 @@ void mdio_clause45_phy_reconfigure(struct efx_nic *efx)
                                    MDIO_MMDREG_CTRL1, ctrl2);
 }
 
+static void mdio_clause45_set_mmd_lpower(struct efx_nic *efx,
+                                        int lpower, int mmd)
+{
+       int phy = efx->mii.phy_id;
+       int stat = mdio_clause45_read(efx, phy, mmd, MDIO_MMDREG_STAT1);
+       int ctrl1, ctrl2;
+
+       EFX_TRACE(efx, "Setting low power mode for MMD %d to %d\n",
+                 mmd, lpower);
+
+       if (stat & (1 << MDIO_MMDREG_STAT1_LPABLE_LBN)) {
+               ctrl1 = ctrl2 = mdio_clause45_read(efx, phy,
+                                                  mmd, MDIO_MMDREG_CTRL1);
+               if (lpower)
+                       ctrl2 |= (1 << MDIO_MMDREG_CTRL1_LPOWER_LBN);
+               else
+                       ctrl2 &= ~(1 << MDIO_MMDREG_CTRL1_LPOWER_LBN);
+               if (ctrl1 != ctrl2)
+                       mdio_clause45_write(efx, phy, mmd,
+                                           MDIO_MMDREG_CTRL1, ctrl2);
+       }
+}
+
+void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
+                                  int low_power, unsigned int mmd_mask)
+{
+       int mmd = 0;
+       while (mmd_mask) {
+               if (mmd_mask & 1)
+                       mdio_clause45_set_mmd_lpower(efx, low_power, mmd);
+               mmd_mask = (mmd_mask >> 1);
+               mmd++;
+       }
+}
+
 /**
  * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO.
  * @efx:               Efx NIC
index 19c42eaf7fb47d714087c62efed01f3242b802c3..db9f358349c61c7fe57315b6f7f0cabcc60a7e09 100644 (file)
@@ -54,6 +54,9 @@
 /* Loopback bit for WIS, PCS, PHYSX and DTEXS */
 #define MDIO_MMDREG_CTRL1_LBACK_LBN    (14)
 #define MDIO_MMDREG_CTRL1_LBACK_WIDTH  (1)
+/* Low power */
+#define MDIO_MMDREG_CTRL1_LPOWER_LBN   (11)
+#define MDIO_MMDREG_CTRL1_LPOWER_WIDTH (1)
 
 /* Bits in MMDREG_STAT1 */
 #define MDIO_MMDREG_STAT1_FAULT_LBN    (7)
@@ -240,6 +243,10 @@ extern void mdio_clause45_transmit_disable(struct efx_nic *efx);
 /* Generic part of reconfigure: set/clear loopback bits */
 extern void mdio_clause45_phy_reconfigure(struct efx_nic *efx);
 
+/* Set the power state of the specified MMDs */
+extern void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
+                                         int low_power, unsigned int mmd_mask);
+
 /* Read (some of) the PHY settings over MDIO */
 extern void mdio_clause45_get_settings(struct efx_nic *efx,
                                       struct ethtool_cmd *ecmd);
diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c
new file mode 100644 (file)
index 0000000..a1e6c28
--- /dev/null
@@ -0,0 +1,268 @@
+/****************************************************************************
+ * Driver for Solarflare Solarstorm network controllers and boards
+ * Copyright 2005-2006 Fen Systems Ltd.
+ * Copyright 2006-2008 Solarflare Communications Inc.
+ *
+ * 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, incorporated herein by reference.
+ */
+
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/delay.h>
+
+#define EFX_DRIVER_NAME "sfc_mtd"
+#include "net_driver.h"
+#include "spi.h"
+
+#define EFX_SPI_VERIFY_BUF_LEN 16
+
+struct efx_mtd {
+       const struct efx_spi_device *spi;
+       struct mtd_info mtd;
+       char name[IFNAMSIZ + 20];
+};
+
+/* SPI utilities */
+
+static int efx_spi_slow_wait(struct efx_mtd *efx_mtd, bool uninterruptible)
+{
+       const struct efx_spi_device *spi = efx_mtd->spi;
+       struct efx_nic *efx = spi->efx;
+       u8 status;
+       int rc, i;
+
+       /* Wait up to 4s for flash/EEPROM to finish a slow operation. */
+       for (i = 0; i < 40; i++) {
+               __set_current_state(uninterruptible ?
+                                   TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE);
+               schedule_timeout(HZ / 10);
+               rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL,
+                                   &status, sizeof(status));
+               if (rc)
+                       return rc;
+               if (!(status & SPI_STATUS_NRDY))
+                       return 0;
+               if (signal_pending(current))
+                       return -EINTR;
+       }
+       EFX_ERR(efx, "timed out waiting for %s\n", efx_mtd->name);
+       return -ETIMEDOUT;
+}
+
+static int efx_spi_unlock(const struct efx_spi_device *spi)
+{
+       const u8 unlock_mask = (SPI_STATUS_BP2 | SPI_STATUS_BP1 |
+                               SPI_STATUS_BP0);
+       u8 status;
+       int rc;
+
+       rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL, &status, sizeof(status));
+       if (rc)
+               return rc;
+
+       if (!(status & unlock_mask))
+               return 0; /* already unlocked */
+
+       rc = falcon_spi_cmd(spi, SPI_WREN, -1, NULL, NULL, 0);
+       if (rc)
+               return rc;
+       rc = falcon_spi_cmd(spi, SPI_SST_EWSR, -1, NULL, NULL, 0);
+       if (rc)
+               return rc;
+
+       status &= ~unlock_mask;
+       rc = falcon_spi_cmd(spi, SPI_WRSR, -1, &status, NULL, sizeof(status));
+       if (rc)
+               return rc;
+       rc = falcon_spi_fast_wait(spi);
+       if (rc)
+               return rc;
+
+       return 0;
+}
+
+static int efx_spi_erase(struct efx_mtd *efx_mtd, loff_t start, size_t len)
+{
+       const struct efx_spi_device *spi = efx_mtd->spi;
+       unsigned pos, block_len;
+       u8 empty[EFX_SPI_VERIFY_BUF_LEN];
+       u8 buffer[EFX_SPI_VERIFY_BUF_LEN];
+       int rc;
+
+       if (len != spi->erase_size)
+               return -EINVAL;
+
+       if (spi->erase_command == 0)
+               return -EOPNOTSUPP;
+
+       rc = efx_spi_unlock(spi);
+       if (rc)
+               return rc;
+       rc = falcon_spi_cmd(spi, SPI_WREN, -1, NULL, NULL, 0);
+       if (rc)
+               return rc;
+       rc = falcon_spi_cmd(spi, spi->erase_command, start, NULL, NULL, 0);
+       if (rc)
+               return rc;
+       rc = efx_spi_slow_wait(efx_mtd, false);
+
+       /* Verify the entire region has been wiped */
+       memset(empty, 0xff, sizeof(empty));
+       for (pos = 0; pos < len; pos += block_len) {
+               block_len = min(len - pos, sizeof(buffer));
+               rc = falcon_spi_read(spi, start + pos, block_len, NULL, buffer);
+               if (rc)
+                       return rc;
+               if (memcmp(empty, buffer, block_len))
+                       return -EIO;
+
+               /* Avoid locking up the system */
+               cond_resched();
+               if (signal_pending(current))
+                       return -EINTR;
+       }
+
+       return rc;
+}
+
+/* MTD interface */
+
+static int efx_mtd_read(struct mtd_info *mtd, loff_t start, size_t len,
+                       size_t *retlen, u8 *buffer)
+{
+       struct efx_mtd *efx_mtd = mtd->priv;
+       const struct efx_spi_device *spi = efx_mtd->spi;
+       struct efx_nic *efx = spi->efx;
+       int rc;
+
+       rc = mutex_lock_interruptible(&efx->spi_lock);
+       if (rc)
+               return rc;
+       rc = falcon_spi_read(spi, FALCON_FLASH_BOOTCODE_START + start,
+                            len, retlen, buffer);
+       mutex_unlock(&efx->spi_lock);
+       return rc;
+}
+
+static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
+{
+       struct efx_mtd *efx_mtd = mtd->priv;
+       struct efx_nic *efx = efx_mtd->spi->efx;
+       int rc;
+
+       rc = mutex_lock_interruptible(&efx->spi_lock);
+       if (rc)
+               return rc;
+       rc = efx_spi_erase(efx_mtd, FALCON_FLASH_BOOTCODE_START + erase->addr,
+                          erase->len);
+       mutex_unlock(&efx->spi_lock);
+
+       if (rc == 0) {
+               erase->state = MTD_ERASE_DONE;
+       } else {
+               erase->state = MTD_ERASE_FAILED;
+               erase->fail_addr = 0xffffffff;
+       }
+       mtd_erase_callback(erase);
+       return rc;
+}
+
+static int efx_mtd_write(struct mtd_info *mtd, loff_t start,
+                        size_t len, size_t *retlen, const u8 *buffer)
+{
+       struct efx_mtd *efx_mtd = mtd->priv;
+       const struct efx_spi_device *spi = efx_mtd->spi;
+       struct efx_nic *efx = spi->efx;
+       int rc;
+
+       rc = mutex_lock_interruptible(&efx->spi_lock);
+       if (rc)
+               return rc;
+       rc = falcon_spi_write(spi, FALCON_FLASH_BOOTCODE_START + start,
+                             len, retlen, buffer);
+       mutex_unlock(&efx->spi_lock);
+       return rc;
+}
+
+static void efx_mtd_sync(struct mtd_info *mtd)
+{
+       struct efx_mtd *efx_mtd = mtd->priv;
+       struct efx_nic *efx = efx_mtd->spi->efx;
+       int rc;
+
+       mutex_lock(&efx->spi_lock);
+       rc = efx_spi_slow_wait(efx_mtd, true);
+       mutex_unlock(&efx->spi_lock);
+
+       if (rc)
+               EFX_ERR(efx, "%s sync failed (%d)\n", efx_mtd->name, rc);
+       return;
+}
+
+void efx_mtd_remove(struct efx_nic *efx)
+{
+       if (efx->spi_flash && efx->spi_flash->mtd) {
+               struct efx_mtd *efx_mtd = efx->spi_flash->mtd;
+               int rc;
+
+               for (;;) {
+                       rc = del_mtd_device(&efx_mtd->mtd);
+                       if (rc != -EBUSY)
+                               break;
+                       ssleep(1);
+               }
+               WARN_ON(rc);
+               kfree(efx_mtd);
+       }
+}
+
+void efx_mtd_rename(struct efx_nic *efx)
+{
+       if (efx->spi_flash && efx->spi_flash->mtd) {
+               struct efx_mtd *efx_mtd = efx->spi_flash->mtd;
+               snprintf(efx_mtd->name, sizeof(efx_mtd->name),
+                        "%s sfc_flash_bootrom", efx->name);
+       }
+}
+
+int efx_mtd_probe(struct efx_nic *efx)
+{
+       struct efx_spi_device *spi = efx->spi_flash;
+       struct efx_mtd *efx_mtd;
+
+       if (!spi || spi->size <= FALCON_FLASH_BOOTCODE_START)
+               return -ENODEV;
+
+       efx_mtd = kzalloc(sizeof(*efx_mtd), GFP_KERNEL);
+       if (!efx_mtd)
+               return -ENOMEM;
+
+       efx_mtd->spi = spi;
+       spi->mtd = efx_mtd;
+
+       efx_mtd->mtd.type = MTD_NORFLASH;
+       efx_mtd->mtd.flags = MTD_CAP_NORFLASH;
+       efx_mtd->mtd.size = spi->size - FALCON_FLASH_BOOTCODE_START;
+       efx_mtd->mtd.erasesize = spi->erase_size;
+       efx_mtd->mtd.writesize = 1;
+       efx_mtd_rename(efx);
+
+       efx_mtd->mtd.owner = THIS_MODULE;
+       efx_mtd->mtd.priv = efx_mtd;
+       efx_mtd->mtd.name = efx_mtd->name;
+       efx_mtd->mtd.erase = efx_mtd_erase;
+       efx_mtd->mtd.read = efx_mtd_read;
+       efx_mtd->mtd.write = efx_mtd_write;
+       efx_mtd->mtd.sync = efx_mtd_sync;
+
+       if (add_mtd_device(&efx_mtd->mtd)) {
+               kfree(efx_mtd);
+               spi->mtd = NULL;
+               /* add_mtd_device() returns 1 if the MTD table is full */
+               return -ENOMEM;
+       }
+
+       return 0;
+}
index cdb11fad6050b0b7700ff8ca64ac8f4afcd68579..e596c9a6a4c42e2ced56db6e2897610bbf120417 100644 (file)
@@ -414,6 +414,7 @@ struct efx_blinker {
  * @init_leds: Sets up board LEDs
  * @set_fault_led: Turns the fault LED on or off
  * @blink: Starts/stops blinking
+ * @monitor: Board-specific health check function
  * @fini: Cleanup function
  * @blinker: used to blink LEDs in software
  * @hwmon_client: I2C client for hardware monitor
@@ -428,6 +429,7 @@ struct efx_board {
         * have a separate init callback that happens later than
         * board init. */
        int (*init_leds)(struct efx_nic *efx);
+       int (*monitor) (struct efx_nic *nic);
        void (*set_fault_led) (struct efx_nic *efx, bool state);
        void (*blink) (struct efx_nic *efx, bool start);
        void (*fini) (struct efx_nic *nic);
@@ -525,11 +527,15 @@ struct efx_phy_operations {
  * @enum efx_phy_mode - PHY operating mode flags
  * @PHY_MODE_NORMAL: on and should pass traffic
  * @PHY_MODE_TX_DISABLED: on with TX disabled
+ * @PHY_MODE_LOW_POWER: set to low power through MDIO
+ * @PHY_MODE_OFF: switched off through external control
  * @PHY_MODE_SPECIAL: on but will not pass traffic
  */
 enum efx_phy_mode {
        PHY_MODE_NORMAL         = 0,
        PHY_MODE_TX_DISABLED    = 1,
+       PHY_MODE_LOW_POWER      = 2,
+       PHY_MODE_OFF            = 4,
        PHY_MODE_SPECIAL        = 8,
 };
 
@@ -655,6 +661,7 @@ union efx_multicast_hash {
  *     This field will be %NULL if no flash device is present.
  * @spi_eeprom: SPI EEPROM device
  *     This field will be %NULL if no EEPROM device is present.
+ * @spi_lock: SPI bus lock
  * @n_rx_nodesc_drop_cnt: RX no descriptor drop count
  * @nic_data: Hardware dependant state
  * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode,
@@ -731,6 +738,7 @@ struct efx_nic {
 
        struct efx_spi_device *spi_flash;
        struct efx_spi_device *spi_eeprom;
+       struct mutex spi_lock;
 
        unsigned n_rx_nodesc_drop_cnt;
 
index 0f805da4ce55e9c09abd9f6102eb741dbe7f71be..b8ba4bbad8897f384f6eb6f6168cce13df95132a 100644 (file)
@@ -752,7 +752,7 @@ void __efx_rx_packet(struct efx_channel *channel,
        channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
 
 done:
-       efx->net_dev->last_rx = jiffies;
+       ;
 }
 
 void efx_rx_strategy(struct efx_channel *channel)
index fe4e3fd223307877ce616020f5a7dd672f734b32..aa576c559ec8b5003f3a9a9a59c434fbc476df8f 100644 (file)
@@ -21,6 +21,7 @@
 #include "falcon_hwdefs.h"
 #include "falcon_io.h"
 #include "mac.h"
+#include "workarounds.h"
 
 /**************************************************************************
  *
 #define        P1_SPARE_LBN 4
 #define        P1_SPARE_WIDTH 4
 
-
-/**************************************************************************
- *
- * Temperature Sensor
- *
- **************************************************************************/
-#define        MAX6647 0x4e
-
-#define        RLTS    0x00
-#define        RLTE    0x01
-#define        RSL     0x02
-#define        RCL     0x03
-#define        RCRA    0x04
-#define        RLHN    0x05
-#define        RLLI    0x06
-#define        RRHI    0x07
-#define        RRLS    0x08
-#define        WCRW    0x0a
-#define        WLHO    0x0b
-#define        WRHA    0x0c
-#define        WRLN    0x0e
-#define        OSHT    0x0f
-#define        REET    0x10
-#define        RIET    0x11
-#define        RWOE    0x19
-#define        RWOI    0x20
-#define        HYS     0x21
-#define        QUEUE   0x22
-#define        MFID    0xfe
-#define        REVID   0xff
-
-/* Status bits */
-#define MAX6647_BUSY   (1 << 7)        /* ADC is converting */
-#define MAX6647_LHIGH  (1 << 6)        /* Local high temp. alarm */
-#define MAX6647_LLOW   (1 << 5)        /* Local low temp. alarm */
-#define MAX6647_RHIGH  (1 << 4)        /* Remote high temp. alarm */
-#define MAX6647_RLOW   (1 << 3)        /* Remote low temp. alarm */
-#define MAX6647_FAULT  (1 << 2)        /* DXN/DXP short/open circuit */
-#define MAX6647_EOT    (1 << 1)        /* Remote junction overtemp. */
-#define MAX6647_IOT    (1 << 0)        /* Local junction overtemp. */
-
-static const u8 xgphy_max_temperature = 90;
+/* Temperature Sensor */
+#define MAX664X_REG_RSL                0x02
+#define MAX664X_REG_WLHO       0x0B
 
 static void sfe4001_poweroff(struct efx_nic *efx)
 {
@@ -119,7 +81,7 @@ static void sfe4001_poweroff(struct efx_nic *efx)
        i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0xff);
 
        /* Clear any over-temperature alert */
-       i2c_smbus_read_byte_data(hwmon_client, RSL);
+       i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL);
 }
 
 static int sfe4001_poweron(struct efx_nic *efx)
@@ -131,7 +93,7 @@ static int sfe4001_poweron(struct efx_nic *efx)
        u8 out;
 
        /* Clear any previous over-temperature alert */
-       rc = i2c_smbus_read_byte_data(hwmon_client, RSL);
+       rc = i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL);
        if (rc < 0)
                return rc;
 
@@ -209,6 +171,34 @@ fail_on:
        return rc;
 }
 
+static int sfe4001_check_hw(struct efx_nic *efx)
+{
+       s32 status;
+
+       /* If XAUI link is up then do not monitor */
+       if (EFX_WORKAROUND_7884(efx) && falcon_xaui_link_ok(efx))
+               return 0;
+
+       /* Check the powered status of the PHY. Lack of power implies that
+        * the MAX6647 has shut down power to it, probably due to a temp.
+        * alarm. Reading the power status rather than the MAX6647 status
+        * directly because the later is read-to-clear and would thus
+        * start to power up the PHY again when polled, causing us to blip
+        * the power undesirably.
+        * We know we can read from the IO expander because we did
+        * it during power-on. Assume failure now is bad news. */
+       status = i2c_smbus_read_byte_data(efx->board_info.ioexp_client, P1_IN);
+       if (status >= 0 &&
+           (status & ((1 << P1_AFE_PWD_LBN) | (1 << P1_DSP_PWD25_LBN))) != 0)
+               return 0;
+
+       /* Use board power control, not PHY power control */
+       sfe4001_poweroff(efx);
+       efx->phy_mode = PHY_MODE_OFF;
+
+       return (status < 0) ? -EIO : -ERANGE;
+}
+
 /* On SFE4001 rev A2 and later, we can control the FLASH_CFG_1 pin
  * using the 3V3X output of the IO-expander.  Allow the user to set
  * this when the device is stopped, and keep it stopped then.
@@ -261,35 +251,34 @@ static void sfe4001_fini(struct efx_nic *efx)
        i2c_unregister_device(efx->board_info.hwmon_client);
 }
 
+static struct i2c_board_info sfe4001_hwmon_info = {
+       I2C_BOARD_INFO("max6647", 0x4e),
+       .irq            = -1,
+};
+
 /* This board uses an I2C expander to provider power to the PHY, which needs to
  * be turned on before the PHY can be used.
  * Context: Process context, rtnl lock held
  */
 int sfe4001_init(struct efx_nic *efx)
 {
-       struct i2c_client *hwmon_client;
        int rc;
 
-       hwmon_client = i2c_new_dummy(&efx->i2c_adap, MAX6647);
-       if (!hwmon_client)
+#if defined(CONFIG_SENSORS_LM90) || defined(CONFIG_SENSORS_LM90_MODULE)
+       efx->board_info.hwmon_client =
+               i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info);
+#else
+       efx->board_info.hwmon_client =
+               i2c_new_dummy(&efx->i2c_adap, sfe4001_hwmon_info.addr);
+#endif
+       if (!efx->board_info.hwmon_client)
                return -EIO;
-       efx->board_info.hwmon_client = hwmon_client;
 
-       /* Set DSP over-temperature alert threshold */
-       EFX_INFO(efx, "DSP cut-out at %dC\n", xgphy_max_temperature);
-       rc = i2c_smbus_write_byte_data(hwmon_client, WLHO,
-                                      xgphy_max_temperature);
+       /* Raise board/PHY high limit from 85 to 90 degrees Celsius */
+       rc = i2c_smbus_write_byte_data(efx->board_info.hwmon_client,
+                                      MAX664X_REG_WLHO, 90);
        if (rc)
-               goto fail_ioexp;
-
-       /* Read it back and verify */
-       rc = i2c_smbus_read_byte_data(hwmon_client, RLHN);
-       if (rc < 0)
-               goto fail_ioexp;
-       if (rc != xgphy_max_temperature) {
-               rc = -EFAULT;
-               goto fail_ioexp;
-       }
+               goto fail_hwmon;
 
        efx->board_info.ioexp_client = i2c_new_dummy(&efx->i2c_adap, PCA9539);
        if (!efx->board_info.ioexp_client) {
@@ -301,6 +290,7 @@ int sfe4001_init(struct efx_nic *efx)
         * blink code. */
        efx->board_info.blink = tenxpress_phy_blink;
 
+       efx->board_info.monitor = sfe4001_check_hw;
        efx->board_info.fini = sfe4001_fini;
 
        rc = sfe4001_poweron(efx);
@@ -319,6 +309,6 @@ fail_on:
 fail_ioexp:
        i2c_unregister_device(efx->board_info.ioexp_client);
 fail_hwmon:
-       i2c_unregister_device(hwmon_client);
+       i2c_unregister_device(efx->board_info.hwmon_client);
        return rc;
 }
index feef619423776889a0d275c81ad407c0a1b65465..c4aca132348aa1faa1412c44b35f73656113dae3 100644 (file)
@@ -25,6 +25,7 @@
 #define SPI_WRDI 0x04          /* Reset write enable latch */
 #define SPI_RDSR 0x05          /* Read status register */
 #define SPI_WREN 0x06          /* Set write enable latch */
+#define SPI_SST_EWSR 0x50      /* SST: Enable write to status register */
 
 #define SPI_STATUS_WPEN 0x80   /* Write-protect pin enabled */
 #define SPI_STATUS_BP2 0x10    /* Block protection bit 2 */
@@ -36,6 +37,7 @@
 /**
  * struct efx_spi_device - an Efx SPI (Serial Peripheral Interface) device
  * @efx:               The Efx controller that owns this device
+ * @mtd:               MTD state
  * @device_id:         Controller's id for the device
  * @size:              Size (in bytes)
  * @addr_len:          Number of address bytes in read/write commands
  *     use bit 3 of the command byte as address bit A8, rather
  *     than having a two-byte address.  If this flag is set, then
  *     commands should be munged in this way.
+ * @erase_command:     Erase command (or 0 if sector erase not needed).
+ * @erase_size:                Erase sector size (in bytes)
+ *     Erase commands affect sectors with this size and alignment.
+ *     This must be a power of two.
  * @block_size:                Write block size (in bytes).
  *     Write commands are limited to blocks with this size and alignment.
- * @read:              Read function for the device
- * @write:             Write function for the device
  */
 struct efx_spi_device {
        struct efx_nic *efx;
+#ifdef CONFIG_SFC_MTD
+       void *mtd;
+#endif
        int device_id;
        unsigned int size;
        unsigned int addr_len;
        unsigned int munge_address:1;
+       u8 erase_command;
+       unsigned int erase_size;
        unsigned int block_size;
 };
 
+int falcon_spi_cmd(const struct efx_spi_device *spi, unsigned int command,
+                  int address, const void* in, void *out, unsigned int len);
+int falcon_spi_fast_wait(const struct efx_spi_device *spi);
 int falcon_spi_read(const struct efx_spi_device *spi, loff_t start,
                    size_t len, size_t *retlen, u8 *buffer);
 int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,
                     size_t len, size_t *retlen, const u8 *buffer);
 
+/*
+ * SFC4000 flash is partitioned into:
+ *     0-0x400       chip and board config (see falcon_hwdefs.h)
+ *     0x400-0x8000  unused (or may contain VPD if EEPROM not present)
+ *     0x8000-end    boot code (mapped to PCI expansion ROM)
+ * SFC4000 small EEPROM (size < 0x400) is used for VPD only.
+ * SFC4000 large EEPROM (size >= 0x400) is partitioned into:
+ *     0-0x400       chip and board config
+ *     configurable  VPD
+ *     0x800-0x1800  boot config
+ * Aside from the chip and board config, all of these are optional and may
+ * be absent or truncated depending on the devices used.
+ */
+#define FALCON_NVCONFIG_END 0x400U
+#define FALCON_FLASH_BOOTCODE_START 0x8000U
+#define EFX_EEPROM_BOOTCONFIG_START 0x800U
+#define EFX_EEPROM_BOOTCONFIG_END 0x1800U
+
 #endif /* EFX_SPI_H */
index d507c93d666e1130dc2cd27768f38f2c4b710221..8d41c29b9d7b7f84974f9277bf7f0ec2a46c46f0 100644 (file)
@@ -376,6 +376,7 @@ static int tenxpress_phy_check_hw(struct efx_nic *efx)
 {
        struct tenxpress_phy_data *phy_data = efx->phy_data;
        bool link_ok;
+       int rc = 0;
 
        link_ok = tenxpress_link_ok(efx, true);
 
@@ -391,7 +392,22 @@ static int tenxpress_phy_check_hw(struct efx_nic *efx)
                atomic_set(&phy_data->bad_crc_count, 0);
        }
 
-       return 0;
+       rc = efx->board_info.monitor(efx);
+       if (rc) {
+               EFX_ERR(efx, "Board sensor %s; shutting down PHY\n",
+                       (rc == -ERANGE) ? "reported fault" : "failed");
+               if (efx->phy_mode & PHY_MODE_OFF) {
+                       /* Assume that board has shut PHY off */
+                       phy_data->phy_mode = PHY_MODE_OFF;
+               } else {
+                       efx->phy_mode |= PHY_MODE_LOW_POWER;
+                       mdio_clause45_set_mmds_lpower(efx, true,
+                                                     efx->phy_op->mmds);
+                       phy_data->phy_mode |= PHY_MODE_LOW_POWER;
+               }
+       }
+
+       return rc;
 }
 
 static void tenxpress_phy_fini(struct efx_nic *efx)
index fa7b49d69288d3d3fe201f6cbd1aa788cf1e8e4f..ec50b90f4285e5d4f4b6dcb4c9c65468edd35d2a 100644 (file)
@@ -22,6 +22,8 @@
 #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS
 /* RX PCIe double split performance issue */
 #define EFX_WORKAROUND_7575 EFX_WORKAROUND_ALWAYS
+/* Bit-bashed I2C reads cause performance drop */
+#define EFX_WORKAROUND_7884 EFX_WORKAROUND_ALWAYS
 /* TX pkt parser problem with <= 16 byte TXes */
 #define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS
 /* Low rate CRC errors require XAUI reset */
index 276151df3a703537ba01a315c90e7842d82ce4a8..91f0246621010cc0fd60a132f42ccbb189ff7c21 100644 (file)
@@ -128,6 +128,15 @@ static int xfp_phy_check_hw(struct efx_nic *efx)
        if (link_up != efx->link_up)
                falcon_xmac_sim_phy_event(efx);
 
+       rc = efx->board_info.monitor(efx);
+       if (rc) {
+               struct xfp_phy_data *phy_data = efx->phy_data;
+               EFX_ERR(efx, "XFP sensor alert; putting PHY into low power\n");
+               efx->phy_mode |= PHY_MODE_LOW_POWER;
+               mdio_clause45_set_mmds_lpower(efx, 1, XFP_REQUIRED_DEVS);
+               phy_data->phy_mode |= PHY_MODE_LOW_POWER;
+       }
+
        return rc;
 }
 
index 6261201403cdd143ca592a880ca5052c167522d9..97d68560067dd6e6a3da4be85c48b0e7fd5eacfe 100644 (file)
@@ -377,7 +377,6 @@ memory_squeeze:
                                        skb_put(skb, len);
                                        skb->protocol = eth_type_trans(skb, dev);
                                        netif_rx(skb);
-                                       dev->last_rx = jiffies;
                                        dev->stats.rx_packets++;
                                        dev->stats.rx_bytes += len;
                                } else {
@@ -657,7 +656,7 @@ static void timeout(struct net_device *dev)
 
 static void sgiseeq_set_multicast(struct net_device *dev)
 {
-       struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv;
+       struct sgiseeq_private *sp = netdev_priv(dev);
        unsigned char oldmode = sp->mode;
 
        if(dev->flags & IFF_PROMISC)
@@ -719,7 +718,6 @@ static int __init sgiseeq_probe(struct platform_device *pdev)
        struct sgiseeq_private *sp;
        struct net_device *dev;
        int err;
-       DECLARE_MAC_BUF(mac);
 
        dev = alloc_etherdev(sizeof (struct sgiseeq_private));
        if (!dev) {
@@ -793,8 +791,7 @@ static int __init sgiseeq_probe(struct platform_device *pdev)
                goto err_out_free_page;
        }
 
-       printk(KERN_INFO "%s: %s %s\n",
-              dev->name, sgiseeqstr, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: %s %pM\n", dev->name, sgiseeqstr, dev->dev_addr);
 
        return 0;
 
index a24bb68887ab24eb399137d8d6cf45366fa2b704..077d796ccb70c74fe62d224b8fc454aa7f84d827 100644 (file)
@@ -540,7 +540,6 @@ static int sh_eth_rx(struct net_device *ndev)
                        skb_put(skb, pkt_len);
                        skb->protocol = eth_type_trans(skb, ndev);
                        netif_rx(skb);
-                       ndev->last_rx = jiffies;
                        mdp->stats.rx_packets++;
                        mdp->stats.rx_bytes += pkt_len;
                }
@@ -800,7 +799,7 @@ static int sh_eth_phy_init(struct net_device *ndev)
        char phy_id[BUS_ID_SIZE];
        struct phy_device *phydev = NULL;
 
-       snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT,
+       snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
                mdp->mii_bus->id , mdp->phy_id);
 
        mdp->link = PHY_DOWN;
index e6e3bf58a56939be71258819256e8386eb47bd11..83cc3c5f79464b1ff2643e565aaaadce3aab71b2 100644 (file)
@@ -627,7 +627,6 @@ static int sis190_rx_interrupt(struct net_device *dev,
 
                        sis190_rx_skb(skb);
 
-                       dev->last_rx = jiffies;
                        stats->rx_packets++;
                        stats->rx_bytes += pkt_size;
                        if ((status & BCAST) == MCAST)
@@ -1791,7 +1790,6 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,
        struct net_device *dev;
        void __iomem *ioaddr;
        int rc;
-       DECLARE_MAC_BUF(mac);
 
        if (!printed_version) {
                net_drv(&debug, KERN_INFO SIS190_DRIVER_NAME " loaded.\n");
@@ -1841,10 +1839,9 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,
        if (rc < 0)
                goto err_remove_mii;
 
-       net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), "
-                 "%s\n",
+       net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), %pM\n",
                  pci_name(pdev), sis_chip_info[ent->driver_data].name,
-                 ioaddr, dev->irq, print_mac(mac, dev->dev_addr));
+                 ioaddr, dev->irq, dev->dev_addr);
 
        net_probe(tp, KERN_INFO "%s: %s mode.\n", dev->name,
                  (tp->features & F_HAS_RGMII) ? "RGMII" : "GMII");
index fa3a460f8e2f4ddd08d735c481e12466d86c6dca..9a363dc0db4125f1f1ce19dabf608eac4b802589 100644 (file)
@@ -404,7 +404,6 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
        int i, ret;
        const char *card_name = card_names[pci_id->driver_data];
        const char *dev_name = pci_name(pci_dev);
-       DECLARE_MAC_BUF(mac);
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -437,7 +436,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
        if (ret)
                goto err_out;
 
-       sis_priv = net_dev->priv;
+       sis_priv = netdev_priv(net_dev);
        net_dev->base_addr = ioaddr;
        net_dev->irq = pci_dev->irq;
        sis_priv->pci_dev = pci_dev;
@@ -534,9 +533,9 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
                goto err_unmap_rx;
 
        /* print some information about our NIC */
-       printk(KERN_INFO "%s: %s at %#lx, IRQ %d, %s\n",
+       printk(KERN_INFO "%s: %s at %#lx, IRQ %d, %pM\n",
               net_dev->name, card_name, ioaddr, net_dev->irq,
-              print_mac(mac, net_dev->dev_addr));
+              net_dev->dev_addr);
 
        /* Detect Wake on Lan support */
        ret = (inl(net_dev->base_addr + CFGPMC) & PMESP) >> 27;
@@ -570,7 +569,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
 
 static int __devinit sis900_mii_probe(struct net_device * net_dev)
 {
-       struct sis900_private * sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        const char *dev_name = pci_name(sis_priv->pci_dev);
        u16 poll_bit = MII_STAT_LINK, status = 0;
        unsigned long timeout = jiffies + 5 * HZ;
@@ -698,7 +697,7 @@ static int __devinit sis900_mii_probe(struct net_device * net_dev)
 
 static u16 sis900_default_phy(struct net_device * net_dev)
 {
-       struct sis900_private * sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        struct mii_phy *phy = NULL, *phy_home = NULL,
                *default_phy = NULL, *phy_lan = NULL;
        u16 status;
@@ -999,7 +998,7 @@ static void sis900_poll(struct net_device *dev)
 static int
 sis900_open(struct net_device *net_dev)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        long ioaddr = net_dev->base_addr;
        int ret;
 
@@ -1055,7 +1054,7 @@ sis900_open(struct net_device *net_dev)
 static void
 sis900_init_rxfilter (struct net_device * net_dev)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        long ioaddr = net_dev->base_addr;
        u32 rfcrSave;
        u32 i;
@@ -1093,7 +1092,7 @@ sis900_init_rxfilter (struct net_device * net_dev)
 static void
 sis900_init_tx_ring(struct net_device *net_dev)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        long ioaddr = net_dev->base_addr;
        int i;
 
@@ -1127,7 +1126,7 @@ sis900_init_tx_ring(struct net_device *net_dev)
 static void
 sis900_init_rx_ring(struct net_device *net_dev)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        long ioaddr = net_dev->base_addr;
        int i;
 
@@ -1198,7 +1197,7 @@ sis900_init_rx_ring(struct net_device *net_dev)
 
 static void sis630_set_eq(struct net_device *net_dev, u8 revision)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        u16 reg14h, eq_value=0, max_value=0, min_value=0;
        int i, maxcount=10;
 
@@ -1271,7 +1270,7 @@ static void sis630_set_eq(struct net_device *net_dev, u8 revision)
 static void sis900_timer(unsigned long data)
 {
        struct net_device *net_dev = (struct net_device *)data;
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        struct mii_phy *mii_phy = sis_priv->mii;
        static const int next_tick = 5*HZ;
        u16 status;
@@ -1341,7 +1340,7 @@ static void sis900_timer(unsigned long data)
 
 static void sis900_check_mode(struct net_device *net_dev, struct mii_phy *mii_phy)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        long ioaddr = net_dev->base_addr;
        int speed, duplex;
 
@@ -1420,7 +1419,7 @@ static void sis900_set_mode (long ioaddr, int speed, int duplex)
 
 static void sis900_auto_negotiate(struct net_device *net_dev, int phy_addr)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        int i = 0;
        u32 status;
 
@@ -1455,7 +1454,7 @@ static void sis900_auto_negotiate(struct net_device *net_dev, int phy_addr)
 
 static void sis900_read_mode(struct net_device *net_dev, int *speed, int *duplex)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        struct mii_phy *phy = sis_priv->mii;
        int phy_addr = sis_priv->cur_phy;
        u32 status;
@@ -1510,7 +1509,7 @@ static void sis900_read_mode(struct net_device *net_dev, int *speed, int *duplex
 
 static void sis900_tx_timeout(struct net_device *net_dev)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        long ioaddr = net_dev->base_addr;
        unsigned long flags;
        int i;
@@ -1569,7 +1568,7 @@ static void sis900_tx_timeout(struct net_device *net_dev)
 static int
 sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        long ioaddr = net_dev->base_addr;
        unsigned int  entry;
        unsigned long flags;
@@ -1639,7 +1638,7 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
 static irqreturn_t sis900_interrupt(int irq, void *dev_instance)
 {
        struct net_device *net_dev = dev_instance;
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        int boguscnt = max_interrupt_work;
        long ioaddr = net_dev->base_addr;
        u32 status;
@@ -1701,7 +1700,7 @@ static irqreturn_t sis900_interrupt(int irq, void *dev_instance)
 
 static int sis900_rx(struct net_device *net_dev)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        long ioaddr = net_dev->base_addr;
        unsigned int entry = sis_priv->cur_rx % NUM_RX_DESC;
        u32 rx_status = sis_priv->rx_ring[entry].cmdsts;
@@ -1790,7 +1789,6 @@ static int sis900_rx(struct net_device *net_dev)
                        /* some network statistics */
                        if ((rx_status & BCAST) == MCAST)
                                net_dev->stats.multicast++;
-                       net_dev->last_rx = jiffies;
                        net_dev->stats.rx_bytes += rx_size;
                        net_dev->stats.rx_packets++;
                        sis_priv->dirty_rx++;
@@ -1851,7 +1849,7 @@ refill_rx_ring:
 
 static void sis900_finish_xmit (struct net_device *net_dev)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
 
        for (; sis_priv->dirty_tx != sis_priv->cur_tx; sis_priv->dirty_tx++) {
                struct sk_buff *skb;
@@ -1920,7 +1918,7 @@ static void sis900_finish_xmit (struct net_device *net_dev)
 static int sis900_close(struct net_device *net_dev)
 {
        long ioaddr = net_dev->base_addr;
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        struct sk_buff *skb;
        int i;
 
@@ -1975,7 +1973,7 @@ static int sis900_close(struct net_device *net_dev)
 static void sis900_get_drvinfo(struct net_device *net_dev,
                               struct ethtool_drvinfo *info)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
 
        strcpy (info->driver, SIS900_MODULE_NAME);
        strcpy (info->version, SIS900_DRV_VERSION);
@@ -1984,26 +1982,26 @@ static void sis900_get_drvinfo(struct net_device *net_dev,
 
 static u32 sis900_get_msglevel(struct net_device *net_dev)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        return sis_priv->msg_enable;
 }
 
 static void sis900_set_msglevel(struct net_device *net_dev, u32 value)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        sis_priv->msg_enable = value;
 }
 
 static u32 sis900_get_link(struct net_device *net_dev)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        return mii_link_ok(&sis_priv->mii_info);
 }
 
 static int sis900_get_settings(struct net_device *net_dev,
                                struct ethtool_cmd *cmd)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        spin_lock_irq(&sis_priv->lock);
        mii_ethtool_gset(&sis_priv->mii_info, cmd);
        spin_unlock_irq(&sis_priv->lock);
@@ -2013,7 +2011,7 @@ static int sis900_get_settings(struct net_device *net_dev,
 static int sis900_set_settings(struct net_device *net_dev,
                                struct ethtool_cmd *cmd)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        int rt;
        spin_lock_irq(&sis_priv->lock);
        rt = mii_ethtool_sset(&sis_priv->mii_info, cmd);
@@ -2023,7 +2021,7 @@ static int sis900_set_settings(struct net_device *net_dev,
 
 static int sis900_nway_reset(struct net_device *net_dev)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        return mii_nway_restart(&sis_priv->mii_info);
 }
 
@@ -2040,7 +2038,7 @@ static int sis900_nway_reset(struct net_device *net_dev)
 
 static int sis900_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        long pmctrl_addr = net_dev->base_addr + pmctrl;
        u32 cfgpmcsr = 0, pmctrl_bits = 0;
 
@@ -2111,7 +2109,7 @@ static const struct ethtool_ops sis900_ethtool_ops = {
 
 static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
 {
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        struct mii_ioctl_data *data = if_mii(rq);
 
        switch(cmd) {
@@ -2145,7 +2143,7 @@ static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
 
 static int sis900_set_config(struct net_device *dev, struct ifmap *map)
 {
-       struct sis900_private *sis_priv = dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(dev);
        struct mii_phy *mii_phy = sis_priv->mii;
 
        u16 status;
@@ -2268,7 +2266,7 @@ static inline u16 sis900_mcast_bitnr(u8 *addr, u8 revision)
 static void set_rx_mode(struct net_device *net_dev)
 {
        long ioaddr = net_dev->base_addr;
-       struct sis900_private * sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        u16 mc_filter[16] = {0};        /* 256/128 bits multicast hash table */
        int i, table_entries;
        u32 rx_mode;
@@ -2343,7 +2341,7 @@ static void set_rx_mode(struct net_device *net_dev)
 
 static void sis900_reset(struct net_device *net_dev)
 {
-       struct sis900_private * sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        long ioaddr = net_dev->base_addr;
        int i = 0;
        u32 status = TxRCMP | RxRCMP;
@@ -2376,7 +2374,7 @@ static void sis900_reset(struct net_device *net_dev)
 static void __devexit sis900_remove(struct pci_dev *pci_dev)
 {
        struct net_device *net_dev = pci_get_drvdata(pci_dev);
-       struct sis900_private * sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        struct mii_phy *phy = NULL;
 
        while (sis_priv->first_mii) {
@@ -2420,7 +2418,7 @@ static int sis900_suspend(struct pci_dev *pci_dev, pm_message_t state)
 static int sis900_resume(struct pci_dev *pci_dev)
 {
        struct net_device *net_dev = pci_get_drvdata(pci_dev);
-       struct sis900_private *sis_priv = net_dev->priv;
+       struct sis900_private *sis_priv = netdev_priv(net_dev);
        long ioaddr = net_dev->base_addr;
 
        if(!netif_running(net_dev))
index a2b092bb3626b63a35ac44bec9ab6b2049242b19..282bb47deccc17c2b13963e1a83f9305cee418e5 100644 (file)
@@ -1680,7 +1680,6 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
        skb->protocol = fddi_type_trans(skb, bp->dev);
 
        netif_rx(skb);
-       bp->dev->last_rx = jiffies;
 
        HWM_RX_CHECK(smc, RX_LOW_WATERMARK);
        return;
@@ -1939,7 +1938,6 @@ int mac_drv_rx_init(struct s_smc *smc, int len, int fc,
 
        // deliver frame to system
        skb->protocol = fddi_type_trans(skb, smc->os.dev);
-       skb->dev->last_rx = jiffies;
        netif_rx(skb);
 
        return (0);
index 43f4c730be42546b8be59f1f97127f2d0ef06a3a..05f9d50d956a2d8dda184cdcfbd52d5123ab7215 100644 (file)
@@ -149,24 +149,6 @@ static u32 wol_supported(const struct skge_hw *hw)
        return WAKE_MAGIC | WAKE_PHY;
 }
 
-static u32 pci_wake_enabled(struct pci_dev *dev)
-{
-       int pm = pci_find_capability(dev, PCI_CAP_ID_PM);
-       u16 value;
-
-       /* If device doesn't support PM Capabilities, but request is to disable
-        * wake events, it's a nop; otherwise fail */
-       if (!pm)
-               return 0;
-
-       pci_read_config_word(dev, pm + PCI_PM_PMC, &value);
-
-       value &= PCI_PM_CAP_PME_MASK;
-       value >>= ffs(PCI_PM_CAP_PME_MASK) - 1;   /* First bit of mask */
-
-       return value != 0;
-}
-
 static void skge_wol_init(struct skge_port *skge)
 {
        struct skge_hw *hw = skge->hw;
@@ -254,10 +236,14 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        struct skge_port *skge = netdev_priv(dev);
        struct skge_hw *hw = skge->hw;
 
-       if (wol->wolopts & ~wol_supported(hw))
+       if ((wol->wolopts & ~wol_supported(hw))
+           || !device_can_wakeup(&hw->pdev->dev))
                return -EOPNOTSUPP;
 
        skge->wol = wol->wolopts;
+
+       device_set_wakeup_enable(&hw->pdev->dev, skge->wol);
+
        return 0;
 }
 
@@ -3200,7 +3186,6 @@ static int skge_poll(struct napi_struct *napi, int to_do)
 
                skb = skge_rx_get(dev, e, control, rd->status, rd->csum2);
                if (likely(skb)) {
-                       dev->last_rx = jiffies;
                        netif_receive_skb(skb);
 
                        ++work_done;
@@ -3856,7 +3841,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
        skge->speed = -1;
        skge->advertising = skge_supported_modes(hw);
 
-       if (pci_wake_enabled(hw->pdev))
+       if (device_may_wakeup(&hw->pdev->dev))
                skge->wol = wol_supported(hw) & WAKE_MAGIC;
 
        hw->dev[port] = dev;
@@ -3885,11 +3870,10 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
 static void __devinit skge_show_addr(struct net_device *dev)
 {
        const struct skge_port *skge = netdev_priv(dev);
-       DECLARE_MAC_BUF(mac);
 
        if (netif_msg_probe(skge))
-               printk(KERN_INFO PFX "%s: addr %s\n",
-                      dev->name, print_mac(mac, dev->dev_addr));
+               printk(KERN_INFO PFX "%s: addr %pM\n",
+                      dev->name, dev->dev_addr);
 }
 
 static int __devinit skge_probe(struct pci_dev *pdev,
@@ -4082,8 +4066,8 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
        }
 
        skge_write32(hw, B0_IMSK, 0);
-       pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
-       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+       pci_prepare_to_sleep(pdev);
 
        return 0;
 }
@@ -4096,7 +4080,7 @@ static int skge_resume(struct pci_dev *pdev)
        if (!hw)
                return 0;
 
-       err = pci_set_power_state(pdev, PCI_D0);
+       err = pci_back_from_sleep(pdev);
        if (err)
                goto out;
 
@@ -4104,8 +4088,6 @@ static int skge_resume(struct pci_dev *pdev)
        if (err)
                goto out;
 
-       pci_enable_wake(pdev, PCI_D0, 0);
-
        err = skge_reset(hw);
        if (err)
                goto out;
@@ -4146,8 +4128,8 @@ static void skge_shutdown(struct pci_dev *pdev)
                wol |= skge->wol;
        }
 
-       pci_enable_wake(pdev, PCI_D3hot, wol);
-       pci_enable_wake(pdev, PCI_D3cold, wol);
+       if (pci_enable_wake(pdev, PCI_D3cold, wol))
+               pci_enable_wake(pdev, PCI_D3hot, wol);
 
        pci_disable_device(pdev);
        pci_set_power_state(pdev, PCI_D3hot);
index 3813d15e2df75d613392bf20f5e134f358cd26ed..4dcd1a62fb490e95768c4cc8446b839890a12194 100644 (file)
@@ -4118,11 +4118,10 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
 static void __devinit sky2_show_addr(struct net_device *dev)
 {
        const struct sky2_port *sky2 = netdev_priv(dev);
-       DECLARE_MAC_BUF(mac);
 
        if (netif_msg_probe(sky2))
-               printk(KERN_INFO PFX "%s: addr %s\n",
-                      dev->name, print_mac(mac, dev->dev_addr));
+               printk(KERN_INFO PFX "%s: addr %pM\n",
+                      dev->name, dev->dev_addr);
 }
 
 /* Handle software interrupt used during MSI test */
index 1d58991d395b6ef32120e1e265c8245ab61219e3..25cec06d6dcc661f0c6bcbb6f039555b529ea836 100644 (file)
@@ -365,7 +365,6 @@ static void sl_bump(struct slip *sl)
        skb_reset_mac_header(skb);
        skb->protocol = htons(ETH_P_IP);
        netif_rx(skb);
-       sl->dev->last_rx = jiffies;
        sl->rx_packets++;
 }
 
index d6abb68e6e2f20eb8b238c85f710ccd7a75f913d..58a0e0a4a325b2ef33fee3425cb6d373254cb180 100644 (file)
@@ -196,7 +196,6 @@ static int __init ultramca_probe(struct device *gen_dev)
        int tirq = 0;
        int base_addr = ultra_io[ultra_found];
        int irq = ultra_irq[ultra_found];
-       DECLARE_MAC_BUF(mac);
 
        if (base_addr || irq) {
                printk(KERN_INFO "Probing for SMC MCA adapter");
@@ -334,8 +333,8 @@ static int __init ultramca_probe(struct device *gen_dev)
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = inb(ioaddr + 8 + i);
 
-       printk(KERN_INFO "smc_mca[%d]: Parameters: %#3x, %s",
-              slot + 1, ioaddr, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "smc_mca[%d]: Parameters: %#3x, %pM",
+              slot + 1, ioaddr, dev->dev_addr);
 
        /* Switch from the station address to the alternate register set
         * and read the useful registers there.
index 00d6cf1af4843a929f5856a40c8bf3af9b0b0c9b..0fe0251767bb52c8e7920e219261839bbacd7769 100644 (file)
@@ -198,7 +198,6 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr)
        unsigned char num_pages, irqreg, addr, piomode;
        unsigned char idreg = inb(ioaddr + 7);
        unsigned char reg4 = inb(ioaddr + 4) & 0x7f;
-       DECLARE_MAC_BUF(mac);
 
        if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME))
                return -EBUSY;
@@ -228,8 +227,8 @@ static int __init ultra_probe1(struct net_device *dev, int ioaddr)
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = inb(ioaddr + 8 + i);
 
-       printk("%s: %s at %#3x, %s", dev->name, model_name,
-              ioaddr, print_mac(mac, dev->dev_addr));
+       printk("%s: %s at %#3x, %pM", dev->name, model_name,
+              ioaddr, dev->dev_addr);
 
        /* Switch from the station address to the alternate register set and
           read the useful registers there. */
index a5a91ace28ccec743507e38210164a67d5dc58c4..cb6c097a2e0ad78e7b31d01ac18750540cc9fb7b 100644 (file)
@@ -163,7 +163,6 @@ static int __init ultra32_probe1(struct net_device *dev, int ioaddr)
        unsigned char idreg;
        unsigned char reg4;
        const char *ifmap[] = {"UTP No Link", "", "UTP/AUI", "UTP/BNC"};
-       DECLARE_MAC_BUF(mac);
 
        if (!request_region(ioaddr, ULTRA32_IO_EXTENT, DRV_NAME))
                return -EBUSY;
@@ -207,8 +206,8 @@ static int __init ultra32_probe1(struct net_device *dev, int ioaddr)
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = inb(ioaddr + 8 + i);
 
-       printk("%s: %s at 0x%X, %s",
-              dev->name, model_name, ioaddr, print_mac(mac, dev->dev_addr));
+       printk("%s: %s at 0x%X, %pM",
+              dev->name, model_name, ioaddr, dev->dev_addr);
 
        /* Switch from the station address to the alternate register set and
           read the useful registers there. */
index 1f26ab0e7986533386a821870c30290222c387ba..a91b7351150d7bed3182a499ab166bbc58846d3b 100644 (file)
@@ -439,7 +439,6 @@ static inline void   smc911x_rcv(struct net_device *dev)
 
                DBG(SMC_DEBUG_PKTS, "%s: Received packet\n", dev->name);
                PRINT_PKT(data, ((pkt_len - 4) <= 64) ? pkt_len - 4 : 64);
-               dev->last_rx = jiffies;
                skb->protocol = eth_type_trans(skb, dev);
                netif_rx(skb);
                dev->stats.rx_packets++;
@@ -1231,7 +1230,6 @@ smc911x_rx_dma_irq(int dma, void *data)
        BUG_ON(skb == NULL);
        lp->current_rx_skb = NULL;
        PRINT_PKT(skb->data, skb->len);
-       dev->last_rx = jiffies;
        skb->protocol = eth_type_trans(skb, dev);
        dev->stats.rx_packets++;
        dev->stats.rx_bytes += skb->len;
index de67744c4a2a1f1cf960e80a8cd0ec309db36e58..e7cc80f32560af16f9a8a4b990a939e5c20827ad 100644 (file)
@@ -876,8 +876,6 @@ static int __init smc_probe(struct net_device *dev, int ioaddr)
        word memory_info_register;
        word memory_cfg_register;
 
-       DECLARE_MAC_BUF(mac);
-
        /* Grab the region so that no one else tries to probe our ioports. */
        if (!request_region(ioaddr, SMC_IO_EXTENT, DRV_NAME))
                return -EBUSY;
@@ -1033,10 +1031,10 @@ static int __init smc_probe(struct net_device *dev, int ioaddr)
        /*
         . Print the Ethernet address
        */
-       printk("ADDR: %s\n", print_mac(mac, dev->dev_addr));
+       printk("ADDR: %pM\n", dev->dev_addr);
 
        /* set the private data to zero by default */
-       memset(dev->priv, 0, sizeof(struct smc_local));
+       memset(netdev_priv(dev), 0, sizeof(struct smc_local));
 
        /* Grab the IRQ */
        retval = request_irq(dev->irq, &smc_interrupt, 0, DRV_NAME, dev);
@@ -1110,7 +1108,7 @@ static int smc_open(struct net_device *dev)
        int     i;      /* used to set hw ethernet address */
 
        /* clear out all the junk that was put here before... */
-       memset(dev->priv, 0, sizeof(struct smc_local));
+       memset(netdev_priv(dev), 0, sizeof(struct smc_local));
 
        /* reset the hardware */
 
@@ -1166,7 +1164,7 @@ static void smc_timeout(struct net_device *dev)
        smc_enable( dev->base_addr );
        dev->trans_start = jiffies;
        /* clear anything saved */
-       ((struct smc_local *)dev->priv)->saved_skb = NULL;
+       ((struct smc_local *)netdev_priv(dev))->saved_skb = NULL;
        netif_wake_queue(dev);
 }
 
@@ -1272,7 +1270,6 @@ static void smc_rcv(struct net_device *dev)
 
                skb->protocol = eth_type_trans(skb, dev );
                netif_rx(skb);
-               dev->last_rx = jiffies;
                dev->stats.rx_packets++;
                dev->stats.rx_bytes += packet_length;
        } else {
index fc80f250da31e8940bcc2d89d781de5eca66d7f2..5879c719b538cb50789e7c62d88e2af479347ec5 100644 (file)
@@ -518,7 +518,6 @@ static inline void  smc_rcv(struct net_device *dev)
 
                PRINT_PKT(data, packet_len - 4);
 
-               dev->last_rx = jiffies;
                skb->protocol = eth_type_trans(skb, dev);
                netif_rx(skb);
                dev->stats.rx_packets++;
@@ -1778,7 +1777,6 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
        int retval;
        unsigned int val, revision_register;
        const char *version_string;
-       DECLARE_MAC_BUF(mac);
 
        DBG(2, "%s: %s\n", CARDNAME, __func__);
 
@@ -1972,8 +1970,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
                               "set using ifconfig\n", dev->name);
                } else {
                        /* Print the Ethernet address */
-                       printk("%s: Ethernet addr: %s\n",
-                              dev->name, print_mac(mac, dev->dev_addr));
+                       printk("%s: Ethernet addr: %pM\n",
+                              dev->name, dev->dev_addr);
                }
 
                if (lp->phy_type == 0) {
@@ -2126,7 +2124,7 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device *
  *     0 --> there is a device
  *     anything else, error
  */
-static int smc_drv_probe(struct platform_device *pdev)
+static int __init smc_drv_probe(struct platform_device *pdev)
 {
        struct smc91x_platdata *pd = pdev->dev.platform_data;
        struct smc_local *lp;
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
new file mode 100644 (file)
index 0000000..fe51788
--- /dev/null
@@ -0,0 +1,2091 @@
+/***************************************************************************
+ *
+ * Copyright (C) 2004-2008 SMSC
+ * Copyright (C) 2005-2008 ARM
+ *
+ * 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 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ ***************************************************************************
+ * Rewritten, heavily based on smsc911x simple driver by SMSC.
+ * Partly uses io macros from smc91x.c by Nicolas Pitre
+ *
+ * Supported devices:
+ *   LAN9115, LAN9116, LAN9117, LAN9118
+ *   LAN9215, LAN9216, LAN9217, LAN9218
+ *   LAN9210, LAN9211
+ *   LAN9220, LAN9221
+ *
+ */
+
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/version.h>
+#include <linux/bug.h>
+#include <linux/bitops.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/phy.h>
+#include <linux/smsc911x.h>
+#include "smsc911x.h"
+
+#define SMSC_CHIPNAME          "smsc911x"
+#define SMSC_MDIONAME          "smsc911x-mdio"
+#define SMSC_DRV_VERSION       "2008-10-21"
+
+MODULE_LICENSE("GPL");
+MODULE_VERSION(SMSC_DRV_VERSION);
+
+#if USE_DEBUG > 0
+static int debug = 16;
+#else
+static int debug = 3;
+#endif
+
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+
+struct smsc911x_data {
+       void __iomem *ioaddr;
+
+       unsigned int idrev;
+
+       /* used to decide which workarounds apply */
+       unsigned int generation;
+
+       /* device configuration (copied from platform_data during probe) */
+       unsigned int irq_polarity;
+       unsigned int irq_type;
+       phy_interface_t phy_interface;
+
+       /* This needs to be acquired before calling any of below:
+        * smsc911x_mac_read(), smsc911x_mac_write()
+        */
+       spinlock_t mac_lock;
+
+#if (!SMSC_CAN_USE_32BIT)
+       /* spinlock to ensure 16-bit accesses are serialised */
+       spinlock_t dev_lock;
+#endif
+
+       struct phy_device *phy_dev;
+       struct mii_bus *mii_bus;
+       int phy_irq[PHY_MAX_ADDR];
+       unsigned int using_extphy;
+       int last_duplex;
+       int last_carrier;
+
+       u32 msg_enable;
+       unsigned int gpio_setting;
+       unsigned int gpio_orig_setting;
+       struct net_device *dev;
+       struct napi_struct napi;
+
+       unsigned int software_irq_signal;
+
+#ifdef USE_PHY_WORK_AROUND
+#define MIN_PACKET_SIZE (64)
+       char loopback_tx_pkt[MIN_PACKET_SIZE];
+       char loopback_rx_pkt[MIN_PACKET_SIZE];
+       unsigned int resetcount;
+#endif
+
+       /* Members for Multicast filter workaround */
+       unsigned int multicast_update_pending;
+       unsigned int set_bits_mask;
+       unsigned int clear_bits_mask;
+       unsigned int hashhi;
+       unsigned int hashlo;
+};
+
+#if SMSC_CAN_USE_32BIT
+
+static inline u32 smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg)
+{
+       return readl(pdata->ioaddr + reg);
+}
+
+static inline void smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg,
+                                     u32 val)
+{
+       writel(val, pdata->ioaddr + reg);
+}
+
+/* Writes a packet to the TX_DATA_FIFO */
+static inline void
+smsc911x_tx_writefifo(struct smsc911x_data *pdata, unsigned int *buf,
+                     unsigned int wordcount)
+{
+       writesl(pdata->ioaddr + TX_DATA_FIFO, buf, wordcount);
+}
+
+/* Reads a packet out of the RX_DATA_FIFO */
+static inline void
+smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf,
+                    unsigned int wordcount)
+{
+       readsl(pdata->ioaddr + RX_DATA_FIFO, buf, wordcount);
+}
+
+#else                          /* SMSC_CAN_USE_32BIT */
+
+/* These 16-bit access functions are significantly slower, due to the locking
+ * necessary.  If your bus hardware can be configured to do this for you
+ * (in response to a single 32-bit operation from software), you should use
+ * the 32-bit access functions instead. */
+
+static inline u32 smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg)
+{
+       unsigned long flags;
+       u32 data;
+
+       /* these two 16-bit reads must be performed consecutively, so must
+        * not be interrupted by our own ISR (which would start another
+        * read operation) */
+       spin_lock_irqsave(&pdata->dev_lock, flags);
+       data = ((readw(pdata->ioaddr + reg) & 0xFFFF) |
+               ((readw(pdata->ioaddr + reg + 2) & 0xFFFF) << 16));
+       spin_unlock_irqrestore(&pdata->dev_lock, flags);
+
+       return data;
+}
+
+static inline void smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg,
+                                     u32 val)
+{
+       unsigned long flags;
+
+       /* these two 16-bit writes must be performed consecutively, so must
+        * not be interrupted by our own ISR (which would start another
+        * read operation) */
+       spin_lock_irqsave(&pdata->dev_lock, flags);
+       writew(val & 0xFFFF, pdata->ioaddr + reg);
+       writew((val >> 16) & 0xFFFF, pdata->ioaddr + reg + 2);
+       spin_unlock_irqrestore(&pdata->dev_lock, flags);
+}
+
+/* Writes a packet to the TX_DATA_FIFO */
+static inline void
+smsc911x_tx_writefifo(struct smsc911x_data *pdata, unsigned int *buf,
+                     unsigned int wordcount)
+{
+       while (wordcount--)
+               smsc911x_reg_write(pdata, TX_DATA_FIFO, *buf++);
+}
+
+/* Reads a packet out of the RX_DATA_FIFO */
+static inline void
+smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf,
+                    unsigned int wordcount)
+{
+       while (wordcount--)
+               *buf++ = smsc911x_reg_read(pdata, RX_DATA_FIFO);
+}
+
+#endif                         /* SMSC_CAN_USE_32BIT */
+
+/* waits for MAC not busy, with timeout.  Only called by smsc911x_mac_read
+ * and smsc911x_mac_write, so assumes mac_lock is held */
+static int smsc911x_mac_complete(struct smsc911x_data *pdata)
+{
+       int i;
+       u32 val;
+
+       SMSC_ASSERT_MAC_LOCK(pdata);
+
+       for (i = 0; i < 40; i++) {
+               val = smsc911x_reg_read(pdata, MAC_CSR_CMD);
+               if (!(val & MAC_CSR_CMD_CSR_BUSY_))
+                       return 0;
+       }
+       SMSC_WARNING(HW, "Timed out waiting for MAC not BUSY. "
+               "MAC_CSR_CMD: 0x%08X", val);
+       return -EIO;
+}
+
+/* Fetches a MAC register value. Assumes mac_lock is acquired */
+static u32 smsc911x_mac_read(struct smsc911x_data *pdata, unsigned int offset)
+{
+       unsigned int temp;
+
+       SMSC_ASSERT_MAC_LOCK(pdata);
+
+       temp = smsc911x_reg_read(pdata, MAC_CSR_CMD);
+       if (unlikely(temp & MAC_CSR_CMD_CSR_BUSY_)) {
+               SMSC_WARNING(HW, "MAC busy at entry");
+               return 0xFFFFFFFF;
+       }
+
+       /* Send the MAC cmd */
+       smsc911x_reg_write(pdata, MAC_CSR_CMD, ((offset & 0xFF) |
+               MAC_CSR_CMD_CSR_BUSY_ | MAC_CSR_CMD_R_NOT_W_));
+
+       /* Workaround for hardware read-after-write restriction */
+       temp = smsc911x_reg_read(pdata, BYTE_TEST);
+
+       /* Wait for the read to complete */
+       if (likely(smsc911x_mac_complete(pdata) == 0))
+               return smsc911x_reg_read(pdata, MAC_CSR_DATA);
+
+       SMSC_WARNING(HW, "MAC busy after read");
+       return 0xFFFFFFFF;
+}
+
+/* Set a mac register, mac_lock must be acquired before calling */
+static void smsc911x_mac_write(struct smsc911x_data *pdata,
+                              unsigned int offset, u32 val)
+{
+       unsigned int temp;
+
+       SMSC_ASSERT_MAC_LOCK(pdata);
+
+       temp = smsc911x_reg_read(pdata, MAC_CSR_CMD);
+       if (unlikely(temp & MAC_CSR_CMD_CSR_BUSY_)) {
+               SMSC_WARNING(HW,
+                       "smsc911x_mac_write failed, MAC busy at entry");
+               return;
+       }
+
+       /* Send data to write */
+       smsc911x_reg_write(pdata, MAC_CSR_DATA, val);
+
+       /* Write the actual data */
+       smsc911x_reg_write(pdata, MAC_CSR_CMD, ((offset & 0xFF) |
+               MAC_CSR_CMD_CSR_BUSY_));
+
+       /* Workaround for hardware read-after-write restriction */
+       temp = smsc911x_reg_read(pdata, BYTE_TEST);
+
+       /* Wait for the write to complete */
+       if (likely(smsc911x_mac_complete(pdata) == 0))
+               return;
+
+       SMSC_WARNING(HW,
+               "smsc911x_mac_write failed, MAC busy after write");
+}
+
+/* Get a phy register */
+static int smsc911x_mii_read(struct mii_bus *bus, int phyaddr, int regidx)
+{
+       struct smsc911x_data *pdata = (struct smsc911x_data *)bus->priv;
+       unsigned long flags;
+       unsigned int addr;
+       int i, reg;
+
+       spin_lock_irqsave(&pdata->mac_lock, flags);
+
+       /* Confirm MII not busy */
+       if (unlikely(smsc911x_mac_read(pdata, MII_ACC) & MII_ACC_MII_BUSY_)) {
+               SMSC_WARNING(HW,
+                       "MII is busy in smsc911x_mii_read???");
+               reg = -EIO;
+               goto out;
+       }
+
+       /* Set the address, index & direction (read from PHY) */
+       addr = ((phyaddr & 0x1F) << 11) | ((regidx & 0x1F) << 6);
+       smsc911x_mac_write(pdata, MII_ACC, addr);
+
+       /* Wait for read to complete w/ timeout */
+       for (i = 0; i < 100; i++)
+               if (!(smsc911x_mac_read(pdata, MII_ACC) & MII_ACC_MII_BUSY_)) {
+                       reg = smsc911x_mac_read(pdata, MII_DATA);
+                       goto out;
+               }
+
+       SMSC_WARNING(HW, "Timed out waiting for MII write to finish");
+       reg = -EIO;
+
+out:
+       spin_unlock_irqrestore(&pdata->mac_lock, flags);
+       return reg;
+}
+
+/* Set a phy register */
+static int smsc911x_mii_write(struct mii_bus *bus, int phyaddr, int regidx,
+                          u16 val)
+{
+       struct smsc911x_data *pdata = (struct smsc911x_data *)bus->priv;
+       unsigned long flags;
+       unsigned int addr;
+       int i, reg;
+
+       spin_lock_irqsave(&pdata->mac_lock, flags);
+
+       /* Confirm MII not busy */
+       if (unlikely(smsc911x_mac_read(pdata, MII_ACC) & MII_ACC_MII_BUSY_)) {
+               SMSC_WARNING(HW,
+                       "MII is busy in smsc911x_mii_write???");
+               reg = -EIO;
+               goto out;
+       }
+
+       /* Put the data to write in the MAC */
+       smsc911x_mac_write(pdata, MII_DATA, val);
+
+       /* Set the address, index & direction (write to PHY) */
+       addr = ((phyaddr & 0x1F) << 11) | ((regidx & 0x1F) << 6) |
+               MII_ACC_MII_WRITE_;
+       smsc911x_mac_write(pdata, MII_ACC, addr);
+
+       /* Wait for write to complete w/ timeout */
+       for (i = 0; i < 100; i++)
+               if (!(smsc911x_mac_read(pdata, MII_ACC) & MII_ACC_MII_BUSY_)) {
+                       reg = 0;
+                       goto out;
+               }
+
+       SMSC_WARNING(HW, "Timed out waiting for MII write to finish");
+       reg = -EIO;
+
+out:
+       spin_unlock_irqrestore(&pdata->mac_lock, flags);
+       return reg;
+}
+
+/* Autodetects and initialises external phy for SMSC9115 and SMSC9117 flavors.
+ * If something goes wrong, returns -ENODEV to revert back to internal phy.
+ * Performed at initialisation only, so interrupts are enabled */
+static int smsc911x_phy_initialise_external(struct smsc911x_data *pdata)
+{
+       unsigned int hwcfg = smsc911x_reg_read(pdata, HW_CFG);
+
+       /* External phy is requested, supported, and detected */
+       if (hwcfg & HW_CFG_EXT_PHY_DET_) {
+
+               /* Switch to external phy. Assuming tx and rx are stopped
+                * because smsc911x_phy_initialise is called before
+                * smsc911x_rx_initialise and tx_initialise. */
+
+               /* Disable phy clocks to the MAC */
+               hwcfg &= (~HW_CFG_PHY_CLK_SEL_);
+               hwcfg |= HW_CFG_PHY_CLK_SEL_CLK_DIS_;
+               smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+               udelay(10);     /* Enough time for clocks to stop */
+
+               /* Switch to external phy */
+               hwcfg |= HW_CFG_EXT_PHY_EN_;
+               smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+
+               /* Enable phy clocks to the MAC */
+               hwcfg &= (~HW_CFG_PHY_CLK_SEL_);
+               hwcfg |= HW_CFG_PHY_CLK_SEL_EXT_PHY_;
+               smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+               udelay(10);     /* Enough time for clocks to restart */
+
+               hwcfg |= HW_CFG_SMI_SEL_;
+               smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+
+               SMSC_TRACE(HW, "Successfully switched to external PHY");
+               pdata->using_extphy = 1;
+       } else {
+               SMSC_WARNING(HW, "No external PHY detected, "
+                       "Using internal PHY instead.");
+               /* Use internal phy */
+               return -ENODEV;
+       }
+       return 0;
+}
+
+/* Fetches a tx status out of the status fifo */
+static unsigned int smsc911x_tx_get_txstatus(struct smsc911x_data *pdata)
+{
+       unsigned int result =
+           smsc911x_reg_read(pdata, TX_FIFO_INF) & TX_FIFO_INF_TSUSED_;
+
+       if (result != 0)
+               result = smsc911x_reg_read(pdata, TX_STATUS_FIFO);
+
+       return result;
+}
+
+/* Fetches the next rx status */
+static unsigned int smsc911x_rx_get_rxstatus(struct smsc911x_data *pdata)
+{
+       unsigned int result =
+           smsc911x_reg_read(pdata, RX_FIFO_INF) & RX_FIFO_INF_RXSUSED_;
+
+       if (result != 0)
+               result = smsc911x_reg_read(pdata, RX_STATUS_FIFO);
+
+       return result;
+}
+
+#ifdef USE_PHY_WORK_AROUND
+static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata)
+{
+       unsigned int tries;
+       u32 wrsz;
+       u32 rdsz;
+       ulong bufp;
+
+       for (tries = 0; tries < 10; tries++) {
+               unsigned int txcmd_a;
+               unsigned int txcmd_b;
+               unsigned int status;
+               unsigned int pktlength;
+               unsigned int i;
+
+               /* Zero-out rx packet memory */
+               memset(pdata->loopback_rx_pkt, 0, MIN_PACKET_SIZE);
+
+               /* Write tx packet to 118 */
+               txcmd_a = (u32)((ulong)pdata->loopback_tx_pkt & 0x03) << 16;
+               txcmd_a |= TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_;
+               txcmd_a |= MIN_PACKET_SIZE;
+
+               txcmd_b = MIN_PACKET_SIZE << 16 | MIN_PACKET_SIZE;
+
+               smsc911x_reg_write(pdata, TX_DATA_FIFO, txcmd_a);
+               smsc911x_reg_write(pdata, TX_DATA_FIFO, txcmd_b);
+
+               bufp = (ulong)pdata->loopback_tx_pkt & (~0x3);
+               wrsz = MIN_PACKET_SIZE + 3;
+               wrsz += (u32)((ulong)pdata->loopback_tx_pkt & 0x3);
+               wrsz >>= 2;
+
+               smsc911x_tx_writefifo(pdata, (unsigned int *)bufp, wrsz);
+
+               /* Wait till transmit is done */
+               i = 60;
+               do {
+                       udelay(5);
+                       status = smsc911x_tx_get_txstatus(pdata);
+               } while ((i--) && (!status));
+
+               if (!status) {
+                       SMSC_WARNING(HW, "Failed to transmit "
+                               "during loopback test");
+                       continue;
+               }
+               if (status & TX_STS_ES_) {
+                       SMSC_WARNING(HW, "Transmit encountered "
+                               "errors during loopback test");
+                       continue;
+               }
+
+               /* Wait till receive is done */
+               i = 60;
+               do {
+                       udelay(5);
+                       status = smsc911x_rx_get_rxstatus(pdata);
+               } while ((i--) && (!status));
+
+               if (!status) {
+                       SMSC_WARNING(HW,
+                               "Failed to receive during loopback test");
+                       continue;
+               }
+               if (status & RX_STS_ES_) {
+                       SMSC_WARNING(HW, "Receive encountered "
+                               "errors during loopback test");
+                       continue;
+               }
+
+               pktlength = ((status & 0x3FFF0000UL) >> 16);
+               bufp = (ulong)pdata->loopback_rx_pkt;
+               rdsz = pktlength + 3;
+               rdsz += (u32)((ulong)pdata->loopback_rx_pkt & 0x3);
+               rdsz >>= 2;
+
+               smsc911x_rx_readfifo(pdata, (unsigned int *)bufp, rdsz);
+
+               if (pktlength != (MIN_PACKET_SIZE + 4)) {
+                       SMSC_WARNING(HW, "Unexpected packet size "
+                               "during loop back test, size=%d, will retry",
+                               pktlength);
+               } else {
+                       unsigned int j;
+                       int mismatch = 0;
+                       for (j = 0; j < MIN_PACKET_SIZE; j++) {
+                               if (pdata->loopback_tx_pkt[j]
+                                   != pdata->loopback_rx_pkt[j]) {
+                                       mismatch = 1;
+                                       break;
+                               }
+                       }
+                       if (!mismatch) {
+                               SMSC_TRACE(HW, "Successfully verified "
+                                          "loopback packet");
+                               return 0;
+                       } else {
+                               SMSC_WARNING(HW, "Data mismatch "
+                                       "during loop back test, will retry");
+                       }
+               }
+       }
+
+       return -EIO;
+}
+
+static int smsc911x_phy_reset(struct smsc911x_data *pdata)
+{
+       struct phy_device *phy_dev = pdata->phy_dev;
+       unsigned int temp;
+       unsigned int i = 100000;
+
+       BUG_ON(!phy_dev);
+       BUG_ON(!phy_dev->bus);
+
+       SMSC_TRACE(HW, "Performing PHY BCR Reset");
+       smsc911x_mii_write(phy_dev->bus, phy_dev->addr, MII_BMCR, BMCR_RESET);
+       do {
+               msleep(1);
+               temp = smsc911x_mii_read(phy_dev->bus, phy_dev->addr,
+                       MII_BMCR);
+       } while ((i--) && (temp & BMCR_RESET));
+
+       if (temp & BMCR_RESET) {
+               SMSC_WARNING(HW, "PHY reset failed to complete.");
+               return -EIO;
+       }
+       /* Extra delay required because the phy may not be completed with
+       * its reset when BMCR_RESET is cleared. Specs say 256 uS is
+       * enough delay but using 1ms here to be safe */
+       msleep(1);
+
+       return 0;
+}
+
+static int smsc911x_phy_loopbacktest(struct net_device *dev)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       struct phy_device *phy_dev = pdata->phy_dev;
+       int result = -EIO;
+       unsigned int i, val;
+       unsigned long flags;
+
+       /* Initialise tx packet using broadcast destination address */
+       memset(pdata->loopback_tx_pkt, 0xff, ETH_ALEN);
+
+       /* Use incrementing source address */
+       for (i = 6; i < 12; i++)
+               pdata->loopback_tx_pkt[i] = (char)i;
+
+       /* Set length type field */
+       pdata->loopback_tx_pkt[12] = 0x00;
+       pdata->loopback_tx_pkt[13] = 0x00;
+
+       for (i = 14; i < MIN_PACKET_SIZE; i++)
+               pdata->loopback_tx_pkt[i] = (char)i;
+
+       val = smsc911x_reg_read(pdata, HW_CFG);
+       val &= HW_CFG_TX_FIF_SZ_;
+       val |= HW_CFG_SF_;
+       smsc911x_reg_write(pdata, HW_CFG, val);
+
+       smsc911x_reg_write(pdata, TX_CFG, TX_CFG_TX_ON_);
+       smsc911x_reg_write(pdata, RX_CFG,
+               (u32)((ulong)pdata->loopback_rx_pkt & 0x03) << 8);
+
+       for (i = 0; i < 10; i++) {
+               /* Set PHY to 10/FD, no ANEG, and loopback mode */
+               smsc911x_mii_write(phy_dev->bus, phy_dev->addr, MII_BMCR,
+                       BMCR_LOOPBACK | BMCR_FULLDPLX);
+
+               /* Enable MAC tx/rx, FD */
+               spin_lock_irqsave(&pdata->mac_lock, flags);
+               smsc911x_mac_write(pdata, MAC_CR, MAC_CR_FDPX_
+                                  | MAC_CR_TXEN_ | MAC_CR_RXEN_);
+               spin_unlock_irqrestore(&pdata->mac_lock, flags);
+
+               if (smsc911x_phy_check_loopbackpkt(pdata) == 0) {
+                       result = 0;
+                       break;
+               }
+               pdata->resetcount++;
+
+               /* Disable MAC rx */
+               spin_lock_irqsave(&pdata->mac_lock, flags);
+               smsc911x_mac_write(pdata, MAC_CR, 0);
+               spin_unlock_irqrestore(&pdata->mac_lock, flags);
+
+               smsc911x_phy_reset(pdata);
+       }
+
+       /* Disable MAC */
+       spin_lock_irqsave(&pdata->mac_lock, flags);
+       smsc911x_mac_write(pdata, MAC_CR, 0);
+       spin_unlock_irqrestore(&pdata->mac_lock, flags);
+
+       /* Cancel PHY loopback mode */
+       smsc911x_mii_write(phy_dev->bus, phy_dev->addr, MII_BMCR, 0);
+
+       smsc911x_reg_write(pdata, TX_CFG, 0);
+       smsc911x_reg_write(pdata, RX_CFG, 0);
+
+       return result;
+}
+#endif                         /* USE_PHY_WORK_AROUND */
+
+static u8 smsc95xx_resolve_flowctrl_fulldplx(u16 lcladv, u16 rmtadv)
+{
+       u8 cap = 0;
+
+       if (lcladv & ADVERTISE_PAUSE_CAP) {
+               if (lcladv & ADVERTISE_PAUSE_ASYM) {
+                       if (rmtadv & LPA_PAUSE_CAP)
+                               cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
+                       else if (rmtadv & LPA_PAUSE_ASYM)
+                               cap = FLOW_CTRL_RX;
+               } else {
+                       if (rmtadv & LPA_PAUSE_CAP)
+                               cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
+               }
+       } else if (lcladv & ADVERTISE_PAUSE_ASYM) {
+               if ((rmtadv & LPA_PAUSE_CAP) && (rmtadv & LPA_PAUSE_ASYM))
+                       cap = FLOW_CTRL_TX;
+       }
+
+       return cap;
+}
+
+static void smsc911x_phy_update_flowcontrol(struct smsc911x_data *pdata)
+{
+       struct phy_device *phy_dev = pdata->phy_dev;
+       u32 afc = smsc911x_reg_read(pdata, AFC_CFG);
+       u32 flow;
+       unsigned long flags;
+
+       if (phy_dev->duplex == DUPLEX_FULL) {
+               u16 lcladv = phy_read(phy_dev, MII_ADVERTISE);
+               u16 rmtadv = phy_read(phy_dev, MII_LPA);
+               u8 cap = smsc95xx_resolve_flowctrl_fulldplx(lcladv, rmtadv);
+
+               if (cap & FLOW_CTRL_RX)
+                       flow = 0xFFFF0002;
+               else
+                       flow = 0;
+
+               if (cap & FLOW_CTRL_TX)
+                       afc |= 0xF;
+               else
+                       afc &= ~0xF;
+
+               SMSC_TRACE(HW, "rx pause %s, tx pause %s",
+                       (cap & FLOW_CTRL_RX ? "enabled" : "disabled"),
+                       (cap & FLOW_CTRL_TX ? "enabled" : "disabled"));
+       } else {
+               SMSC_TRACE(HW, "half duplex");
+               flow = 0;
+               afc |= 0xF;
+       }
+
+       spin_lock_irqsave(&pdata->mac_lock, flags);
+       smsc911x_mac_write(pdata, FLOW, flow);
+       spin_unlock_irqrestore(&pdata->mac_lock, flags);
+
+       smsc911x_reg_write(pdata, AFC_CFG, afc);
+}
+
+/* Update link mode if anything has changed.  Called periodically when the
+ * PHY is in polling mode, even if nothing has changed. */
+static void smsc911x_phy_adjust_link(struct net_device *dev)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       struct phy_device *phy_dev = pdata->phy_dev;
+       unsigned long flags;
+       int carrier;
+
+       if (phy_dev->duplex != pdata->last_duplex) {
+               unsigned int mac_cr;
+               SMSC_TRACE(HW, "duplex state has changed");
+
+               spin_lock_irqsave(&pdata->mac_lock, flags);
+               mac_cr = smsc911x_mac_read(pdata, MAC_CR);
+               if (phy_dev->duplex) {
+                       SMSC_TRACE(HW,
+                               "configuring for full duplex mode");
+                       mac_cr |= MAC_CR_FDPX_;
+               } else {
+                       SMSC_TRACE(HW,
+                               "configuring for half duplex mode");
+                       mac_cr &= ~MAC_CR_FDPX_;
+               }
+               smsc911x_mac_write(pdata, MAC_CR, mac_cr);
+               spin_unlock_irqrestore(&pdata->mac_lock, flags);
+
+               smsc911x_phy_update_flowcontrol(pdata);
+               pdata->last_duplex = phy_dev->duplex;
+       }
+
+       carrier = netif_carrier_ok(dev);
+       if (carrier != pdata->last_carrier) {
+               SMSC_TRACE(HW, "carrier state has changed");
+               if (carrier) {
+                       SMSC_TRACE(HW, "configuring for carrier OK");
+                       if ((pdata->gpio_orig_setting & GPIO_CFG_LED1_EN_) &&
+                           (!pdata->using_extphy)) {
+                               /* Restore orginal GPIO configuration */
+                               pdata->gpio_setting = pdata->gpio_orig_setting;
+                               smsc911x_reg_write(pdata, GPIO_CFG,
+                                       pdata->gpio_setting);
+                       }
+               } else {
+                       SMSC_TRACE(HW, "configuring for no carrier");
+                       /* Check global setting that LED1
+                        * usage is 10/100 indicator */
+                       pdata->gpio_setting = smsc911x_reg_read(pdata,
+                               GPIO_CFG);
+                       if ((pdata->gpio_setting & GPIO_CFG_LED1_EN_)
+                           && (!pdata->using_extphy)) {
+                               /* Force 10/100 LED off, after saving
+                                * orginal GPIO configuration */
+                               pdata->gpio_orig_setting = pdata->gpio_setting;
+
+                               pdata->gpio_setting &= ~GPIO_CFG_LED1_EN_;
+                               pdata->gpio_setting |= (GPIO_CFG_GPIOBUF0_
+                                                       | GPIO_CFG_GPIODIR0_
+                                                       | GPIO_CFG_GPIOD0_);
+                               smsc911x_reg_write(pdata, GPIO_CFG,
+                                       pdata->gpio_setting);
+                       }
+               }
+               pdata->last_carrier = carrier;
+       }
+}
+
+static int smsc911x_mii_probe(struct net_device *dev)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       struct phy_device *phydev = NULL;
+       int phy_addr;
+
+       /* find the first phy */
+       for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+               if (pdata->mii_bus->phy_map[phy_addr]) {
+                       phydev = pdata->mii_bus->phy_map[phy_addr];
+                       SMSC_TRACE(PROBE, "PHY %d: addr %d, phy_id 0x%08X",
+                               phy_addr, phydev->addr, phydev->phy_id);
+                       break;
+               }
+       }
+
+       if (!phydev) {
+               pr_err("%s: no PHY found\n", dev->name);
+               return -ENODEV;
+       }
+
+       phydev = phy_connect(dev, phydev->dev.bus_id,
+               &smsc911x_phy_adjust_link, 0, pdata->phy_interface);
+
+       if (IS_ERR(phydev)) {
+               pr_err("%s: Could not attach to PHY\n", dev->name);
+               return PTR_ERR(phydev);
+       }
+
+       pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
+               dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+
+       /* mask with MAC supported features */
+       phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
+                             SUPPORTED_Asym_Pause);
+       phydev->advertising = phydev->supported;
+
+       pdata->phy_dev = phydev;
+       pdata->last_duplex = -1;
+       pdata->last_carrier = -1;
+
+#ifdef USE_PHY_WORK_AROUND
+       if (smsc911x_phy_loopbacktest(dev) < 0) {
+               SMSC_WARNING(HW, "Failed Loop Back Test");
+               return -ENODEV;
+       }
+       SMSC_TRACE(HW, "Passed Loop Back Test");
+#endif                         /* USE_PHY_WORK_AROUND */
+
+       SMSC_TRACE(HW, "phy initialised succesfully");
+       return 0;
+}
+
+static int __devinit smsc911x_mii_init(struct platform_device *pdev,
+                                      struct net_device *dev)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       int err = -ENXIO, i;
+
+       pdata->mii_bus = mdiobus_alloc();
+       if (!pdata->mii_bus) {
+               err = -ENOMEM;
+               goto err_out_1;
+       }
+
+       pdata->mii_bus->name = SMSC_MDIONAME;
+       snprintf(pdata->mii_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id);
+       pdata->mii_bus->priv = pdata;
+       pdata->mii_bus->read = smsc911x_mii_read;
+       pdata->mii_bus->write = smsc911x_mii_write;
+       pdata->mii_bus->irq = pdata->phy_irq;
+       for (i = 0; i < PHY_MAX_ADDR; ++i)
+               pdata->mii_bus->irq[i] = PHY_POLL;
+
+       pdata->mii_bus->parent = &pdev->dev;
+       dev_set_drvdata(&pdev->dev, &pdata->mii_bus);
+
+       pdata->using_extphy = 0;
+
+       switch (pdata->idrev & 0xFFFF0000) {
+       case 0x01170000:
+       case 0x01150000:
+       case 0x117A0000:
+       case 0x115A0000:
+               /* External PHY supported, try to autodetect */
+               if (smsc911x_phy_initialise_external(pdata) < 0) {
+                       SMSC_TRACE(HW, "No external PHY detected, "
+                               "using internal PHY");
+               }
+               break;
+       default:
+               SMSC_TRACE(HW, "External PHY is not supported, "
+                       "using internal PHY");
+               break;
+       }
+
+       if (!pdata->using_extphy) {
+               /* Mask all PHYs except ID 1 (internal) */
+               pdata->mii_bus->phy_mask = ~(1 << 1);
+       }
+
+       if (mdiobus_register(pdata->mii_bus)) {
+               SMSC_WARNING(PROBE, "Error registering mii bus");
+               goto err_out_free_bus_2;
+       }
+
+       if (smsc911x_mii_probe(dev) < 0) {
+               SMSC_WARNING(PROBE, "Error registering mii bus");
+               goto err_out_unregister_bus_3;
+       }
+
+       return 0;
+
+err_out_unregister_bus_3:
+       mdiobus_unregister(pdata->mii_bus);
+err_out_free_bus_2:
+       mdiobus_free(pdata->mii_bus);
+err_out_1:
+       return err;
+}
+
+/* Gets the number of tx statuses in the fifo */
+static unsigned int smsc911x_tx_get_txstatcount(struct smsc911x_data *pdata)
+{
+       return (smsc911x_reg_read(pdata, TX_FIFO_INF)
+               & TX_FIFO_INF_TSUSED_) >> 16;
+}
+
+/* Reads tx statuses and increments counters where necessary */
+static void smsc911x_tx_update_txcounters(struct net_device *dev)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       unsigned int tx_stat;
+
+       while ((tx_stat = smsc911x_tx_get_txstatus(pdata)) != 0) {
+               if (unlikely(tx_stat & 0x80000000)) {
+                       /* In this driver the packet tag is used as the packet
+                        * length. Since a packet length can never reach the
+                        * size of 0x8000, this bit is reserved. It is worth
+                        * noting that the "reserved bit" in the warning above
+                        * does not reference a hardware defined reserved bit
+                        * but rather a driver defined one.
+                        */
+                       SMSC_WARNING(HW,
+                               "Packet tag reserved bit is high");
+               } else {
+                       if (unlikely(tx_stat & 0x00008000)) {
+                               dev->stats.tx_errors++;
+                       } else {
+                               dev->stats.tx_packets++;
+                               dev->stats.tx_bytes += (tx_stat >> 16);
+                       }
+                       if (unlikely(tx_stat & 0x00000100)) {
+                               dev->stats.collisions += 16;
+                               dev->stats.tx_aborted_errors += 1;
+                       } else {
+                               dev->stats.collisions +=
+                                   ((tx_stat >> 3) & 0xF);
+                       }
+                       if (unlikely(tx_stat & 0x00000800))
+                               dev->stats.tx_carrier_errors += 1;
+                       if (unlikely(tx_stat & 0x00000200)) {
+                               dev->stats.collisions++;
+                               dev->stats.tx_aborted_errors++;
+                       }
+               }
+       }
+}
+
+/* Increments the Rx error counters */
+static void
+smsc911x_rx_counterrors(struct net_device *dev, unsigned int rxstat)
+{
+       int crc_err = 0;
+
+       if (unlikely(rxstat & 0x00008000)) {
+               dev->stats.rx_errors++;
+               if (unlikely(rxstat & 0x00000002)) {
+                       dev->stats.rx_crc_errors++;
+                       crc_err = 1;
+               }
+       }
+       if (likely(!crc_err)) {
+               if (unlikely((rxstat & 0x00001020) == 0x00001020)) {
+                       /* Frame type indicates length,
+                        * and length error is set */
+                       dev->stats.rx_length_errors++;
+               }
+               if (rxstat & RX_STS_MCAST_)
+                       dev->stats.multicast++;
+       }
+}
+
+/* Quickly dumps bad packets */
+static void
+smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes)
+{
+       unsigned int pktwords = (pktbytes + NET_IP_ALIGN + 3) >> 2;
+
+       if (likely(pktwords >= 4)) {
+               unsigned int timeout = 500;
+               unsigned int val;
+               smsc911x_reg_write(pdata, RX_DP_CTRL, RX_DP_CTRL_RX_FFWD_);
+               do {
+                       udelay(1);
+                       val = smsc911x_reg_read(pdata, RX_DP_CTRL);
+               } while (timeout-- && (val & RX_DP_CTRL_RX_FFWD_));
+
+               if (unlikely(timeout == 0))
+                       SMSC_WARNING(HW, "Timed out waiting for "
+                               "RX FFWD to finish, RX_DP_CTRL: 0x%08X", val);
+       } else {
+               unsigned int temp;
+               while (pktwords--)
+                       temp = smsc911x_reg_read(pdata, RX_DATA_FIFO);
+       }
+}
+
+/* NAPI poll function */
+static int smsc911x_poll(struct napi_struct *napi, int budget)
+{
+       struct smsc911x_data *pdata =
+               container_of(napi, struct smsc911x_data, napi);
+       struct net_device *dev = pdata->dev;
+       int npackets = 0;
+
+       while (likely(netif_running(dev)) && (npackets < budget)) {
+               unsigned int pktlength;
+               unsigned int pktwords;
+               struct sk_buff *skb;
+               unsigned int rxstat = smsc911x_rx_get_rxstatus(pdata);
+
+               if (!rxstat) {
+                       unsigned int temp;
+                       /* We processed all packets available.  Tell NAPI it can
+                        * stop polling then re-enable rx interrupts */
+                       smsc911x_reg_write(pdata, INT_STS, INT_STS_RSFL_);
+                       netif_rx_complete(dev, napi);
+                       temp = smsc911x_reg_read(pdata, INT_EN);
+                       temp |= INT_EN_RSFL_EN_;
+                       smsc911x_reg_write(pdata, INT_EN, temp);
+                       break;
+               }
+
+               /* Count packet for NAPI scheduling, even if it has an error.
+                * Error packets still require cycles to discard */
+               npackets++;
+
+               pktlength = ((rxstat & 0x3FFF0000) >> 16);
+               pktwords = (pktlength + NET_IP_ALIGN + 3) >> 2;
+               smsc911x_rx_counterrors(dev, rxstat);
+
+               if (unlikely(rxstat & RX_STS_ES_)) {
+                       SMSC_WARNING(RX_ERR,
+                               "Discarding packet with error bit set");
+                       /* Packet has an error, discard it and continue with
+                        * the next */
+                       smsc911x_rx_fastforward(pdata, pktwords);
+                       dev->stats.rx_dropped++;
+                       continue;
+               }
+
+               skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN);
+               if (unlikely(!skb)) {
+                       SMSC_WARNING(RX_ERR,
+                               "Unable to allocate skb for rx packet");
+                       /* Drop the packet and stop this polling iteration */
+                       smsc911x_rx_fastforward(pdata, pktwords);
+                       dev->stats.rx_dropped++;
+                       break;
+               }
+
+               skb->data = skb->head;
+               skb_reset_tail_pointer(skb);
+
+               /* Align IP on 16B boundary */
+               skb_reserve(skb, NET_IP_ALIGN);
+               skb_put(skb, pktlength - 4);
+               smsc911x_rx_readfifo(pdata, (unsigned int *)skb->head,
+                                    pktwords);
+               skb->protocol = eth_type_trans(skb, dev);
+               skb->ip_summed = CHECKSUM_NONE;
+               netif_receive_skb(skb);
+
+               /* Update counters */
+               dev->stats.rx_packets++;
+               dev->stats.rx_bytes += (pktlength - 4);
+               dev->last_rx = jiffies;
+       }
+
+       /* Return total received packets */
+       return npackets;
+}
+
+/* Returns hash bit number for given MAC address
+ * Example:
+ * 01 00 5E 00 00 01 -> returns bit number 31 */
+static unsigned int smsc911x_hash(char addr[ETH_ALEN])
+{
+       return (ether_crc(ETH_ALEN, addr) >> 26) & 0x3f;
+}
+
+static void smsc911x_rx_multicast_update(struct smsc911x_data *pdata)
+{
+       /* Performs the multicast & mac_cr update.  This is called when
+        * safe on the current hardware, and with the mac_lock held */
+       unsigned int mac_cr;
+
+       SMSC_ASSERT_MAC_LOCK(pdata);
+
+       mac_cr = smsc911x_mac_read(pdata, MAC_CR);
+       mac_cr |= pdata->set_bits_mask;
+       mac_cr &= ~(pdata->clear_bits_mask);
+       smsc911x_mac_write(pdata, MAC_CR, mac_cr);
+       smsc911x_mac_write(pdata, HASHH, pdata->hashhi);
+       smsc911x_mac_write(pdata, HASHL, pdata->hashlo);
+       SMSC_TRACE(HW, "maccr 0x%08X, HASHH 0x%08X, HASHL 0x%08X",
+               mac_cr, pdata->hashhi, pdata->hashlo);
+}
+
+static void smsc911x_rx_multicast_update_workaround(struct smsc911x_data *pdata)
+{
+       unsigned int mac_cr;
+
+       /* This function is only called for older LAN911x devices
+        * (revA or revB), where MAC_CR, HASHH and HASHL should not
+        * be modified during Rx - newer devices immediately update the
+        * registers.
+        *
+        * This is called from interrupt context */
+
+       spin_lock(&pdata->mac_lock);
+
+       /* Check Rx has stopped */
+       if (smsc911x_mac_read(pdata, MAC_CR) & MAC_CR_RXEN_)
+               SMSC_WARNING(DRV, "Rx not stopped");
+
+       /* Perform the update - safe to do now Rx has stopped */
+       smsc911x_rx_multicast_update(pdata);
+
+       /* Re-enable Rx */
+       mac_cr = smsc911x_mac_read(pdata, MAC_CR);
+       mac_cr |= MAC_CR_RXEN_;
+       smsc911x_mac_write(pdata, MAC_CR, mac_cr);
+
+       pdata->multicast_update_pending = 0;
+
+       spin_unlock(&pdata->mac_lock);
+}
+
+static int smsc911x_soft_reset(struct smsc911x_data *pdata)
+{
+       unsigned int timeout;
+       unsigned int temp;
+
+       /* Reset the LAN911x */
+       smsc911x_reg_write(pdata, HW_CFG, HW_CFG_SRST_);
+       timeout = 10;
+       do {
+               udelay(10);
+               temp = smsc911x_reg_read(pdata, HW_CFG);
+       } while ((--timeout) && (temp & HW_CFG_SRST_));
+
+       if (unlikely(temp & HW_CFG_SRST_)) {
+               SMSC_WARNING(DRV, "Failed to complete reset");
+               return -EIO;
+       }
+       return 0;
+}
+
+/* Sets the device MAC address to dev_addr, called with mac_lock held */
+static void
+smsc911x_set_mac_address(struct smsc911x_data *pdata, u8 dev_addr[6])
+{
+       u32 mac_high16 = (dev_addr[5] << 8) | dev_addr[4];
+       u32 mac_low32 = (dev_addr[3] << 24) | (dev_addr[2] << 16) |
+           (dev_addr[1] << 8) | dev_addr[0];
+
+       SMSC_ASSERT_MAC_LOCK(pdata);
+
+       smsc911x_mac_write(pdata, ADDRH, mac_high16);
+       smsc911x_mac_write(pdata, ADDRL, mac_low32);
+}
+
+static int smsc911x_open(struct net_device *dev)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       unsigned int timeout;
+       unsigned int temp;
+       unsigned int intcfg;
+
+       /* if the phy is not yet registered, retry later*/
+       if (!pdata->phy_dev) {
+               SMSC_WARNING(HW, "phy_dev is NULL");
+               return -EAGAIN;
+       }
+
+       if (!is_valid_ether_addr(dev->dev_addr)) {
+               SMSC_WARNING(HW, "dev_addr is not a valid MAC address");
+               return -EADDRNOTAVAIL;
+       }
+
+       /* Reset the LAN911x */
+       if (smsc911x_soft_reset(pdata)) {
+               SMSC_WARNING(HW, "soft reset failed");
+               return -EIO;
+       }
+
+       smsc911x_reg_write(pdata, HW_CFG, 0x00050000);
+       smsc911x_reg_write(pdata, AFC_CFG, 0x006E3740);
+
+       /* Make sure EEPROM has finished loading before setting GPIO_CFG */
+       timeout = 50;
+       while ((timeout--) &&
+              (smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_)) {
+               udelay(10);
+       }
+
+       if (unlikely(timeout == 0))
+               SMSC_WARNING(IFUP,
+                       "Timed out waiting for EEPROM busy bit to clear");
+
+       smsc911x_reg_write(pdata, GPIO_CFG, 0x70070000);
+
+       /* The soft reset above cleared the device's MAC address,
+        * restore it from local copy (set in probe) */
+       spin_lock_irq(&pdata->mac_lock);
+       smsc911x_set_mac_address(pdata, dev->dev_addr);
+       spin_unlock_irq(&pdata->mac_lock);
+
+       /* Initialise irqs, but leave all sources disabled */
+       smsc911x_reg_write(pdata, INT_EN, 0);
+       smsc911x_reg_write(pdata, INT_STS, 0xFFFFFFFF);
+
+       /* Set interrupt deassertion to 100uS */
+       intcfg = ((10 << 24) | INT_CFG_IRQ_EN_);
+
+       if (pdata->irq_polarity) {
+               SMSC_TRACE(IFUP, "irq polarity: active high");
+               intcfg |= INT_CFG_IRQ_POL_;
+       } else {
+               SMSC_TRACE(IFUP, "irq polarity: active low");
+       }
+
+       if (pdata->irq_type) {
+               SMSC_TRACE(IFUP, "irq type: push-pull");
+               intcfg |= INT_CFG_IRQ_TYPE_;
+       } else {
+               SMSC_TRACE(IFUP, "irq type: open drain");
+       }
+
+       smsc911x_reg_write(pdata, INT_CFG, intcfg);
+
+       SMSC_TRACE(IFUP, "Testing irq handler using IRQ %d", dev->irq);
+       pdata->software_irq_signal = 0;
+       smp_wmb();
+
+       temp = smsc911x_reg_read(pdata, INT_EN);
+       temp |= INT_EN_SW_INT_EN_;
+       smsc911x_reg_write(pdata, INT_EN, temp);
+
+       timeout = 1000;
+       while (timeout--) {
+               if (pdata->software_irq_signal)
+                       break;
+               msleep(1);
+       }
+
+       if (!pdata->software_irq_signal) {
+               dev_warn(&dev->dev, "ISR failed signaling test (IRQ %d)\n",
+                        dev->irq);
+               return -ENODEV;
+       }
+       SMSC_TRACE(IFUP, "IRQ handler passed test using IRQ %d", dev->irq);
+
+       dev_info(&dev->dev, "SMSC911x/921x identified at %#08lx, IRQ: %d\n",
+                (unsigned long)pdata->ioaddr, dev->irq);
+
+       /* Bring the PHY up */
+       phy_start(pdata->phy_dev);
+
+       temp = smsc911x_reg_read(pdata, HW_CFG);
+       /* Preserve TX FIFO size and external PHY configuration */
+       temp &= (HW_CFG_TX_FIF_SZ_|0x00000FFF);
+       temp |= HW_CFG_SF_;
+       smsc911x_reg_write(pdata, HW_CFG, temp);
+
+       temp = smsc911x_reg_read(pdata, FIFO_INT);
+       temp |= FIFO_INT_TX_AVAIL_LEVEL_;
+       temp &= ~(FIFO_INT_RX_STS_LEVEL_);
+       smsc911x_reg_write(pdata, FIFO_INT, temp);
+
+       /* set RX Data offset to 2 bytes for alignment */
+       smsc911x_reg_write(pdata, RX_CFG, (2 << 8));
+
+       /* enable NAPI polling before enabling RX interrupts */
+       napi_enable(&pdata->napi);
+
+       temp = smsc911x_reg_read(pdata, INT_EN);
+       temp |= (INT_EN_TDFA_EN_ | INT_EN_RSFL_EN_);
+       smsc911x_reg_write(pdata, INT_EN, temp);
+
+       spin_lock_irq(&pdata->mac_lock);
+       temp = smsc911x_mac_read(pdata, MAC_CR);
+       temp |= (MAC_CR_TXEN_ | MAC_CR_RXEN_ | MAC_CR_HBDIS_);
+       smsc911x_mac_write(pdata, MAC_CR, temp);
+       spin_unlock_irq(&pdata->mac_lock);
+
+       smsc911x_reg_write(pdata, TX_CFG, TX_CFG_TX_ON_);
+
+       netif_start_queue(dev);
+       return 0;
+}
+
+/* Entry point for stopping the interface */
+static int smsc911x_stop(struct net_device *dev)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       unsigned int temp;
+
+       BUG_ON(!pdata->phy_dev);
+
+       /* Disable all device interrupts */
+       temp = smsc911x_reg_read(pdata, INT_CFG);
+       temp &= ~INT_CFG_IRQ_EN_;
+       smsc911x_reg_write(pdata, INT_CFG, temp);
+
+       /* Stop Tx and Rx polling */
+       netif_stop_queue(dev);
+       napi_disable(&pdata->napi);
+
+       /* At this point all Rx and Tx activity is stopped */
+       dev->stats.rx_dropped += smsc911x_reg_read(pdata, RX_DROP);
+       smsc911x_tx_update_txcounters(dev);
+
+       /* Bring the PHY down */
+       phy_stop(pdata->phy_dev);
+
+       SMSC_TRACE(IFDOWN, "Interface stopped");
+       return 0;
+}
+
+/* Entry point for transmitting a packet */
+static int smsc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       unsigned int freespace;
+       unsigned int tx_cmd_a;
+       unsigned int tx_cmd_b;
+       unsigned int temp;
+       u32 wrsz;
+       ulong bufp;
+
+       freespace = smsc911x_reg_read(pdata, TX_FIFO_INF) & TX_FIFO_INF_TDFREE_;
+
+       if (unlikely(freespace < TX_FIFO_LOW_THRESHOLD))
+               SMSC_WARNING(TX_ERR,
+                       "Tx data fifo low, space available: %d", freespace);
+
+       /* Word alignment adjustment */
+       tx_cmd_a = (u32)((ulong)skb->data & 0x03) << 16;
+       tx_cmd_a |= TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_;
+       tx_cmd_a |= (unsigned int)skb->len;
+
+       tx_cmd_b = ((unsigned int)skb->len) << 16;
+       tx_cmd_b |= (unsigned int)skb->len;
+
+       smsc911x_reg_write(pdata, TX_DATA_FIFO, tx_cmd_a);
+       smsc911x_reg_write(pdata, TX_DATA_FIFO, tx_cmd_b);
+
+       bufp = (ulong)skb->data & (~0x3);
+       wrsz = (u32)skb->len + 3;
+       wrsz += (u32)((ulong)skb->data & 0x3);
+       wrsz >>= 2;
+
+       smsc911x_tx_writefifo(pdata, (unsigned int *)bufp, wrsz);
+       freespace -= (skb->len + 32);
+       dev_kfree_skb(skb);
+       dev->trans_start = jiffies;
+
+       if (unlikely(smsc911x_tx_get_txstatcount(pdata) >= 30))
+               smsc911x_tx_update_txcounters(dev);
+
+       if (freespace < TX_FIFO_LOW_THRESHOLD) {
+               netif_stop_queue(dev);
+               temp = smsc911x_reg_read(pdata, FIFO_INT);
+               temp &= 0x00FFFFFF;
+               temp |= 0x32000000;
+               smsc911x_reg_write(pdata, FIFO_INT, temp);
+       }
+
+       return NETDEV_TX_OK;
+}
+
+/* Entry point for getting status counters */
+static struct net_device_stats *smsc911x_get_stats(struct net_device *dev)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       smsc911x_tx_update_txcounters(dev);
+       dev->stats.rx_dropped += smsc911x_reg_read(pdata, RX_DROP);
+       return &dev->stats;
+}
+
+/* Entry point for setting addressing modes */
+static void smsc911x_set_multicast_list(struct net_device *dev)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       unsigned long flags;
+
+       if (dev->flags & IFF_PROMISC) {
+               /* Enabling promiscuous mode */
+               pdata->set_bits_mask = MAC_CR_PRMS_;
+               pdata->clear_bits_mask = (MAC_CR_MCPAS_ | MAC_CR_HPFILT_);
+               pdata->hashhi = 0;
+               pdata->hashlo = 0;
+       } else if (dev->flags & IFF_ALLMULTI) {
+               /* Enabling all multicast mode */
+               pdata->set_bits_mask = MAC_CR_MCPAS_;
+               pdata->clear_bits_mask = (MAC_CR_PRMS_ | MAC_CR_HPFILT_);
+               pdata->hashhi = 0;
+               pdata->hashlo = 0;
+       } else if (dev->mc_count > 0) {
+               /* Enabling specific multicast addresses */
+               unsigned int hash_high = 0;
+               unsigned int hash_low = 0;
+               unsigned int count = 0;
+               struct dev_mc_list *mc_list = dev->mc_list;
+
+               pdata->set_bits_mask = MAC_CR_HPFILT_;
+               pdata->clear_bits_mask = (MAC_CR_PRMS_ | MAC_CR_MCPAS_);
+
+               while (mc_list) {
+                       count++;
+                       if ((mc_list->dmi_addrlen) == ETH_ALEN) {
+                               unsigned int bitnum =
+                                   smsc911x_hash(mc_list->dmi_addr);
+                               unsigned int mask = 0x01 << (bitnum & 0x1F);
+                               if (bitnum & 0x20)
+                                       hash_high |= mask;
+                               else
+                                       hash_low |= mask;
+                       } else {
+                               SMSC_WARNING(DRV, "dmi_addrlen != 6");
+                       }
+                       mc_list = mc_list->next;
+               }
+               if (count != (unsigned int)dev->mc_count)
+                       SMSC_WARNING(DRV, "mc_count != dev->mc_count");
+
+               pdata->hashhi = hash_high;
+               pdata->hashlo = hash_low;
+       } else {
+               /* Enabling local MAC address only */
+               pdata->set_bits_mask = 0;
+               pdata->clear_bits_mask =
+                   (MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_);
+               pdata->hashhi = 0;
+               pdata->hashlo = 0;
+       }
+
+       spin_lock_irqsave(&pdata->mac_lock, flags);
+
+       if (pdata->generation <= 1) {
+               /* Older hardware revision - cannot change these flags while
+                * receiving data */
+               if (!pdata->multicast_update_pending) {
+                       unsigned int temp;
+                       SMSC_TRACE(HW, "scheduling mcast update");
+                       pdata->multicast_update_pending = 1;
+
+                       /* Request the hardware to stop, then perform the
+                        * update when we get an RX_STOP interrupt */
+                       smsc911x_reg_write(pdata, INT_STS, INT_STS_RXSTOP_INT_);
+                       temp = smsc911x_reg_read(pdata, INT_EN);
+                       temp |= INT_EN_RXSTOP_INT_EN_;
+                       smsc911x_reg_write(pdata, INT_EN, temp);
+
+                       temp = smsc911x_mac_read(pdata, MAC_CR);
+                       temp &= ~(MAC_CR_RXEN_);
+                       smsc911x_mac_write(pdata, MAC_CR, temp);
+               } else {
+                       /* There is another update pending, this should now
+                        * use the newer values */
+               }
+       } else {
+               /* Newer hardware revision - can write immediately */
+               smsc911x_rx_multicast_update(pdata);
+       }
+
+       spin_unlock_irqrestore(&pdata->mac_lock, flags);
+}
+
+static irqreturn_t smsc911x_irqhandler(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       u32 intsts = smsc911x_reg_read(pdata, INT_STS);
+       u32 inten = smsc911x_reg_read(pdata, INT_EN);
+       int serviced = IRQ_NONE;
+       u32 temp;
+
+       if (unlikely(intsts & inten & INT_STS_SW_INT_)) {
+               temp = smsc911x_reg_read(pdata, INT_EN);
+               temp &= (~INT_EN_SW_INT_EN_);
+               smsc911x_reg_write(pdata, INT_EN, temp);
+               smsc911x_reg_write(pdata, INT_STS, INT_STS_SW_INT_);
+               pdata->software_irq_signal = 1;
+               smp_wmb();
+               serviced = IRQ_HANDLED;
+       }
+
+       if (unlikely(intsts & inten & INT_STS_RXSTOP_INT_)) {
+               /* Called when there is a multicast update scheduled and
+                * it is now safe to complete the update */
+               SMSC_TRACE(INTR, "RX Stop interrupt");
+               temp = smsc911x_reg_read(pdata, INT_EN);
+               temp &= (~INT_EN_RXSTOP_INT_EN_);
+               smsc911x_reg_write(pdata, INT_EN, temp);
+               smsc911x_reg_write(pdata, INT_STS, INT_STS_RXSTOP_INT_);
+               smsc911x_rx_multicast_update_workaround(pdata);
+               serviced = IRQ_HANDLED;
+       }
+
+       if (intsts & inten & INT_STS_TDFA_) {
+               temp = smsc911x_reg_read(pdata, FIFO_INT);
+               temp |= FIFO_INT_TX_AVAIL_LEVEL_;
+               smsc911x_reg_write(pdata, FIFO_INT, temp);
+               smsc911x_reg_write(pdata, INT_STS, INT_STS_TDFA_);
+               netif_wake_queue(dev);
+               serviced = IRQ_HANDLED;
+       }
+
+       if (unlikely(intsts & inten & INT_STS_RXE_)) {
+               SMSC_TRACE(INTR, "RX Error interrupt");
+               smsc911x_reg_write(pdata, INT_STS, INT_STS_RXE_);
+               serviced = IRQ_HANDLED;
+       }
+
+       if (likely(intsts & inten & INT_STS_RSFL_)) {
+               if (likely(netif_rx_schedule_prep(dev, &pdata->napi))) {
+                       /* Disable Rx interrupts */
+                       temp = smsc911x_reg_read(pdata, INT_EN);
+                       temp &= (~INT_EN_RSFL_EN_);
+                       smsc911x_reg_write(pdata, INT_EN, temp);
+                       /* Schedule a NAPI poll */
+                       __netif_rx_schedule(dev, &pdata->napi);
+               } else {
+                       SMSC_WARNING(RX_ERR,
+                               "netif_rx_schedule_prep failed");
+               }
+               serviced = IRQ_HANDLED;
+       }
+
+       return serviced;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+void smsc911x_poll_controller(struct net_device *dev)
+{
+       disable_irq(dev->irq);
+       smsc911x_irqhandler(0, dev);
+       enable_irq(dev->irq);
+}
+#endif                         /* CONFIG_NET_POLL_CONTROLLER */
+
+/* Standard ioctls for mii-tool */
+static int smsc911x_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+
+       if (!netif_running(dev) || !pdata->phy_dev)
+               return -EINVAL;
+
+       return phy_mii_ioctl(pdata->phy_dev, if_mii(ifr), cmd);
+}
+
+static int
+smsc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+
+       cmd->maxtxpkt = 1;
+       cmd->maxrxpkt = 1;
+       return phy_ethtool_gset(pdata->phy_dev, cmd);
+}
+
+static int
+smsc911x_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+
+       return phy_ethtool_sset(pdata->phy_dev, cmd);
+}
+
+static void smsc911x_ethtool_getdrvinfo(struct net_device *dev,
+                                       struct ethtool_drvinfo *info)
+{
+       strlcpy(info->driver, SMSC_CHIPNAME, sizeof(info->driver));
+       strlcpy(info->version, SMSC_DRV_VERSION, sizeof(info->version));
+       strlcpy(info->bus_info, dev->dev.parent->bus_id,
+               sizeof(info->bus_info));
+}
+
+static int smsc911x_ethtool_nwayreset(struct net_device *dev)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+
+       return phy_start_aneg(pdata->phy_dev);
+}
+
+static u32 smsc911x_ethtool_getmsglevel(struct net_device *dev)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       return pdata->msg_enable;
+}
+
+static void smsc911x_ethtool_setmsglevel(struct net_device *dev, u32 level)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       pdata->msg_enable = level;
+}
+
+static int smsc911x_ethtool_getregslen(struct net_device *dev)
+{
+       return (((E2P_DATA - ID_REV) / 4 + 1) + (WUCSR - MAC_CR) + 1 + 32) *
+           sizeof(u32);
+}
+
+static void
+smsc911x_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs,
+                        void *buf)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       struct phy_device *phy_dev = pdata->phy_dev;
+       unsigned long flags;
+       unsigned int i;
+       unsigned int j = 0;
+       u32 *data = buf;
+
+       regs->version = pdata->idrev;
+       for (i = ID_REV; i <= E2P_DATA; i += (sizeof(u32)))
+               data[j++] = smsc911x_reg_read(pdata, i);
+
+       for (i = MAC_CR; i <= WUCSR; i++) {
+               spin_lock_irqsave(&pdata->mac_lock, flags);
+               data[j++] = smsc911x_mac_read(pdata, i);
+               spin_unlock_irqrestore(&pdata->mac_lock, flags);
+       }
+
+       for (i = 0; i <= 31; i++)
+               data[j++] = smsc911x_mii_read(phy_dev->bus, phy_dev->addr, i);
+}
+
+static void smsc911x_eeprom_enable_access(struct smsc911x_data *pdata)
+{
+       unsigned int temp = smsc911x_reg_read(pdata, GPIO_CFG);
+       temp &= ~GPIO_CFG_EEPR_EN_;
+       smsc911x_reg_write(pdata, GPIO_CFG, temp);
+       msleep(1);
+}
+
+static int smsc911x_eeprom_send_cmd(struct smsc911x_data *pdata, u32 op)
+{
+       int timeout = 100;
+       u32 e2cmd;
+
+       SMSC_TRACE(DRV, "op 0x%08x", op);
+       if (smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_) {
+               SMSC_WARNING(DRV, "Busy at start");
+               return -EBUSY;
+       }
+
+       e2cmd = op | E2P_CMD_EPC_BUSY_;
+       smsc911x_reg_write(pdata, E2P_CMD, e2cmd);
+
+       do {
+               msleep(1);
+               e2cmd = smsc911x_reg_read(pdata, E2P_CMD);
+       } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (timeout--));
+
+       if (!timeout) {
+               SMSC_TRACE(DRV, "TIMED OUT");
+               return -EAGAIN;
+       }
+
+       if (e2cmd & E2P_CMD_EPC_TIMEOUT_) {
+               SMSC_TRACE(DRV, "Error occured during eeprom operation");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int smsc911x_eeprom_read_location(struct smsc911x_data *pdata,
+                                        u8 address, u8 *data)
+{
+       u32 op = E2P_CMD_EPC_CMD_READ_ | address;
+       int ret;
+
+       SMSC_TRACE(DRV, "address 0x%x", address);
+       ret = smsc911x_eeprom_send_cmd(pdata, op);
+
+       if (!ret)
+               data[address] = smsc911x_reg_read(pdata, E2P_DATA);
+
+       return ret;
+}
+
+static int smsc911x_eeprom_write_location(struct smsc911x_data *pdata,
+                                         u8 address, u8 data)
+{
+       u32 op = E2P_CMD_EPC_CMD_ERASE_ | address;
+       int ret;
+
+       SMSC_TRACE(DRV, "address 0x%x, data 0x%x", address, data);
+       ret = smsc911x_eeprom_send_cmd(pdata, op);
+
+       if (!ret) {
+               op = E2P_CMD_EPC_CMD_WRITE_ | address;
+               smsc911x_reg_write(pdata, E2P_DATA, (u32)data);
+               ret = smsc911x_eeprom_send_cmd(pdata, op);
+       }
+
+       return ret;
+}
+
+static int smsc911x_ethtool_get_eeprom_len(struct net_device *dev)
+{
+       return SMSC911X_EEPROM_SIZE;
+}
+
+static int smsc911x_ethtool_get_eeprom(struct net_device *dev,
+                                      struct ethtool_eeprom *eeprom, u8 *data)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       u8 eeprom_data[SMSC911X_EEPROM_SIZE];
+       int len;
+       int i;
+
+       smsc911x_eeprom_enable_access(pdata);
+
+       len = min(eeprom->len, SMSC911X_EEPROM_SIZE);
+       for (i = 0; i < len; i++) {
+               int ret = smsc911x_eeprom_read_location(pdata, i, eeprom_data);
+               if (ret < 0) {
+                       eeprom->len = 0;
+                       return ret;
+               }
+       }
+
+       memcpy(data, &eeprom_data[eeprom->offset], len);
+       eeprom->len = len;
+       return 0;
+}
+
+static int smsc911x_ethtool_set_eeprom(struct net_device *dev,
+                                      struct ethtool_eeprom *eeprom, u8 *data)
+{
+       int ret;
+       struct smsc911x_data *pdata = netdev_priv(dev);
+
+       smsc911x_eeprom_enable_access(pdata);
+       smsc911x_eeprom_send_cmd(pdata, E2P_CMD_EPC_CMD_EWEN_);
+       ret = smsc911x_eeprom_write_location(pdata, eeprom->offset, *data);
+       smsc911x_eeprom_send_cmd(pdata, E2P_CMD_EPC_CMD_EWDS_);
+
+       /* Single byte write, according to man page */
+       eeprom->len = 1;
+
+       return ret;
+}
+
+static struct ethtool_ops smsc911x_ethtool_ops = {
+       .get_settings = smsc911x_ethtool_getsettings,
+       .set_settings = smsc911x_ethtool_setsettings,
+       .get_link = ethtool_op_get_link,
+       .get_drvinfo = smsc911x_ethtool_getdrvinfo,
+       .nway_reset = smsc911x_ethtool_nwayreset,
+       .get_msglevel = smsc911x_ethtool_getmsglevel,
+       .set_msglevel = smsc911x_ethtool_setmsglevel,
+       .get_regs_len = smsc911x_ethtool_getregslen,
+       .get_regs = smsc911x_ethtool_getregs,
+       .get_eeprom_len = smsc911x_ethtool_get_eeprom_len,
+       .get_eeprom = smsc911x_ethtool_get_eeprom,
+       .set_eeprom = smsc911x_ethtool_set_eeprom,
+};
+
+/* Initializing private device structures, only called from probe */
+static int __devinit smsc911x_init(struct net_device *dev)
+{
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       unsigned int byte_test;
+
+       SMSC_TRACE(PROBE, "Driver Parameters:");
+       SMSC_TRACE(PROBE, "LAN base: 0x%08lX",
+               (unsigned long)pdata->ioaddr);
+       SMSC_TRACE(PROBE, "IRQ: %d", dev->irq);
+       SMSC_TRACE(PROBE, "PHY will be autodetected.");
+
+#if (!SMSC_CAN_USE_32BIT)
+       spin_lock_init(&pdata->dev_lock);
+#endif
+
+       if (pdata->ioaddr == 0) {
+               SMSC_WARNING(PROBE, "pdata->ioaddr: 0x00000000");
+               return -ENODEV;
+       }
+
+       /* Check byte ordering */
+       byte_test = smsc911x_reg_read(pdata, BYTE_TEST);
+       SMSC_TRACE(PROBE, "BYTE_TEST: 0x%08X", byte_test);
+       if (byte_test == 0x43218765) {
+               SMSC_TRACE(PROBE, "BYTE_TEST looks swapped, "
+                       "applying WORD_SWAP");
+               smsc911x_reg_write(pdata, WORD_SWAP, 0xffffffff);
+
+               /* 1 dummy read of BYTE_TEST is needed after a write to
+                * WORD_SWAP before its contents are valid */
+               byte_test = smsc911x_reg_read(pdata, BYTE_TEST);
+
+               byte_test = smsc911x_reg_read(pdata, BYTE_TEST);
+       }
+
+       if (byte_test != 0x87654321) {
+               SMSC_WARNING(DRV, "BYTE_TEST: 0x%08X", byte_test);
+               if (((byte_test >> 16) & 0xFFFF) == (byte_test & 0xFFFF)) {
+                       SMSC_WARNING(PROBE,
+                               "top 16 bits equal to bottom 16 bits");
+                       SMSC_TRACE(PROBE, "This may mean the chip is set "
+                               "for 32 bit while the bus is reading 16 bit");
+               }
+               return -ENODEV;
+       }
+
+       /* Default generation to zero (all workarounds apply) */
+       pdata->generation = 0;
+
+       pdata->idrev = smsc911x_reg_read(pdata, ID_REV);
+       switch (pdata->idrev & 0xFFFF0000) {
+       case 0x01180000:
+       case 0x01170000:
+       case 0x01160000:
+       case 0x01150000:
+               /* LAN911[5678] family */
+               pdata->generation = pdata->idrev & 0x0000FFFF;
+               break;
+
+       case 0x118A0000:
+       case 0x117A0000:
+       case 0x116A0000:
+       case 0x115A0000:
+               /* LAN921[5678] family */
+               pdata->generation = 3;
+               break;
+
+       case 0x92100000:
+       case 0x92110000:
+       case 0x92200000:
+       case 0x92210000:
+               /* LAN9210/LAN9211/LAN9220/LAN9221 */
+               pdata->generation = 4;
+               break;
+
+       default:
+               SMSC_WARNING(PROBE, "LAN911x not identified, idrev: 0x%08X",
+                       pdata->idrev);
+               return -ENODEV;
+       }
+
+       SMSC_TRACE(PROBE, "LAN911x identified, idrev: 0x%08X, generation: %d",
+               pdata->idrev, pdata->generation);
+
+       if (pdata->generation == 0)
+               SMSC_WARNING(PROBE,
+                       "This driver is not intended for this chip revision");
+
+       /* Reset the LAN911x */
+       if (smsc911x_soft_reset(pdata))
+               return -ENODEV;
+
+       /* Disable all interrupt sources until we bring the device up */
+       smsc911x_reg_write(pdata, INT_EN, 0);
+
+       ether_setup(dev);
+       dev->open = smsc911x_open;
+       dev->stop = smsc911x_stop;
+       dev->hard_start_xmit = smsc911x_hard_start_xmit;
+       dev->get_stats = smsc911x_get_stats;
+       dev->set_multicast_list = smsc911x_set_multicast_list;
+       dev->flags |= IFF_MULTICAST;
+       dev->do_ioctl = smsc911x_do_ioctl;
+       netif_napi_add(dev, &pdata->napi, smsc911x_poll, SMSC_NAPI_WEIGHT);
+       dev->ethtool_ops = &smsc911x_ethtool_ops;
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       dev->poll_controller = smsc911x_poll_controller;
+#endif                         /* CONFIG_NET_POLL_CONTROLLER */
+
+       return 0;
+}
+
+static int __devexit smsc911x_drv_remove(struct platform_device *pdev)
+{
+       struct net_device *dev;
+       struct smsc911x_data *pdata;
+       struct resource *res;
+
+       dev = platform_get_drvdata(pdev);
+       BUG_ON(!dev);
+       pdata = netdev_priv(dev);
+       BUG_ON(!pdata);
+       BUG_ON(!pdata->ioaddr);
+       BUG_ON(!pdata->phy_dev);
+
+       SMSC_TRACE(IFDOWN, "Stopping driver.");
+
+       phy_disconnect(pdata->phy_dev);
+       pdata->phy_dev = NULL;
+       mdiobus_unregister(pdata->mii_bus);
+       mdiobus_free(pdata->mii_bus);
+
+       platform_set_drvdata(pdev, NULL);
+       unregister_netdev(dev);
+       free_irq(dev->irq, dev);
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                          "smsc911x-memory");
+       if (!res)
+               platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       release_mem_region(res->start, res->end - res->start);
+
+       iounmap(pdata->ioaddr);
+
+       free_netdev(dev);
+
+       return 0;
+}
+
+static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
+{
+       struct net_device *dev;
+       struct smsc911x_data *pdata;
+       struct resource *res;
+       unsigned int intcfg = 0;
+       int res_size;
+       int retval;
+       DECLARE_MAC_BUF(mac);
+
+       pr_info("%s: Driver version %s.\n", SMSC_CHIPNAME, SMSC_DRV_VERSION);
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                          "smsc911x-memory");
+       if (!res)
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               pr_warning("%s: Could not allocate resource.\n",
+                       SMSC_CHIPNAME);
+               retval = -ENODEV;
+               goto out_0;
+       }
+       res_size = res->end - res->start;
+
+       if (!request_mem_region(res->start, res_size, SMSC_CHIPNAME)) {
+               retval = -EBUSY;
+               goto out_0;
+       }
+
+       dev = alloc_etherdev(sizeof(struct smsc911x_data));
+       if (!dev) {
+               pr_warning("%s: Could not allocate device.\n", SMSC_CHIPNAME);
+               retval = -ENOMEM;
+               goto out_release_io_1;
+       }
+
+       SET_NETDEV_DEV(dev, &pdev->dev);
+
+       pdata = netdev_priv(dev);
+
+       dev->irq = platform_get_irq(pdev, 0);
+       pdata->ioaddr = ioremap_nocache(res->start, res_size);
+
+       /* copy config parameters across if present, otherwise pdata
+        * defaults to zeros */
+       if (pdev->dev.platform_data) {
+               struct smsc911x_platform_config *config =
+                       pdev->dev.platform_data;
+               pdata->irq_polarity = config->irq_polarity;
+               pdata->irq_type  = config->irq_type;
+               pdata->phy_interface = config->phy_interface;
+       }
+
+       pdata->dev = dev;
+       pdata->msg_enable = ((1 << debug) - 1);
+
+       if (pdata->ioaddr == NULL) {
+               SMSC_WARNING(PROBE,
+                       "Error smsc911x base address invalid");
+               retval = -ENOMEM;
+               goto out_free_netdev_2;
+       }
+
+       retval = smsc911x_init(dev);
+       if (retval < 0)
+               goto out_unmap_io_3;
+
+       /* configure irq polarity and type before connecting isr */
+       if (pdata->irq_polarity == SMSC911X_IRQ_POLARITY_ACTIVE_HIGH)
+               intcfg |= INT_CFG_IRQ_POL_;
+
+       if (pdata->irq_type == SMSC911X_IRQ_TYPE_PUSH_PULL)
+               intcfg |= INT_CFG_IRQ_TYPE_;
+
+       smsc911x_reg_write(pdata, INT_CFG, intcfg);
+
+       /* Ensure interrupts are globally disabled before connecting ISR */
+       smsc911x_reg_write(pdata, INT_EN, 0);
+       smsc911x_reg_write(pdata, INT_STS, 0xFFFFFFFF);
+
+       retval = request_irq(dev->irq, smsc911x_irqhandler, IRQF_DISABLED,
+                            SMSC_CHIPNAME, dev);
+       if (retval) {
+               SMSC_WARNING(PROBE,
+                       "Unable to claim requested irq: %d", dev->irq);
+               goto out_unmap_io_3;
+       }
+
+       platform_set_drvdata(pdev, dev);
+
+       retval = register_netdev(dev);
+       if (retval) {
+               SMSC_WARNING(PROBE,
+                       "Error %i registering device", retval);
+               goto out_unset_drvdata_4;
+       } else {
+               SMSC_TRACE(PROBE, "Network interface: \"%s\"", dev->name);
+       }
+
+       spin_lock_init(&pdata->mac_lock);
+
+       retval = smsc911x_mii_init(pdev, dev);
+       if (retval) {
+               SMSC_WARNING(PROBE,
+                       "Error %i initialising mii", retval);
+               goto out_unregister_netdev_5;
+       }
+
+       spin_lock_irq(&pdata->mac_lock);
+
+       /* Check if mac address has been specified when bringing interface up */
+       if (is_valid_ether_addr(dev->dev_addr)) {
+               smsc911x_set_mac_address(pdata, dev->dev_addr);
+               SMSC_TRACE(PROBE, "MAC Address is specified by configuration");
+       } else {
+               /* Try reading mac address from device. if EEPROM is present
+                * it will already have been set */
+               u32 mac_high16 = smsc911x_mac_read(pdata, ADDRH);
+               u32 mac_low32 = smsc911x_mac_read(pdata, ADDRL);
+               dev->dev_addr[0] = (u8)(mac_low32);
+               dev->dev_addr[1] = (u8)(mac_low32 >> 8);
+               dev->dev_addr[2] = (u8)(mac_low32 >> 16);
+               dev->dev_addr[3] = (u8)(mac_low32 >> 24);
+               dev->dev_addr[4] = (u8)(mac_high16);
+               dev->dev_addr[5] = (u8)(mac_high16 >> 8);
+
+               if (is_valid_ether_addr(dev->dev_addr)) {
+                       /* eeprom values are valid  so use them */
+                       SMSC_TRACE(PROBE,
+                               "Mac Address is read from LAN911x EEPROM");
+               } else {
+                       /* eeprom values are invalid, generate random MAC */
+                       random_ether_addr(dev->dev_addr);
+                       smsc911x_set_mac_address(pdata, dev->dev_addr);
+                       SMSC_TRACE(PROBE,
+                               "MAC Address is set to random_ether_addr");
+               }
+       }
+
+       spin_unlock_irq(&pdata->mac_lock);
+
+       dev_info(&dev->dev, "MAC Address: %s\n",
+                print_mac(mac, dev->dev_addr));
+
+       return 0;
+
+out_unregister_netdev_5:
+       unregister_netdev(dev);
+out_unset_drvdata_4:
+       platform_set_drvdata(pdev, NULL);
+       free_irq(dev->irq, dev);
+out_unmap_io_3:
+       iounmap(pdata->ioaddr);
+out_free_netdev_2:
+       free_netdev(dev);
+out_release_io_1:
+       release_mem_region(res->start, res->end - res->start);
+out_0:
+       return retval;
+}
+
+static struct platform_driver smsc911x_driver = {
+       .probe = smsc911x_drv_probe,
+       .remove = smsc911x_drv_remove,
+       .driver = {
+               .name = SMSC_CHIPNAME,
+       },
+};
+
+/* Entry point for loading the module */
+static int __init smsc911x_init_module(void)
+{
+       return platform_driver_register(&smsc911x_driver);
+}
+
+/* entry point for unloading the module */
+static void __exit smsc911x_cleanup_module(void)
+{
+       platform_driver_unregister(&smsc911x_driver);
+}
+
+module_init(smsc911x_init_module);
+module_exit(smsc911x_cleanup_module);
diff --git a/drivers/net/smsc911x.h b/drivers/net/smsc911x.h
new file mode 100644 (file)
index 0000000..feb36de
--- /dev/null
@@ -0,0 +1,394 @@
+/***************************************************************************
+ *
+ * Copyright (C) 2004-2008 SMSC
+ * Copyright (C) 2005-2008 ARM
+ *
+ * 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 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ ***************************************************************************/
+#ifndef __SMSC911X_H__
+#define __SMSC911X_H__
+
+#define SMSC_CAN_USE_32BIT     1
+#define TX_FIFO_LOW_THRESHOLD  ((u32)1600)
+#define SMSC911X_EEPROM_SIZE   ((u32)7)
+#define USE_DEBUG              0
+
+/* This is the maximum number of packets to be received every
+ * NAPI poll */
+#define SMSC_NAPI_WEIGHT       16
+
+/* implements a PHY loopback test at initialisation time, to ensure a packet
+ * can be succesfully looped back */
+#define USE_PHY_WORK_AROUND
+
+#define DPRINTK(nlevel, klevel, fmt, args...) \
+       ((void)((NETIF_MSG_##nlevel & pdata->msg_enable) && \
+       printk(KERN_##klevel "%s: %s: " fmt "\n", \
+       pdata->dev->name, __func__, ## args)))
+
+#if USE_DEBUG >= 1
+#define SMSC_WARNING(nlevel, fmt, args...) \
+       DPRINTK(nlevel, WARNING, fmt, ## args)
+#else
+#define SMSC_WARNING(nlevel, fmt, args...) \
+       ({ do {} while (0); 0; })
+#endif
+
+#if USE_DEBUG >= 2
+#define SMSC_TRACE(nlevel, fmt, args...) \
+       DPRINTK(nlevel, INFO, fmt, ## args)
+#else
+#define SMSC_TRACE(nlevel, fmt, args...) \
+       ({ do {} while (0); 0; })
+#endif
+
+#ifdef CONFIG_DEBUG_SPINLOCK
+#define SMSC_ASSERT_MAC_LOCK(pdata) \
+               WARN_ON(!spin_is_locked(&pdata->mac_lock))
+#else
+#define SMSC_ASSERT_MAC_LOCK(pdata) do {} while (0)
+#endif                         /* CONFIG_DEBUG_SPINLOCK */
+
+#define FLOW_CTRL_TX           (1)
+#define FLOW_CTRL_RX           (2)
+
+/* SMSC911x registers and bitfields */
+#define RX_DATA_FIFO                   0x00
+
+#define TX_DATA_FIFO                   0x20
+#define TX_CMD_A_ON_COMP_              0x80000000
+#define TX_CMD_A_BUF_END_ALGN_         0x03000000
+#define TX_CMD_A_4_BYTE_ALGN_          0x00000000
+#define TX_CMD_A_16_BYTE_ALGN_         0x01000000
+#define TX_CMD_A_32_BYTE_ALGN_         0x02000000
+#define TX_CMD_A_DATA_OFFSET_          0x001F0000
+#define TX_CMD_A_FIRST_SEG_            0x00002000
+#define TX_CMD_A_LAST_SEG_             0x00001000
+#define TX_CMD_A_BUF_SIZE_             0x000007FF
+#define TX_CMD_B_PKT_TAG_              0xFFFF0000
+#define TX_CMD_B_ADD_CRC_DISABLE_      0x00002000
+#define TX_CMD_B_DISABLE_PADDING_      0x00001000
+#define TX_CMD_B_PKT_BYTE_LENGTH_      0x000007FF
+
+#define RX_STATUS_FIFO                 0x40
+#define RX_STS_ES_                     0x00008000
+#define RX_STS_MCAST_                  0x00000400
+
+#define RX_STATUS_FIFO_PEEK            0x44
+
+#define TX_STATUS_FIFO                 0x48
+#define TX_STS_ES_                     0x00008000
+
+#define TX_STATUS_FIFO_PEEK            0x4C
+
+#define ID_REV                         0x50
+#define ID_REV_CHIP_ID_                        0xFFFF0000
+#define ID_REV_REV_ID_                 0x0000FFFF
+
+#define INT_CFG                                0x54
+#define INT_CFG_INT_DEAS_              0xFF000000
+#define INT_CFG_INT_DEAS_CLR_          0x00004000
+#define INT_CFG_INT_DEAS_STS_          0x00002000
+#define INT_CFG_IRQ_INT_               0x00001000
+#define INT_CFG_IRQ_EN_                        0x00000100
+#define INT_CFG_IRQ_POL_               0x00000010
+#define INT_CFG_IRQ_TYPE_              0x00000001
+
+#define INT_STS                                0x58
+#define INT_STS_SW_INT_                        0x80000000
+#define INT_STS_TXSTOP_INT_            0x02000000
+#define INT_STS_RXSTOP_INT_            0x01000000
+#define INT_STS_RXDFH_INT_             0x00800000
+#define INT_STS_RXDF_INT_              0x00400000
+#define INT_STS_TX_IOC_                        0x00200000
+#define INT_STS_RXD_INT_               0x00100000
+#define INT_STS_GPT_INT_               0x00080000
+#define INT_STS_PHY_INT_               0x00040000
+#define INT_STS_PME_INT_               0x00020000
+#define INT_STS_TXSO_                  0x00010000
+#define INT_STS_RWT_                   0x00008000
+#define INT_STS_RXE_                   0x00004000
+#define INT_STS_TXE_                   0x00002000
+#define INT_STS_TDFU_                  0x00000800
+#define INT_STS_TDFO_                  0x00000400
+#define INT_STS_TDFA_                  0x00000200
+#define INT_STS_TSFF_                  0x00000100
+#define INT_STS_TSFL_                  0x00000080
+#define INT_STS_RXDF_                  0x00000040
+#define INT_STS_RDFL_                  0x00000020
+#define INT_STS_RSFF_                  0x00000010
+#define INT_STS_RSFL_                  0x00000008
+#define INT_STS_GPIO2_INT_             0x00000004
+#define INT_STS_GPIO1_INT_             0x00000002
+#define INT_STS_GPIO0_INT_             0x00000001
+
+#define INT_EN                         0x5C
+#define INT_EN_SW_INT_EN_              0x80000000
+#define INT_EN_TXSTOP_INT_EN_          0x02000000
+#define INT_EN_RXSTOP_INT_EN_          0x01000000
+#define INT_EN_RXDFH_INT_EN_           0x00800000
+#define INT_EN_TIOC_INT_EN_            0x00200000
+#define INT_EN_RXD_INT_EN_             0x00100000
+#define INT_EN_GPT_INT_EN_             0x00080000
+#define INT_EN_PHY_INT_EN_             0x00040000
+#define INT_EN_PME_INT_EN_             0x00020000
+#define INT_EN_TXSO_EN_                        0x00010000
+#define INT_EN_RWT_EN_                 0x00008000
+#define INT_EN_RXE_EN_                 0x00004000
+#define INT_EN_TXE_EN_                 0x00002000
+#define INT_EN_TDFU_EN_                        0x00000800
+#define INT_EN_TDFO_EN_                        0x00000400
+#define INT_EN_TDFA_EN_                        0x00000200
+#define INT_EN_TSFF_EN_                        0x00000100
+#define INT_EN_TSFL_EN_                        0x00000080
+#define INT_EN_RXDF_EN_                        0x00000040
+#define INT_EN_RDFL_EN_                        0x00000020
+#define INT_EN_RSFF_EN_                        0x00000010
+#define INT_EN_RSFL_EN_                        0x00000008
+#define INT_EN_GPIO2_INT_              0x00000004
+#define INT_EN_GPIO1_INT_              0x00000002
+#define INT_EN_GPIO0_INT_              0x00000001
+
+#define BYTE_TEST                      0x64
+
+#define FIFO_INT                       0x68
+#define FIFO_INT_TX_AVAIL_LEVEL_       0xFF000000
+#define FIFO_INT_TX_STS_LEVEL_         0x00FF0000
+#define FIFO_INT_RX_AVAIL_LEVEL_       0x0000FF00
+#define FIFO_INT_RX_STS_LEVEL_         0x000000FF
+
+#define RX_CFG                         0x6C
+#define RX_CFG_RX_END_ALGN_            0xC0000000
+#define RX_CFG_RX_END_ALGN4_           0x00000000
+#define RX_CFG_RX_END_ALGN16_          0x40000000
+#define RX_CFG_RX_END_ALGN32_          0x80000000
+#define RX_CFG_RX_DMA_CNT_             0x0FFF0000
+#define RX_CFG_RX_DUMP_                        0x00008000
+#define RX_CFG_RXDOFF_                 0x00001F00
+
+#define TX_CFG                         0x70
+#define TX_CFG_TXS_DUMP_               0x00008000
+#define TX_CFG_TXD_DUMP_               0x00004000
+#define TX_CFG_TXSAO_                  0x00000004
+#define TX_CFG_TX_ON_                  0x00000002
+#define TX_CFG_STOP_TX_                        0x00000001
+
+#define HW_CFG                         0x74
+#define HW_CFG_TTM_                    0x00200000
+#define HW_CFG_SF_                     0x00100000
+#define HW_CFG_TX_FIF_SZ_              0x000F0000
+#define HW_CFG_TR_                     0x00003000
+#define HW_CFG_SRST_                   0x00000001
+
+/* only available on 115/117 */
+#define HW_CFG_PHY_CLK_SEL_            0x00000060
+#define HW_CFG_PHY_CLK_SEL_INT_PHY_    0x00000000
+#define HW_CFG_PHY_CLK_SEL_EXT_PHY_    0x00000020
+#define HW_CFG_PHY_CLK_SEL_CLK_DIS_    0x00000040
+#define HW_CFG_SMI_SEL_                        0x00000010
+#define HW_CFG_EXT_PHY_DET_            0x00000008
+#define HW_CFG_EXT_PHY_EN_             0x00000004
+#define HW_CFG_SRST_TO_                        0x00000002
+
+/* only available  on 116/118 */
+#define HW_CFG_32_16_BIT_MODE_         0x00000004
+
+#define RX_DP_CTRL                     0x78
+#define RX_DP_CTRL_RX_FFWD_            0x80000000
+
+#define RX_FIFO_INF                    0x7C
+#define RX_FIFO_INF_RXSUSED_           0x00FF0000
+#define RX_FIFO_INF_RXDUSED_           0x0000FFFF
+
+#define TX_FIFO_INF                    0x80
+#define TX_FIFO_INF_TSUSED_            0x00FF0000
+#define TX_FIFO_INF_TDFREE_            0x0000FFFF
+
+#define PMT_CTRL                       0x84
+#define PMT_CTRL_PM_MODE_              0x00003000
+#define PMT_CTRL_PM_MODE_D0_           0x00000000
+#define PMT_CTRL_PM_MODE_D1_           0x00001000
+#define PMT_CTRL_PM_MODE_D2_           0x00002000
+#define PMT_CTRL_PM_MODE_D3_           0x00003000
+#define PMT_CTRL_PHY_RST_              0x00000400
+#define PMT_CTRL_WOL_EN_               0x00000200
+#define PMT_CTRL_ED_EN_                        0x00000100
+#define PMT_CTRL_PME_TYPE_             0x00000040
+#define PMT_CTRL_WUPS_                 0x00000030
+#define PMT_CTRL_WUPS_NOWAKE_          0x00000000
+#define PMT_CTRL_WUPS_ED_              0x00000010
+#define PMT_CTRL_WUPS_WOL_             0x00000020
+#define PMT_CTRL_WUPS_MULTI_           0x00000030
+#define PMT_CTRL_PME_IND_              0x00000008
+#define PMT_CTRL_PME_POL_              0x00000004
+#define PMT_CTRL_PME_EN_               0x00000002
+#define PMT_CTRL_READY_                        0x00000001
+
+#define GPIO_CFG                       0x88
+#define GPIO_CFG_LED3_EN_              0x40000000
+#define GPIO_CFG_LED2_EN_              0x20000000
+#define GPIO_CFG_LED1_EN_              0x10000000
+#define GPIO_CFG_GPIO2_INT_POL_                0x04000000
+#define GPIO_CFG_GPIO1_INT_POL_                0x02000000
+#define GPIO_CFG_GPIO0_INT_POL_                0x01000000
+#define GPIO_CFG_EEPR_EN_              0x00700000
+#define GPIO_CFG_GPIOBUF2_             0x00040000
+#define GPIO_CFG_GPIOBUF1_             0x00020000
+#define GPIO_CFG_GPIOBUF0_             0x00010000
+#define GPIO_CFG_GPIODIR2_             0x00000400
+#define GPIO_CFG_GPIODIR1_             0x00000200
+#define GPIO_CFG_GPIODIR0_             0x00000100
+#define GPIO_CFG_GPIOD4_               0x00000020
+#define GPIO_CFG_GPIOD3_               0x00000010
+#define GPIO_CFG_GPIOD2_               0x00000004
+#define GPIO_CFG_GPIOD1_               0x00000002
+#define GPIO_CFG_GPIOD0_               0x00000001
+
+#define GPT_CFG                                0x8C
+#define GPT_CFG_TIMER_EN_              0x20000000
+#define GPT_CFG_GPT_LOAD_              0x0000FFFF
+
+#define GPT_CNT                                0x90
+#define GPT_CNT_GPT_CNT_               0x0000FFFF
+
+#define WORD_SWAP                      0x98
+
+#define FREE_RUN                       0x9C
+
+#define RX_DROP                                0xA0
+
+#define MAC_CSR_CMD                    0xA4
+#define MAC_CSR_CMD_CSR_BUSY_          0x80000000
+#define MAC_CSR_CMD_R_NOT_W_           0x40000000
+#define MAC_CSR_CMD_CSR_ADDR_          0x000000FF
+
+#define MAC_CSR_DATA                   0xA8
+
+#define AFC_CFG                                0xAC
+#define AFC_CFG_AFC_HI_                        0x00FF0000
+#define AFC_CFG_AFC_LO_                        0x0000FF00
+#define AFC_CFG_BACK_DUR_              0x000000F0
+#define AFC_CFG_FCMULT_                        0x00000008
+#define AFC_CFG_FCBRD_                 0x00000004
+#define AFC_CFG_FCADD_                 0x00000002
+#define AFC_CFG_FCANY_                 0x00000001
+
+#define E2P_CMD                                0xB0
+#define E2P_CMD_EPC_BUSY_              0x80000000
+#define E2P_CMD_EPC_CMD_               0x70000000
+#define E2P_CMD_EPC_CMD_READ_          0x00000000
+#define E2P_CMD_EPC_CMD_EWDS_          0x10000000
+#define E2P_CMD_EPC_CMD_EWEN_          0x20000000
+#define E2P_CMD_EPC_CMD_WRITE_         0x30000000
+#define E2P_CMD_EPC_CMD_WRAL_          0x40000000
+#define E2P_CMD_EPC_CMD_ERASE_         0x50000000
+#define E2P_CMD_EPC_CMD_ERAL_          0x60000000
+#define E2P_CMD_EPC_CMD_RELOAD_                0x70000000
+#define E2P_CMD_EPC_TIMEOUT_           0x00000200
+#define E2P_CMD_MAC_ADDR_LOADED_       0x00000100
+#define E2P_CMD_EPC_ADDR_              0x000000FF
+
+#define E2P_DATA                       0xB4
+#define E2P_DATA_EEPROM_DATA_          0x000000FF
+#define LAN_REGISTER_EXTENT            0x00000100
+
+/*
+ * MAC Control and Status Register (Indirect Address)
+ * Offset (through the MAC_CSR CMD and DATA port)
+ */
+#define MAC_CR                         0x01
+#define MAC_CR_RXALL_                  0x80000000
+#define MAC_CR_HBDIS_                  0x10000000
+#define MAC_CR_RCVOWN_                 0x00800000
+#define MAC_CR_LOOPBK_                 0x00200000
+#define MAC_CR_FDPX_                   0x00100000
+#define MAC_CR_MCPAS_                  0x00080000
+#define MAC_CR_PRMS_                   0x00040000
+#define MAC_CR_INVFILT_                        0x00020000
+#define MAC_CR_PASSBAD_                        0x00010000
+#define MAC_CR_HFILT_                  0x00008000
+#define MAC_CR_HPFILT_                 0x00002000
+#define MAC_CR_LCOLL_                  0x00001000
+#define MAC_CR_BCAST_                  0x00000800
+#define MAC_CR_DISRTY_                 0x00000400
+#define MAC_CR_PADSTR_                 0x00000100
+#define MAC_CR_BOLMT_MASK_             0x000000C0
+#define MAC_CR_DFCHK_                  0x00000020
+#define MAC_CR_TXEN_                   0x00000008
+#define MAC_CR_RXEN_                   0x00000004
+
+#define ADDRH                          0x02
+
+#define ADDRL                          0x03
+
+#define HASHH                          0x04
+
+#define HASHL                          0x05
+
+#define MII_ACC                                0x06
+#define MII_ACC_PHY_ADDR_              0x0000F800
+#define MII_ACC_MIIRINDA_              0x000007C0
+#define MII_ACC_MII_WRITE_             0x00000002
+#define MII_ACC_MII_BUSY_              0x00000001
+
+#define MII_DATA                       0x07
+
+#define FLOW                           0x08
+#define FLOW_FCPT_                     0xFFFF0000
+#define FLOW_FCPASS_                   0x00000004
+#define FLOW_FCEN_                     0x00000002
+#define FLOW_FCBSY_                    0x00000001
+
+#define VLAN1                          0x09
+
+#define VLAN2                          0x0A
+
+#define WUFF                           0x0B
+
+#define WUCSR                          0x0C
+#define WUCSR_GUE_                     0x00000200
+#define WUCSR_WUFR_                    0x00000040
+#define WUCSR_MPR_                     0x00000020
+#define WUCSR_WAKE_EN_                 0x00000004
+#define WUCSR_MPEN_                    0x00000002
+
+/*
+ * Phy definitions (vendor-specific)
+ */
+#define LAN9118_PHY_ID                 0x00C0001C
+
+#define MII_INTSTS                     0x1D
+
+#define MII_INTMSK                     0x1E
+#define PHY_INTMSK_AN_RCV_             (1 << 1)
+#define PHY_INTMSK_PDFAULT_            (1 << 2)
+#define PHY_INTMSK_AN_ACK_             (1 << 3)
+#define PHY_INTMSK_LNKDOWN_            (1 << 4)
+#define PHY_INTMSK_RFAULT_             (1 << 5)
+#define PHY_INTMSK_AN_COMP_            (1 << 6)
+#define PHY_INTMSK_ENERGYON_           (1 << 7)
+#define PHY_INTMSK_DEFAULT_            (PHY_INTMSK_ENERGYON_ | \
+                                        PHY_INTMSK_AN_COMP_ | \
+                                        PHY_INTMSK_RFAULT_ | \
+                                        PHY_INTMSK_LNKDOWN_)
+
+#define ADVERTISE_PAUSE_ALL            (ADVERTISE_PAUSE_CAP | \
+                                        ADVERTISE_PAUSE_ASYM)
+
+#define LPA_PAUSE_ALL                  (LPA_PAUSE_CAP | \
+                                        LPA_PAUSE_ASYM)
+
+#endif                         /* __SMSC911X_H__ */
index 8069f3e32d83db988a33277073c1cd5d706b601a..211e805c122350a2707e90858321d8a8fd4a5a60 100644 (file)
@@ -450,7 +450,6 @@ static void sonic_rx(struct net_device *dev)
                        skb_trim(used_skb, pkt_len);
                        used_skb->protocol = eth_type_trans(used_skb, dev);
                        netif_rx(used_skb);
-                       dev->last_rx = jiffies;
                        lp->stats.rx_packets++;
                        lp->stats.rx_bytes += pkt_len;
 
index 7db13e4a7ea55c70c8b31c9cd0c93dbbb6012d1f..07091dd27e5df2969592a3faa54f30fdad4a4844 100644 (file)
@@ -371,7 +371,7 @@ static inline __u16 sonic_buf_get(void* base, int bitmode,
 static inline void sonic_cda_put(struct net_device* dev, int entry,
                                 int offset, __u16 val)
 {
-       struct sonic_local* lp = (struct sonic_local *) dev->priv;
+       struct sonic_local *lp = netdev_priv(dev);
        sonic_buf_put(lp->cda, lp->dma_bitmode,
                      (entry * SIZEOF_SONIC_CD) + offset, val);
 }
@@ -379,27 +379,27 @@ static inline void sonic_cda_put(struct net_device* dev, int entry,
 static inline __u16 sonic_cda_get(struct net_device* dev, int entry,
                                  int offset)
 {
-       struct sonic_local* lp = (struct sonic_local *) dev->priv;
+       struct sonic_local *lp = netdev_priv(dev);
        return sonic_buf_get(lp->cda, lp->dma_bitmode,
                             (entry * SIZEOF_SONIC_CD) + offset);
 }
 
 static inline void sonic_set_cam_enable(struct net_device* dev, __u16 val)
 {
-       struct sonic_local* lp = (struct sonic_local *) dev->priv;
+       struct sonic_local *lp = netdev_priv(dev);
        sonic_buf_put(lp->cda, lp->dma_bitmode, SONIC_CDA_CAM_ENABLE, val);
 }
 
 static inline __u16 sonic_get_cam_enable(struct net_device* dev)
 {
-       struct sonic_local* lp = (struct sonic_local *) dev->priv;
+       struct sonic_local *lp = netdev_priv(dev);
        return sonic_buf_get(lp->cda, lp->dma_bitmode, SONIC_CDA_CAM_ENABLE);
 }
 
 static inline void sonic_tda_put(struct net_device* dev, int entry,
                                 int offset, __u16 val)
 {
-       struct sonic_local* lp = (struct sonic_local *) dev->priv;
+       struct sonic_local *lp = netdev_priv(dev);
        sonic_buf_put(lp->tda, lp->dma_bitmode,
                      (entry * SIZEOF_SONIC_TD) + offset, val);
 }
@@ -407,7 +407,7 @@ static inline void sonic_tda_put(struct net_device* dev, int entry,
 static inline __u16 sonic_tda_get(struct net_device* dev, int entry,
                                  int offset)
 {
-       struct sonic_local* lp = (struct sonic_local *) dev->priv;
+       struct sonic_local *lp = netdev_priv(dev);
        return sonic_buf_get(lp->tda, lp->dma_bitmode,
                             (entry * SIZEOF_SONIC_TD) + offset);
 }
@@ -415,7 +415,7 @@ static inline __u16 sonic_tda_get(struct net_device* dev, int entry,
 static inline void sonic_rda_put(struct net_device* dev, int entry,
                                 int offset, __u16 val)
 {
-       struct sonic_local* lp = (struct sonic_local *) dev->priv;
+       struct sonic_local *lp = netdev_priv(dev);
        sonic_buf_put(lp->rda, lp->dma_bitmode,
                      (entry * SIZEOF_SONIC_RD) + offset, val);
 }
@@ -423,7 +423,7 @@ static inline void sonic_rda_put(struct net_device* dev, int entry,
 static inline __u16 sonic_rda_get(struct net_device* dev, int entry,
                                  int offset)
 {
-       struct sonic_local* lp = (struct sonic_local *) dev->priv;
+       struct sonic_local *lp = netdev_priv(dev);
        return sonic_buf_get(lp->rda, lp->dma_bitmode,
                             (entry * SIZEOF_SONIC_RD) + offset);
 }
@@ -431,7 +431,7 @@ static inline __u16 sonic_rda_get(struct net_device* dev, int entry,
 static inline void sonic_rra_put(struct net_device* dev, int entry,
                                 int offset, __u16 val)
 {
-       struct sonic_local* lp = (struct sonic_local *) dev->priv;
+       struct sonic_local *lp = netdev_priv(dev);
        sonic_buf_put(lp->rra, lp->dma_bitmode,
                      (entry * SIZEOF_SONIC_RR) + offset, val);
 }
@@ -439,7 +439,7 @@ static inline void sonic_rra_put(struct net_device* dev, int entry,
 static inline __u16 sonic_rra_get(struct net_device* dev, int entry,
                                  int offset)
 {
-       struct sonic_local* lp = (struct sonic_local *) dev->priv;
+       struct sonic_local *lp = netdev_priv(dev);
        return sonic_buf_get(lp->rra, lp->dma_bitmode,
                             (entry * SIZEOF_SONIC_RR) + offset);
 }
index 85691d2a0be26a454e65550d867d4e59a0713119..5bae728c3820a01b00ace7672d1422fecc9d8aee 100644 (file)
@@ -118,7 +118,7 @@ spider_net_ethtool_nway_reset(struct net_device *netdev)
 static u32
 spider_net_ethtool_get_rx_csum(struct net_device *netdev)
 {
-       struct spider_net_card *card = netdev->priv;
+       struct spider_net_card *card = netdev_priv(netdev);
 
        return card->options.rx_csum;
 }
@@ -126,7 +126,7 @@ spider_net_ethtool_get_rx_csum(struct net_device *netdev)
 static int
 spider_net_ethtool_set_rx_csum(struct net_device *netdev, u32 n)
 {
-       struct spider_net_card *card = netdev->priv;
+       struct spider_net_card *card = netdev_priv(netdev);
 
        card->options.rx_csum = n;
        return 0;
@@ -137,7 +137,7 @@ static void
 spider_net_ethtool_get_ringparam(struct net_device *netdev,
                                 struct ethtool_ringparam *ering)
 {
-       struct spider_net_card *card = netdev->priv;
+       struct spider_net_card *card = netdev_priv(netdev);
 
        ering->tx_max_pending = SPIDER_NET_TX_DESCRIPTORS_MAX;
        ering->tx_pending = card->tx_chain.num_desc;
@@ -158,7 +158,7 @@ static int spider_net_get_sset_count(struct net_device *netdev, int sset)
 static void spider_net_get_ethtool_stats(struct net_device *netdev,
                struct ethtool_stats *stats, u64 *data)
 {
-       struct spider_net_card *card = netdev->priv;
+       struct spider_net_card *card = netdev_priv(netdev);
 
        data[0] = netdev->stats.tx_packets;
        data[1] = netdev->stats.tx_bytes;
index 1d2ef8f47780904da79f621bf2ac09d284b50753..0358809f409c8d8522d983fd54966b54be78b5ef 100644 (file)
@@ -653,7 +653,6 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
        void __iomem *base;
        int drv_flags, io_size;
        int boguscnt;
-       DECLARE_MAC_BUF(mac);
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -823,9 +822,9 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
        if (register_netdev(dev))
                goto err_out_cleardev;
 
-       printk(KERN_INFO "%s: %s at %p, %s, IRQ %d.\n",
+       printk(KERN_INFO "%s: %s at %p, %pM, IRQ %d.\n",
               dev->name, netdrv_tbl[chip_idx].name, base,
-              print_mac(mac, dev->dev_addr), irq);
+              dev->dev_addr, irq);
 
        if (drv_flags & CanHaveMII) {
                int phy, phy_idx = 0;
@@ -1452,12 +1451,8 @@ static int __netdev_rx(struct net_device *dev, int *quota)
 #ifndef final_version                  /* Remove after testing. */
                /* You will want this info for the initial debug. */
                if (debug > 5) {
-                       printk(KERN_DEBUG "  Rx data " MAC_FMT " " MAC_FMT
-                              " %2.2x%2.2x.\n",
-                              skb->data[0], skb->data[1], skb->data[2],
-                              skb->data[3], skb->data[4], skb->data[5],
-                              skb->data[6], skb->data[7], skb->data[8],
-                              skb->data[9], skb->data[10], skb->data[11],
+                       printk(KERN_DEBUG "  Rx data %pM %pM %2.2x%2.2x.\n",
+                              skb->data, skb->data + 6,
                               skb->data[12], skb->data[13]);
                }
 #endif
@@ -1501,7 +1496,6 @@ static int __netdev_rx(struct net_device *dev, int *quota)
                } else
 #endif /* VLAN_SUPPORT */
                        netif_receive_skb(skb);
-               dev->last_rx = jiffies;
                np->stats.rx_packets++;
 
        next_rx:
index e531302d95f5078680e1065bda74550346574055..e8f97d5c9c239f14598aece1e865e469a1e5eb6f 100644 (file)
@@ -247,7 +247,7 @@ static int check586(struct net_device *dev,char *where,unsigned size)
  */
 static void alloc586(struct net_device *dev)
 {
-       struct priv *p =        (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        sun3_reset586();
        DELAY(1);
@@ -363,17 +363,21 @@ static int __init sun3_82586_probe1(struct net_device *dev,int ioaddr)
                goto out;
        }
 
-       ((struct priv *) (dev->priv))->memtop = (char *)dvma_btov(dev->mem_start);
-       ((struct priv *) (dev->priv))->base = (unsigned long) dvma_btov(0);
+       ((struct priv *)netdev_priv(dev))->memtop =
+                                       (char *)dvma_btov(dev->mem_start);
+       ((struct priv *)netdev_priv(dev))->base = (unsigned long) dvma_btov(0);
        alloc586(dev);
 
        /* set number of receive-buffs according to memsize */
        if(size == 0x2000)
-               ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_8;
+               ((struct priv *)netdev_priv(dev))->num_recv_buffs =
+                                                       NUM_RECV_BUFFS_8;
        else if(size == 0x4000)
-               ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_16;
+               ((struct priv *)netdev_priv(dev))->num_recv_buffs =
+                                                       NUM_RECV_BUFFS_16;
        else
-               ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_32;
+               ((struct priv *)netdev_priv(dev))->num_recv_buffs =
+                                                       NUM_RECV_BUFFS_32;
 
        printk("Memaddr: 0x%lx, Memsize: %d, IRQ %d\n",dev->mem_start,size, dev->irq);
 
@@ -397,7 +401,7 @@ static int init586(struct net_device *dev)
 {
        void *ptr;
        int i,result=0;
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
        volatile struct configure_cmd_struct    *cfg_cmd;
        volatile struct iasetup_cmd_struct *ias_cmd;
        volatile struct tdr_cmd_struct *tdr_cmd;
@@ -631,7 +635,7 @@ static void *alloc_rfa(struct net_device *dev,void *ptr)
        volatile struct rfd_struct *rfd = (struct rfd_struct *)ptr;
        volatile struct rbd_struct *rbd;
        int i;
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        memset((char *) rfd,0,sizeof(struct rfd_struct)*(p->num_recv_buffs+rfdadd));
        p->rfd_first = rfd;
@@ -683,7 +687,7 @@ static irqreturn_t sun3_82586_interrupt(int irq,void *dev_id)
                printk ("sun3_82586-interrupt: irq %d for unknown device.\n",irq);
                return IRQ_NONE;
        }
-       p = (struct priv *) dev->priv;
+       p = netdev_priv(dev);
 
        if(debuglevel > 1)
                printk("I");
@@ -753,7 +757,7 @@ static void sun3_82586_rcv_int(struct net_device *dev)
        unsigned short totlen;
        struct sk_buff *skb;
        struct rbd_struct *rbd;
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        if(debuglevel > 0)
                printk("R");
@@ -871,7 +875,7 @@ static void sun3_82586_rcv_int(struct net_device *dev)
 
 static void sun3_82586_rnr_int(struct net_device *dev)
 {
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        p->stats.rx_errors++;
 
@@ -895,7 +899,7 @@ static void sun3_82586_rnr_int(struct net_device *dev)
 static void sun3_82586_xmt_int(struct net_device *dev)
 {
        int status;
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        if(debuglevel > 0)
                printk("X");
@@ -945,7 +949,7 @@ static void sun3_82586_xmt_int(struct net_device *dev)
 
 static void startrecv586(struct net_device *dev)
 {
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        WAIT_4_SCB_CMD();
        WAIT_4_SCB_CMD_RUC();
@@ -957,7 +961,7 @@ static void startrecv586(struct net_device *dev)
 
 static void sun3_82586_timeout(struct net_device *dev)
 {
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 #ifndef NO_NOPCOMMANDS
        if(p->scb->cus & CU_ACTIVE) /* COMMAND-UNIT active? */
        {
@@ -999,7 +1003,7 @@ static int sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
 #ifndef NO_NOPCOMMANDS
        int next_nop;
 #endif
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
 
        if(skb->len > XMIT_BUFF_SIZE)
        {
@@ -1108,7 +1112,7 @@ static int sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
 
 static struct net_device_stats *sun3_82586_get_stats(struct net_device *dev)
 {
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
        unsigned short crc,aln,rsc,ovrn;
 
        crc = swab16(p->scb->crc_errs); /* get error-statistic from the ni82586 */
@@ -1171,7 +1175,7 @@ void cleanup_module(void)
  */
 void sun3_82586_dump(struct net_device *dev,void *ptr)
 {
-       struct priv *p = (struct priv *) dev->priv;
+       struct priv *p = netdev_priv(dev);
        struct dump_cmd_struct *dump_cmd = (struct dump_cmd_struct *) ptr;
        int i;
 
index 359452a06c67d7160e444ee3ab893afec2747f6d..4bb8f72c65cceb3f4e20d20229c299ebca33abf0 100644 (file)
@@ -303,7 +303,6 @@ static int __init lance_probe( struct net_device *dev)
        static int              did_version;
        volatile unsigned short *ioaddr_probe;
        unsigned short tmp1, tmp2;
-       DECLARE_MAC_BUF(mac);
 
 #ifdef CONFIG_SUN3
        ioaddr = (unsigned long)ioremap(LANCE_OBIO, PAGE_SIZE);
@@ -379,7 +378,7 @@ static int __init lance_probe( struct net_device *dev)
        MEM->init.hwaddr[4] = dev->dev_addr[5];
        MEM->init.hwaddr[5] = dev->dev_addr[4];
 
-       printk("%s\n", print_mac(mac, dev->dev_addr));
+       printk("%pM\n", dev->dev_addr);
 
        MEM->init.mode = 0x0000;
        MEM->init.filter[0] = 0x00000000;
@@ -824,12 +823,10 @@ static int lance_rx( struct net_device *dev )
 #if 0
                                if (lance_debug >= 3) {
                                        u_char *data = PKTBUF_ADDR(head);
-                                       DECLARE_MAC_BUF(mac);
-                                       DECLARE_MAC_BUF(mac2)
                                        printk("%s: RX pkt %d type 0x%04x"
-                                              " from %s to %s",
+                                              " from %pM to %pM",
                                               dev->name, lp->new_tx, ((u_short *)data)[6],
-                                              print_mac(mac, &data[6]), print_mac(mac2, data));
+                                              &data[6], data);
 
                                        printk(" data %02x %02x %02x %02x %02x %02x %02x %02x "
                                               "len %d at %08x\n",
@@ -852,7 +849,6 @@ static int lance_rx( struct net_device *dev )
 
                                skb->protocol = eth_type_trans( skb, dev );
                                netif_rx( skb );
-                               dev->last_rx = jiffies;
                                dev->stats.rx_packets++;
                                dev->stats.rx_bytes += pkt_len;
                        }
index 018d0fca9422bc2760c835b6f9a9de46670da7e1..977b3e08bbfc5eb706f29534d2d2c818d5b79cc7 100644 (file)
@@ -878,7 +878,6 @@ static void bigmac_rx(struct bigmac *bp)
                /* No checksums done by the BigMAC ;-( */
                skb->protocol = eth_type_trans(skb, bp->dev);
                netif_rx(skb);
-               bp->dev->last_rx = jiffies;
                bp->enet_stats.rx_packets++;
                bp->enet_stats.rx_bytes += len;
        next:
@@ -917,7 +916,7 @@ static irqreturn_t bigmac_interrupt(int irq, void *dev_id)
 
 static int bigmac_open(struct net_device *dev)
 {
-       struct bigmac *bp = (struct bigmac *) dev->priv;
+       struct bigmac *bp = netdev_priv(dev);
        int ret;
 
        ret = request_irq(dev->irq, &bigmac_interrupt, IRQF_SHARED, dev->name, bp);
@@ -934,7 +933,7 @@ static int bigmac_open(struct net_device *dev)
 
 static int bigmac_close(struct net_device *dev)
 {
-       struct bigmac *bp = (struct bigmac *) dev->priv;
+       struct bigmac *bp = netdev_priv(dev);
 
        del_timer(&bp->bigmac_timer);
        bp->timer_state = asleep;
@@ -948,7 +947,7 @@ static int bigmac_close(struct net_device *dev)
 
 static void bigmac_tx_timeout(struct net_device *dev)
 {
-       struct bigmac *bp = (struct bigmac *) dev->priv;
+       struct bigmac *bp = netdev_priv(dev);
 
        bigmac_init_hw(bp, 0);
        netif_wake_queue(dev);
@@ -957,7 +956,7 @@ static void bigmac_tx_timeout(struct net_device *dev)
 /* Put a packet on the wire. */
 static int bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct bigmac *bp = (struct bigmac *) dev->priv;
+       struct bigmac *bp = netdev_priv(dev);
        int len, entry;
        u32 mapping;
 
@@ -990,7 +989,7 @@ static int bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static struct net_device_stats *bigmac_get_stats(struct net_device *dev)
 {
-       struct bigmac *bp = (struct bigmac *) dev->priv;
+       struct bigmac *bp = netdev_priv(dev);
 
        bigmac_get_counters(bp, bp->bregs);
        return &bp->enet_stats;
@@ -998,7 +997,7 @@ static struct net_device_stats *bigmac_get_stats(struct net_device *dev)
 
 static void bigmac_set_multicast(struct net_device *dev)
 {
-       struct bigmac *bp = (struct bigmac *) dev->priv;
+       struct bigmac *bp = netdev_priv(dev);
        void __iomem *bregs = bp->bregs;
        struct dev_mc_list *dmi = dev->mc_list;
        char *addrs;
@@ -1061,7 +1060,7 @@ static void bigmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i
 
 static u32 bigmac_get_link(struct net_device *dev)
 {
-       struct bigmac *bp = dev->priv;
+       struct bigmac *bp = netdev_priv(dev);
 
        spin_lock_irq(&bp->lock);
        bp->sw_bmsr = bigmac_tcvr_read(bp, bp->tregs, BIGMAC_BMSR);
@@ -1081,7 +1080,6 @@ static int __devinit bigmac_ether_init(struct of_device *op,
        static int version_printed;
        struct net_device *dev;
        u8 bsizes, bsizes_more;
-       DECLARE_MAC_BUF(mac);
        struct bigmac *bp;
        int i;
 
@@ -1212,8 +1210,8 @@ static int __devinit bigmac_ether_init(struct of_device *op,
 
        dev_set_drvdata(&bp->bigmac_op->dev, bp);
 
-       printk(KERN_INFO "%s: BigMAC 100baseT Ethernet %s\n",
-              dev->name, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: BigMAC 100baseT Ethernet %pM\n",
+              dev->name, dev->dev_addr);
 
        return 0;
 
index f860ea150395871357639e4f457834fbf67408c1..698893b92003d0f5022a86ba43f12f3a0fa064ce 100644 (file)
@@ -468,7 +468,6 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
        int bar = 1;
 #endif
        int phy, phy_end, phy_idx = 0;
-       DECLARE_MAC_BUF(mac);
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -547,9 +546,9 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
        if (i)
                goto err_out_unmap_rx;
 
-       printk(KERN_INFO "%s: %s at %p, %s, IRQ %d.\n",
+       printk(KERN_INFO "%s: %s at %p, %pM, IRQ %d.\n",
               dev->name, pci_id_tbl[chip_idx].name, ioaddr,
-              print_mac(mac, dev->dev_addr), irq);
+              dev->dev_addr, irq);
 
        np->phys[0] = 1;                /* Default setting */
        np->mii_preamble_required++;
@@ -1351,7 +1350,6 @@ static void rx_poll(unsigned long data)
                        skb->protocol = eth_type_trans(skb, dev);
                        /* Note: checksum -> skb->ip_summed = CHECKSUM_UNNECESSARY; */
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                }
                entry = (entry + 1) % RX_RING_SIZE;
                received++;
index 4291458955ef7ac9ae1cf5201b3e72a998d61bde..44be8dfbcf171b33d582aad8b2421c2ff9203c39 100644 (file)
@@ -164,7 +164,7 @@ static u16 __phy_read(struct gem *gp, int phy_addr, int reg)
 
 static inline int _phy_read(struct net_device *dev, int mii_id, int reg)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
        return __phy_read(gp, mii_id, reg);
 }
 
@@ -197,7 +197,7 @@ static void __phy_write(struct gem *gp, int phy_addr, int reg, u16 val)
 
 static inline void _phy_write(struct net_device *dev, int mii_id, int reg, int val)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
        __phy_write(gp, mii_id, reg, val & 0xffff);
 }
 
@@ -863,7 +863,6 @@ static int gem_rx(struct gem *gp, int work_to_do)
 
                gp->net_stats.rx_packets++;
                gp->net_stats.rx_bytes += len;
-               gp->dev->last_rx = jiffies;
 
        next:
                entry = NEXT_RX(entry);
@@ -933,7 +932,7 @@ static int gem_poll(struct napi_struct *napi, int budget)
 static irqreturn_t gem_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
        unsigned long flags;
 
        /* Swallow interrupts when shutting the chip down, though
@@ -979,7 +978,7 @@ static void gem_poll_controller(struct net_device *dev)
 
 static void gem_tx_timeout(struct net_device *dev)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
 
        printk(KERN_ERR "%s: transmit timed out, resetting\n", dev->name);
        if (!gp->running) {
@@ -1018,7 +1017,7 @@ static __inline__ int gem_intme(int entry)
 
 static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
        int entry;
        u64 ctrl;
        unsigned long flags;
@@ -2191,7 +2190,7 @@ static void gem_stop_phy(struct gem *gp, int wol)
 
 static int gem_do_start(struct net_device *dev)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
        unsigned long flags;
 
        spin_lock_irqsave(&gp->lock, flags);
@@ -2238,7 +2237,7 @@ static int gem_do_start(struct net_device *dev)
 
 static void gem_do_stop(struct net_device *dev, int wol)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
        unsigned long flags;
 
        spin_lock_irqsave(&gp->lock, flags);
@@ -2313,7 +2312,7 @@ static void gem_reset_task(struct work_struct *work)
 
 static int gem_open(struct net_device *dev)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
        int rc = 0;
 
        mutex_lock(&gp->pm_mutex);
@@ -2332,7 +2331,7 @@ static int gem_open(struct net_device *dev)
 
 static int gem_close(struct net_device *dev)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
 
        mutex_lock(&gp->pm_mutex);
 
@@ -2351,7 +2350,7 @@ static int gem_close(struct net_device *dev)
 static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
        unsigned long flags;
 
        mutex_lock(&gp->pm_mutex);
@@ -2415,7 +2414,7 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
 static int gem_resume(struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
        unsigned long flags;
 
        printk(KERN_INFO "%s: resuming\n", dev->name);
@@ -2489,7 +2488,7 @@ static int gem_resume(struct pci_dev *pdev)
 
 static struct net_device_stats *gem_get_stats(struct net_device *dev)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
        struct net_device_stats *stats = &gp->net_stats;
 
        spin_lock_irq(&gp->lock);
@@ -2525,7 +2524,7 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev)
 static int gem_set_mac_address(struct net_device *dev, void *addr)
 {
        struct sockaddr *macaddr = (struct sockaddr *) addr;
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
        unsigned char *e = &dev->dev_addr[0];
 
        if (!is_valid_ether_addr(macaddr->sa_data))
@@ -2553,7 +2552,7 @@ static int gem_set_mac_address(struct net_device *dev, void *addr)
 
 static void gem_set_multicast(struct net_device *dev)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
        u32 rxcfg, rxcfg_new;
        int limit = 10000;
 
@@ -2602,7 +2601,7 @@ static void gem_set_multicast(struct net_device *dev)
 
 static int gem_change_mtu(struct net_device *dev, int new_mtu)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
 
        if (new_mtu < GEM_MIN_MTU || new_mtu > GEM_MAX_MTU)
                return -EINVAL;
@@ -2633,7 +2632,7 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu)
 
 static void gem_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
 
        strcpy(info->driver, DRV_NAME);
        strcpy(info->version, DRV_VERSION);
@@ -2642,7 +2641,7 @@ static void gem_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info
 
 static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
 
        if (gp->phy_type == phy_mii_mdio0 ||
            gp->phy_type == phy_mii_mdio1) {
@@ -2688,7 +2687,7 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 static int gem_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
 
        /* Verify the settings we care about. */
        if (cmd->autoneg != AUTONEG_ENABLE &&
@@ -2719,7 +2718,7 @@ static int gem_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 static int gem_nway_reset(struct net_device *dev)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
 
        if (!gp->want_autoneg)
                return -EINVAL;
@@ -2736,13 +2735,13 @@ static int gem_nway_reset(struct net_device *dev)
 
 static u32 gem_get_msglevel(struct net_device *dev)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
        return gp->msg_enable;
 }
 
 static void gem_set_msglevel(struct net_device *dev, u32 value)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
        gp->msg_enable = value;
 }
 
@@ -2754,7 +2753,7 @@ static void gem_set_msglevel(struct net_device *dev, u32 value)
 
 static void gem_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
 
        /* Add more when I understand how to program the chip */
        if (gp->has_wol) {
@@ -2768,7 +2767,7 @@ static void gem_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 
 static int gem_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
 
        if (!gp->has_wol)
                return -EOPNOTSUPP;
@@ -2790,7 +2789,7 @@ static const struct ethtool_ops gem_ethtool_ops = {
 
 static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = netdev_priv(dev);
        struct mii_ioctl_data *data = if_mii(ifr);
        int rc = -EOPNOTSUPP;
        unsigned long flags;
@@ -2922,7 +2921,7 @@ static void gem_remove_one(struct pci_dev *pdev)
        struct net_device *dev = pci_get_drvdata(pdev);
 
        if (dev) {
-               struct gem *gp = dev->priv;
+               struct gem *gp = netdev_priv(dev);
 
                unregister_netdev(dev);
 
@@ -2966,7 +2965,6 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
        struct net_device *dev;
        struct gem *gp;
        int err, pci_using_dac;
-       DECLARE_MAC_BUF(mac);
 
        if (gem_version_printed++ == 0)
                printk(KERN_INFO "%s", version);
@@ -3026,7 +3024,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
        }
        SET_NETDEV_DEV(dev, &pdev->dev);
 
-       gp = dev->priv;
+       gp = netdev_priv(dev);
 
        err = pci_request_regions(pdev, DRV_NAME);
        if (err) {
@@ -3150,9 +3148,8 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
                goto err_out_free_consistent;
        }
 
-       printk(KERN_INFO "%s: Sun GEM (PCI) 10/100/1000BaseT Ethernet "
-              "%s\n",
-              dev->name, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: Sun GEM (PCI) 10/100/1000BaseT Ethernet %pM\n",
+              dev->name, dev->dev_addr);
 
        if (gp->phy_type == phy_mii_mdio0 ||
            gp->phy_type == phy_mii_mdio1)
index f1ebeb5f65b2f56d6ba3a6ee9da9eb579cfb16d1..b22d3355fb45f7157328824390315fcf9013d372 100644 (file)
@@ -2072,7 +2072,6 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
                skb->protocol = eth_type_trans(skb, dev);
                netif_rx(skb);
 
-               dev->last_rx = jiffies;
                hp->net_stats.rx_packets++;
                hp->net_stats.rx_bytes += len;
        next:
@@ -2131,7 +2130,7 @@ static irqreturn_t quattro_sbus_interrupt(int irq, void *cookie)
 
        for (i = 0; i < 4; i++) {
                struct net_device *dev = qp->happy_meals[i];
-               struct happy_meal *hp  = dev->priv;
+               struct happy_meal *hp  = netdev_priv(dev);
                u32 happy_status       = hme_read32(hp, hp->gregs + GREG_STAT);
 
                HMD(("quattro_interrupt: status=%08x ", happy_status));
@@ -2176,7 +2175,7 @@ static irqreturn_t quattro_sbus_interrupt(int irq, void *cookie)
 
 static int happy_meal_open(struct net_device *dev)
 {
-       struct happy_meal *hp = dev->priv;
+       struct happy_meal *hp = netdev_priv(dev);
        int res;
 
        HMD(("happy_meal_open: "));
@@ -2208,7 +2207,7 @@ static int happy_meal_open(struct net_device *dev)
 
 static int happy_meal_close(struct net_device *dev)
 {
-       struct happy_meal *hp = dev->priv;
+       struct happy_meal *hp = netdev_priv(dev);
 
        spin_lock_irq(&hp->happy_lock);
        happy_meal_stop(hp, hp->gregs);
@@ -2237,7 +2236,7 @@ static int happy_meal_close(struct net_device *dev)
 
 static void happy_meal_tx_timeout(struct net_device *dev)
 {
-       struct happy_meal *hp = dev->priv;
+       struct happy_meal *hp = netdev_priv(dev);
 
        printk (KERN_ERR "%s: transmit timed out, resetting\n", dev->name);
        tx_dump_log();
@@ -2255,7 +2254,7 @@ static void happy_meal_tx_timeout(struct net_device *dev)
 
 static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct happy_meal *hp = dev->priv;
+       struct happy_meal *hp = netdev_priv(dev);
        int entry;
        u32 tx_flags;
 
@@ -2344,7 +2343,7 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static struct net_device_stats *happy_meal_get_stats(struct net_device *dev)
 {
-       struct happy_meal *hp = dev->priv;
+       struct happy_meal *hp = netdev_priv(dev);
 
        spin_lock_irq(&hp->happy_lock);
        happy_meal_get_counters(hp, hp->bigmacregs);
@@ -2355,7 +2354,7 @@ static struct net_device_stats *happy_meal_get_stats(struct net_device *dev)
 
 static void happy_meal_set_multicast(struct net_device *dev)
 {
-       struct happy_meal *hp = dev->priv;
+       struct happy_meal *hp = netdev_priv(dev);
        void __iomem *bregs = hp->bigmacregs;
        struct dev_mc_list *dmi = dev->mc_list;
        char *addrs;
@@ -2401,7 +2400,7 @@ static void happy_meal_set_multicast(struct net_device *dev)
 /* Ethtool support... */
 static int hme_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-       struct happy_meal *hp = dev->priv;
+       struct happy_meal *hp = netdev_priv(dev);
 
        cmd->supported =
                (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
@@ -2446,7 +2445,7 @@ static int hme_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 static int hme_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-       struct happy_meal *hp = dev->priv;
+       struct happy_meal *hp = netdev_priv(dev);
 
        /* Verify the settings we care about. */
        if (cmd->autoneg != AUTONEG_ENABLE &&
@@ -2470,7 +2469,7 @@ static int hme_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 static void hme_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-       struct happy_meal *hp = dev->priv;
+       struct happy_meal *hp = netdev_priv(dev);
 
        strcpy(info->driver, "sunhme");
        strcpy(info->version, "2.02");
@@ -2492,7 +2491,7 @@ static void hme_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info
 
 static u32 hme_get_link(struct net_device *dev)
 {
-       struct happy_meal *hp = dev->priv;
+       struct happy_meal *hp = netdev_priv(dev);
 
        spin_lock_irq(&hp->happy_lock);
        hp->sw_bmcr = happy_meal_tcvr_read(hp, hp->tcvregs, MII_BMCR);
@@ -2617,7 +2616,6 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe)
        struct net_device *dev;
        int i, qfe_slot = -1;
        int err = -ENODEV;
-       DECLARE_MAC_BUF(mac);
 
        if (is_qfe) {
                qp = quattro_sbus_find(op);
@@ -2797,7 +2795,7 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe)
                printk(KERN_INFO "%s: HAPPY MEAL (SBUS) 10/100baseT Ethernet ",
                       dev->name);
 
-       printk("%s\n", print_mac(mac, dev->dev_addr));
+       printk("%pM\n", dev->dev_addr);
 
        return 0;
 
@@ -2932,7 +2930,6 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
        int i, qfe_slot = -1;
        char prom_name[64];
        int err;
-       DECLARE_MAC_BUF(mac);
 
        /* Now make sure pci_dev cookie is there. */
 #ifdef CONFIG_SPARC
@@ -2973,7 +2970,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
 
        dev->base_addr = (long) pdev;
 
-       hp = (struct happy_meal *)dev->priv;
+       hp = netdev_priv(dev);
        memset(hp, 0, sizeof(*hp));
 
        hp->happy_dev = pdev;
@@ -3141,7 +3138,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
                printk(KERN_INFO "%s: HAPPY MEAL (PCI/CheerIO) 10/100BaseT Ethernet ",
                       dev->name);
 
-       printk("%s\n", print_mac(mac, dev->dev_addr));
+       printk("%pM\n", dev->dev_addr);
 
        return 0;
 
index 704301a5a7ffed417655912cbc0a61552d55bf71..281373281756e381d24125eb841f903eda0a8286 100644 (file)
@@ -555,7 +555,6 @@ static void lance_rx_dvma(struct net_device *dev)
                                         len);
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                }
 
@@ -726,7 +725,6 @@ static void lance_rx_pio(struct net_device *dev)
                        lance_piocopy_to_skb(skb, &(ib->rx_buf[entry][0]), len);
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                }
 
@@ -1321,7 +1319,6 @@ static int __devinit sparc_lance_probe_one(struct of_device *op,
        static unsigned version_printed;
        struct lance_private *lp;
        struct net_device *dev;
-       DECLARE_MAC_BUF(mac);
        int    i;
 
        dev = alloc_etherdev(sizeof(struct lance_private) + 8);
@@ -1491,8 +1488,8 @@ no_link_test:
 
        dev_set_drvdata(&op->dev, lp);
 
-       printk(KERN_INFO "%s: LANCE %s\n",
-              dev->name, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: LANCE %pM\n",
+              dev->name, dev->dev_addr);
 
        return 0;
 
index f63644744ff9dafafb56eb746d3acf5018b3733f..6e8f377355fe8a6e98ab28676c0fa09671bc501a 100644 (file)
@@ -446,7 +446,6 @@ static void qe_rx(struct sunqe *qep)
                                                 len);
                                skb->protocol = eth_type_trans(skb, qep->dev);
                                netif_rx(skb);
-                               qep->dev->last_rx = jiffies;
                                dev->stats.rx_packets++;
                                dev->stats.rx_bytes += len;
                        }
@@ -513,7 +512,7 @@ static irqreturn_t qec_interrupt(int irq, void *dev_id)
 
 static int qe_open(struct net_device *dev)
 {
-       struct sunqe *qep = (struct sunqe *) dev->priv;
+       struct sunqe *qep = netdev_priv(dev);
 
        qep->mconfig = (MREGS_MCONFIG_TXENAB |
                        MREGS_MCONFIG_RXENAB |
@@ -523,7 +522,7 @@ static int qe_open(struct net_device *dev)
 
 static int qe_close(struct net_device *dev)
 {
-       struct sunqe *qep = (struct sunqe *) dev->priv;
+       struct sunqe *qep = netdev_priv(dev);
 
        qe_stop(qep);
        return 0;
@@ -549,7 +548,7 @@ static void qe_tx_reclaim(struct sunqe *qep)
 
 static void qe_tx_timeout(struct net_device *dev)
 {
-       struct sunqe *qep = (struct sunqe *) dev->priv;
+       struct sunqe *qep = netdev_priv(dev);
        int tx_full;
 
        spin_lock_irq(&qep->lock);
@@ -575,7 +574,7 @@ out:
 /* Get a packet queued to go onto the wire. */
 static int qe_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct sunqe *qep = (struct sunqe *) dev->priv;
+       struct sunqe *qep = netdev_priv(dev);
        struct sunqe_buffers *qbufs = qep->buffers;
        __u32 txbuf_dvma, qbufs_dvma = qep->buffers_dvma;
        unsigned char *txbuf;
@@ -627,7 +626,7 @@ static int qe_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static void qe_set_multicast(struct net_device *dev)
 {
-       struct sunqe *qep = (struct sunqe *) dev->priv;
+       struct sunqe *qep = netdev_priv(dev);
        struct dev_mc_list *dmi = dev->mc_list;
        u8 new_mconfig = qep->mconfig;
        char *addrs;
@@ -693,7 +692,7 @@ static void qe_set_multicast(struct net_device *dev)
 static void qe_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
        const struct linux_prom_registers *regs;
-       struct sunqe *qep = dev->priv;
+       struct sunqe *qep = netdev_priv(dev);
        struct of_device *op;
 
        strcpy(info->driver, "sunqe");
@@ -708,7 +707,7 @@ static void qe_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 
 static u32 qe_get_link(struct net_device *dev)
 {
-       struct sunqe *qep = dev->priv;
+       struct sunqe *qep = netdev_priv(dev);
        void __iomem *mregs = qep->mregs;
        u8 phyconfig;
 
index a720065553df48645f121c86b11bcf8bf5c61e52..233f1cda36e52b425e952ba823a02bfe11c1ab81 100644 (file)
@@ -1149,7 +1149,6 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev,
        struct vnet *vp;
        const u64 *rmac;
        int len, i, err, switch_port;
-       DECLARE_MAC_BUF(mac);
 
        print_version();
 
@@ -1214,8 +1213,8 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev,
 
        dev_set_drvdata(&vdev->dev, port);
 
-       printk(KERN_INFO "%s: PORT ( remote-mac %s%s )\n",
-              vp->dev->name, print_mac(mac, port->raddr),
+       printk(KERN_INFO "%s: PORT ( remote-mac %pM%s )\n",
+              vp->dev->name, port->raddr,
               switch_port ? " switch-port" : "");
 
        vio_port_up(&port->vio);
index df20cafff7dd3a5da1926740e5cb14193f5b81f9..44126c463fac8870f9b109f5aaedd9e87b0fdda0 100644 (file)
@@ -236,7 +236,7 @@ struct tc35815_regs {
 #define Rx_Halted             0x00008000 /* Rx Halted                       */
 #define Rx_Good                       0x00004000 /* Rx Good                         */
 #define Rx_RxPar              0x00002000 /* Rx Parity Error                 */
-                           /* 0x00001000    not use                         */
+#define Rx_TypePkt            0x00001000 /* Rx Type Packet                  */
 #define Rx_LongErr            0x00000800 /* Rx Long Error                   */
 #define Rx_Over                       0x00000400 /* Rx Overflow                     */
 #define Rx_CRCErr             0x00000200 /* Rx CRC Error                    */
@@ -244,8 +244,9 @@ struct tc35815_regs {
 #define Rx_10Stat             0x00000080 /* Rx 10Mbps Status                */
 #define Rx_IntRx              0x00000040 /* Rx Interrupt                    */
 #define Rx_CtlRecd            0x00000020 /* Rx Control Receive              */
+#define Rx_InLenErr           0x00000010 /* Rx In Range Frame Length Error  */
 
-#define Rx_Stat_Mask          0x0000EFC0 /* Rx All Status Mask              */
+#define Rx_Stat_Mask          0x0000FFF0 /* Rx All Status Mask              */
 
 /* Int_En bit asign -------------------------------------------------------- */
 #define Int_NRAbtEn           0x00000800 /* 1:Non-recoverable Abort Enable  */
@@ -865,7 +866,6 @@ static int __devinit tc35815_init_one(struct pci_dev *pdev,
        struct net_device *dev;
        struct tc35815_local *lp;
        int rc;
-       DECLARE_MAC_BUF(mac);
 
        static int printed_version;
        if (!printed_version++) {
@@ -942,11 +942,11 @@ static int __devinit tc35815_init_one(struct pci_dev *pdev,
                goto err_out;
 
        memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
-       printk(KERN_INFO "%s: %s at 0x%lx, %s, IRQ %d\n",
+       printk(KERN_INFO "%s: %s at 0x%lx, %pM, IRQ %d\n",
                dev->name,
                chip_info[ent->driver_data].name,
                dev->base_addr,
-               print_mac(mac, dev->dev_addr),
+               dev->dev_addr,
                dev->irq);
 
        rc = tc_mii_init(dev);
@@ -1288,12 +1288,9 @@ panic_queues(struct net_device *dev)
 
 static void print_eth(const u8 *add)
 {
-       DECLARE_MAC_BUF(mac);
-
        printk(KERN_DEBUG "print_eth(%p)\n", add);
-       printk(KERN_DEBUG " %s =>", print_mac(mac, add + 6));
-       printk(KERN_CONT " %s : %02x%02x\n",
-               print_mac(mac, add), add[12], add[13]);
+       printk(KERN_DEBUG " %pM => %pM : %02x%02x\n",
+               add + 6, add, add[12], add[13]);
 }
 
 static int tc35815_tx_full(struct net_device *dev)
@@ -1760,7 +1757,6 @@ tc35815_rx(struct net_device *dev)
 #else
                        netif_rx(skb);
 #endif
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                        dev->stats.rx_bytes += pkt_len;
                } else {
@@ -2153,13 +2149,12 @@ static void tc35815_set_cam_entry(struct net_device *dev, int index, unsigned ch
        int cam_index = index * 6;
        u32 cam_data;
        u32 saved_addr;
-       DECLARE_MAC_BUF(mac);
 
        saved_addr = tc_readl(&tr->CAM_Adr);
 
        if (netif_msg_hw(lp))
-               printk(KERN_DEBUG "%s: CAM %d: %s\n",
-                       dev->name, index, print_mac(mac, addr));
+               printk(KERN_DEBUG "%s: CAM %d: %pM\n",
+                       dev->name, index, addr);
        if (index & 1) {
                /* read modify write */
                tc_writel(cam_index - 2, &tr->CAM_Adr);
index 91f9054a1d9522b5f60f0347d6264beeba8d4c60..7e36a10423f9cdaddd85b799e17eee4a174f870d 100644 (file)
@@ -251,7 +251,7 @@ static void bdx_isr_extra(struct bdx_priv *priv, u32 isr)
 static irqreturn_t bdx_isr_napi(int irq, void *dev)
 {
        struct net_device *ndev = dev;
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
        u32 isr;
 
        ENTER;
@@ -559,7 +559,7 @@ static int bdx_close(struct net_device *ndev)
        struct bdx_priv *priv = NULL;
 
        ENTER;
-       priv = ndev->priv;
+       priv = netdev_priv(ndev);
 
        napi_disable(&priv->napi);
 
@@ -588,7 +588,7 @@ static int bdx_open(struct net_device *ndev)
        int rc;
 
        ENTER;
-       priv = ndev->priv;
+       priv = netdev_priv(ndev);
        bdx_reset(priv);
        if (netif_running(ndev))
                netif_stop_queue(priv->ndev);
@@ -633,7 +633,7 @@ static int bdx_range_check(struct bdx_priv *priv, u32 offset)
 
 static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd)
 {
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
        u32 data[3];
        int error;
 
@@ -698,7 +698,7 @@ static int bdx_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
  */
 static void __bdx_vlan_rx_vid(struct net_device *ndev, uint16_t vid, int enable)
 {
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
        u32 reg, bit, val;
 
        ENTER;
@@ -748,7 +748,7 @@ static void bdx_vlan_rx_kill_vid(struct net_device *ndev, unsigned short vid)
 static void
 bdx_vlan_rx_register(struct net_device *ndev, struct vlan_group *grp)
 {
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
 
        ENTER;
        DBG("device='%s', group='%p'\n", ndev->name, grp);
@@ -787,7 +787,7 @@ static int bdx_change_mtu(struct net_device *ndev, int new_mtu)
 
 static void bdx_setmulti(struct net_device *ndev)
 {
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
 
        u32 rxf_val =
            GMAC_RX_FILTER_AM | GMAC_RX_FILTER_AB | GMAC_RX_FILTER_OSEN;
@@ -847,7 +847,7 @@ static void bdx_setmulti(struct net_device *ndev)
 
 static int bdx_set_mac(struct net_device *ndev, void *p)
 {
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
        struct sockaddr *addr = p;
 
        ENTER;
@@ -929,7 +929,7 @@ static void bdx_update_stats(struct bdx_priv *priv)
 
 static struct net_device_stats *bdx_get_stats(struct net_device *ndev)
 {
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
        struct net_device_stats *net_stat = &priv->net_stats;
        return net_stat;
 }
@@ -1237,7 +1237,6 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
        ENTER;
        max_done = budget;
 
-       priv->ndev->last_rx = jiffies;
        f->m.wptr = READ_REG(priv, f->m.reg_WPTR) & TXF_WPTR_WR_PTR;
 
        size = f->m.wptr - f->m.rptr;
@@ -1624,7 +1623,7 @@ static inline int bdx_tx_space(struct bdx_priv *priv)
  */
 static int bdx_tx_transmit(struct sk_buff *skb, struct net_device *ndev)
 {
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
        struct txd_fifo *f = &priv->txd_fifo0;
        int txd_checksum = 7;   /* full checksum */
        int txd_lgsnd = 0;
@@ -2027,7 +2026,7 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                        ndev->features |= NETIF_F_HIGHDMA;
 
        /************** priv ****************/
-               priv = nic->priv[port] = ndev->priv;
+               priv = nic->priv[port] = netdev_priv(ndev);
 
                memset(priv, 0, sizeof(struct bdx_priv));
                priv->pBdxRegs = nic->regs + port * 0x8000;
@@ -2150,7 +2149,7 @@ static int bdx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
        u32 rdintcm;
        u32 tdintcm;
-       struct bdx_priv *priv = netdev->priv;
+       struct bdx_priv *priv = netdev_priv(netdev);
 
        rdintcm = priv->rdintcm;
        tdintcm = priv->tdintcm;
@@ -2181,7 +2180,7 @@ static int bdx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 static void
 bdx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
 {
-       struct bdx_priv *priv = netdev->priv;
+       struct bdx_priv *priv = netdev_priv(netdev);
 
        strlcat(drvinfo->driver, BDX_DRV_NAME, sizeof(drvinfo->driver));
        strlcat(drvinfo->version, BDX_DRV_VERSION, sizeof(drvinfo->version));
@@ -2223,7 +2222,7 @@ bdx_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *ecoal)
 {
        u32 rdintcm;
        u32 tdintcm;
-       struct bdx_priv *priv = netdev->priv;
+       struct bdx_priv *priv = netdev_priv(netdev);
 
        rdintcm = priv->rdintcm;
        tdintcm = priv->tdintcm;
@@ -2252,7 +2251,7 @@ bdx_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ecoal)
 {
        u32 rdintcm;
        u32 tdintcm;
-       struct bdx_priv *priv = netdev->priv;
+       struct bdx_priv *priv = netdev_priv(netdev);
        int rx_coal;
        int tx_coal;
        int rx_max_coal;
@@ -2310,7 +2309,7 @@ static inline int bdx_tx_fifo_size_to_packets(int tx_size)
 static void
 bdx_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
 {
-       struct bdx_priv *priv = netdev->priv;
+       struct bdx_priv *priv = netdev_priv(netdev);
 
        /*max_pending - the maximum-sized FIFO we allow */
        ring->rx_max_pending = bdx_rx_fifo_size_to_packets(3);
@@ -2327,7 +2326,7 @@ bdx_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
 static int
 bdx_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
 {
-       struct bdx_priv *priv = netdev->priv;
+       struct bdx_priv *priv = netdev_priv(netdev);
        int rx_size = 0;
        int tx_size = 0;
 
@@ -2388,7 +2387,7 @@ static void bdx_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
  */
 static int bdx_get_stats_count(struct net_device *netdev)
 {
-       struct bdx_priv *priv = netdev->priv;
+       struct bdx_priv *priv = netdev_priv(netdev);
        BDX_ASSERT(ARRAY_SIZE(bdx_stat_names)
                   != sizeof(struct bdx_stats) / sizeof(u64));
        return ((priv->stats_flag) ? ARRAY_SIZE(bdx_stat_names) : 0);
@@ -2403,7 +2402,7 @@ static int bdx_get_stats_count(struct net_device *netdev)
 static void bdx_get_ethtool_stats(struct net_device *netdev,
                                  struct ethtool_stats *stats, u64 *data)
 {
-       struct bdx_priv *priv = netdev->priv;
+       struct bdx_priv *priv = netdev_priv(netdev);
 
        if (priv->stats_flag) {
 
index eb9f8f3638e1923bf664f55bdbf4de9e32621a47..e05849ee9000fe93dab53ca869097f43c04af95f 100644 (file)
@@ -54,6 +54,9 @@
 #include <asm/prom.h>
 #endif
 
+#define BAR_0  0
+#define BAR_2  2
+
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 #define TG3_VLAN_TAG_USED 1
 #else
@@ -66,8 +69,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.94"
-#define DRV_MODULE_RELDATE     "August 14, 2008"
+#define DRV_MODULE_VERSION     "3.95"
+#define DRV_MODULE_RELDATE     "November 3, 2008"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -205,6 +208,8 @@ static struct pci_device_id tg3_pci_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5723)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761E)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761S)},
+       {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761SE)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5785)},
        {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
        {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
@@ -872,13 +877,48 @@ static int tg3_mdio_reset(struct mii_bus *bp)
        return 0;
 }
 
-static void tg3_mdio_config(struct tg3 *tp)
+static void tg3_mdio_config_5785(struct tg3 *tp)
 {
        u32 val;
+       struct phy_device *phydev;
+
+       phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+       switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
+       case TG3_PHY_ID_BCM50610:
+               val = MAC_PHYCFG2_50610_LED_MODES;
+               break;
+       case TG3_PHY_ID_BCMAC131:
+               val = MAC_PHYCFG2_AC131_LED_MODES;
+               break;
+       case TG3_PHY_ID_RTL8211C:
+               val = MAC_PHYCFG2_RTL8211C_LED_MODES;
+               break;
+       case TG3_PHY_ID_RTL8201E:
+               val = MAC_PHYCFG2_RTL8201E_LED_MODES;
+               break;
+       default:
+               return;
+       }
+
+       if (phydev->interface != PHY_INTERFACE_MODE_RGMII) {
+               tw32(MAC_PHYCFG2, val);
+
+               val = tr32(MAC_PHYCFG1);
+               val &= ~MAC_PHYCFG1_RGMII_INT;
+               tw32(MAC_PHYCFG1, val);
 
-       if (tp->mdio_bus->phy_map[PHY_ADDR]->interface !=
-           PHY_INTERFACE_MODE_RGMII)
                return;
+       }
+
+       if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE))
+               val |= MAC_PHYCFG2_EMODE_MASK_MASK |
+                      MAC_PHYCFG2_FMODE_MASK_MASK |
+                      MAC_PHYCFG2_GMODE_MASK_MASK |
+                      MAC_PHYCFG2_ACT_MASK_MASK   |
+                      MAC_PHYCFG2_QUAL_MASK_MASK |
+                      MAC_PHYCFG2_INBAND_ENABLE;
+
+       tw32(MAC_PHYCFG2, val);
 
        val = tr32(MAC_PHYCFG1) & ~(MAC_PHYCFG1_RGMII_EXT_RX_DEC |
                                    MAC_PHYCFG1_RGMII_SND_STAT_EN);
@@ -890,11 +930,6 @@ static void tg3_mdio_config(struct tg3 *tp)
        }
        tw32(MAC_PHYCFG1, val | MAC_PHYCFG1_RGMII_INT | MAC_PHYCFG1_TXC_DRV);
 
-       val = tr32(MAC_PHYCFG2) & ~(MAC_PHYCFG2_INBAND_ENABLE);
-       if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE))
-               val |= MAC_PHYCFG2_INBAND_ENABLE;
-       tw32(MAC_PHYCFG2, val);
-
        val = tr32(MAC_EXT_RGMII_MODE);
        val &= ~(MAC_RGMII_MODE_RX_INT_B |
                 MAC_RGMII_MODE_RX_QUALITY |
@@ -903,7 +938,7 @@ static void tg3_mdio_config(struct tg3 *tp)
                 MAC_RGMII_MODE_TX_ENABLE |
                 MAC_RGMII_MODE_TX_LOWPWR |
                 MAC_RGMII_MODE_TX_RESET);
-       if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE) {
+       if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)) {
                if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
                        val |= MAC_RGMII_MODE_RX_INT_B |
                               MAC_RGMII_MODE_RX_QUALITY |
@@ -929,8 +964,9 @@ static void tg3_mdio_start(struct tg3 *tp)
        tw32_f(MAC_MI_MODE, tp->mi_mode);
        udelay(80);
 
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED)
-               tg3_mdio_config(tp);
+       if ((tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) &&
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+               tg3_mdio_config_5785(tp);
 }
 
 static void tg3_mdio_stop(struct tg3 *tp)
@@ -984,29 +1020,41 @@ static int tg3_mdio_init(struct tg3 *tp)
        if (i) {
                printk(KERN_WARNING "%s: mdiobus_reg failed (0x%x)\n",
                        tp->dev->name, i);
+               mdiobus_free(tp->mdio_bus);
                return i;
        }
 
-       tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED;
-
        phydev = tp->mdio_bus->phy_map[PHY_ADDR];
 
-       switch (phydev->phy_id) {
+       if (!phydev || !phydev->drv) {
+               printk(KERN_WARNING "%s: No PHY devices\n", tp->dev->name);
+               mdiobus_unregister(tp->mdio_bus);
+               mdiobus_free(tp->mdio_bus);
+               return -ENODEV;
+       }
+
+       switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
        case TG3_PHY_ID_BCM50610:
-               phydev->interface = PHY_INTERFACE_MODE_RGMII;
                if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)
                        phydev->dev_flags |= PHY_BRCM_STD_IBND_DISABLE;
                if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
                        phydev->dev_flags |= PHY_BRCM_EXT_IBND_RX_ENABLE;
                if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
                        phydev->dev_flags |= PHY_BRCM_EXT_IBND_TX_ENABLE;
+               /* fallthru */
+       case TG3_PHY_ID_RTL8211C:
+               phydev->interface = PHY_INTERFACE_MODE_RGMII;
                break;
+       case TG3_PHY_ID_RTL8201E:
        case TG3_PHY_ID_BCMAC131:
                phydev->interface = PHY_INTERFACE_MODE_MII;
                break;
        }
 
-       tg3_mdio_config(tp);
+       tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED;
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+               tg3_mdio_config_5785(tp);
 
        return 0;
 }
@@ -1299,6 +1347,15 @@ static void tg3_adjust_link(struct net_device *dev)
                udelay(40);
        }
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
+               if (phydev->speed == SPEED_10)
+                       tw32(MAC_MI_STAT,
+                            MAC_MI_STAT_10MBPS_MODE |
+                            MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
+               else
+                       tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
+       }
+
        if (phydev->speed == SPEED_1000 && phydev->duplex == DUPLEX_HALF)
                tw32(MAC_TX_LENGTHS,
                     ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
@@ -1339,25 +1396,34 @@ static int tg3_phy_init(struct tg3 *tp)
        phydev = tp->mdio_bus->phy_map[PHY_ADDR];
 
        /* Attach the MAC to the PHY. */
-       phydev = phy_connect(tp->dev, phydev->dev.bus_id, tg3_adjust_link,
+       phydev = phy_connect(tp->dev, dev_name(&phydev->dev), tg3_adjust_link,
                             phydev->dev_flags, phydev->interface);
        if (IS_ERR(phydev)) {
                printk(KERN_ERR "%s: Could not attach to PHY\n", tp->dev->name);
                return PTR_ERR(phydev);
        }
 
-       tp->tg3_flags3 |= TG3_FLG3_PHY_CONNECTED;
-
        /* Mask with MAC supported features. */
-       phydev->supported &= (PHY_GBIT_FEATURES |
-                             SUPPORTED_Pause |
-                             SUPPORTED_Asym_Pause);
+       switch (phydev->interface) {
+       case PHY_INTERFACE_MODE_GMII:
+       case PHY_INTERFACE_MODE_RGMII:
+               phydev->supported &= (PHY_GBIT_FEATURES |
+                                     SUPPORTED_Pause |
+                                     SUPPORTED_Asym_Pause);
+               break;
+       case PHY_INTERFACE_MODE_MII:
+               phydev->supported &= (PHY_BASIC_FEATURES |
+                                     SUPPORTED_Pause |
+                                     SUPPORTED_Asym_Pause);
+               break;
+       default:
+               phy_disconnect(tp->mdio_bus->phy_map[PHY_ADDR]);
+               return -EINVAL;
+       }
 
-       phydev->advertising = phydev->supported;
+       tp->tg3_flags3 |= TG3_FLG3_PHY_CONNECTED;
 
-       printk(KERN_INFO
-              "%s: attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
-              tp->dev->name, phydev->drv->name, phydev->dev.bus_id);
+       phydev->advertising = phydev->supported;
 
        return 0;
 }
@@ -1737,7 +1803,8 @@ static int tg3_phy_reset(struct tg3 *tp)
                tw32(TG3_CPMU_CTRL, cpmuctrl);
        }
 
-       if (tp->tg3_flags3 & TG3_FLG3_5761_5784_AX_FIXES) {
+       if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX ||
+           GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5761_AX) {
                u32 val;
 
                val = tr32(TG3_CPMU_LSPD_1000MB_CLK);
@@ -1961,7 +2028,7 @@ static int tg3_halt_cpu(struct tg3 *, u32);
 static int tg3_nvram_lock(struct tg3 *);
 static void tg3_nvram_unlock(struct tg3 *);
 
-static void tg3_power_down_phy(struct tg3 *tp)
+static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
 {
        u32 val;
 
@@ -1984,10 +2051,15 @@ static void tg3_power_down_phy(struct tg3 *tp)
                tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ);
                udelay(40);
                return;
-       } else if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
+       } else if (do_low_power) {
                tg3_writephy(tp, MII_TG3_EXT_CTRL,
                             MII_TG3_EXT_CTRL_FORCE_LED_OFF);
-               tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
+
+               tg3_writephy(tp, MII_TG3_AUX_CTRL,
+                            MII_TG3_AUXCTL_SHDWSEL_PWRCTL |
+                            MII_TG3_AUXCTL_PCTL_100TX_LPWR |
+                            MII_TG3_AUXCTL_PCTL_SPR_ISOLATE |
+                            MII_TG3_AUXCTL_PCTL_VREG_11V);
        }
 
        /* The PHY should not be powered down on some chips because
@@ -1999,7 +2071,8 @@ static void tg3_power_down_phy(struct tg3 *tp)
             (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)))
                return;
 
-       if (tp->tg3_flags3 & TG3_FLG3_5761_5784_AX_FIXES) {
+       if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX ||
+           GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5761_AX) {
                val = tr32(TG3_CPMU_LSPD_1000MB_CLK);
                val &= ~CPMU_LSPD_1000MB_MACCLK_MASK;
                val |= CPMU_LSPD_1000MB_MACCLK_12_5;
@@ -2009,9 +2082,47 @@ static void tg3_power_down_phy(struct tg3 *tp)
        tg3_writephy(tp, MII_BMCR, BMCR_PDOWN);
 }
 
+/* tp->lock is held. */
+static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
+{
+       u32 addr_high, addr_low;
+       int i;
+
+       addr_high = ((tp->dev->dev_addr[0] << 8) |
+                    tp->dev->dev_addr[1]);
+       addr_low = ((tp->dev->dev_addr[2] << 24) |
+                   (tp->dev->dev_addr[3] << 16) |
+                   (tp->dev->dev_addr[4] <<  8) |
+                   (tp->dev->dev_addr[5] <<  0));
+       for (i = 0; i < 4; i++) {
+               if (i == 1 && skip_mac_1)
+                       continue;
+               tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high);
+               tw32(MAC_ADDR_0_LOW + (i * 8), addr_low);
+       }
+
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
+               for (i = 0; i < 12; i++) {
+                       tw32(MAC_EXTADDR_0_HIGH + (i * 8), addr_high);
+                       tw32(MAC_EXTADDR_0_LOW + (i * 8), addr_low);
+               }
+       }
+
+       addr_high = (tp->dev->dev_addr[0] +
+                    tp->dev->dev_addr[1] +
+                    tp->dev->dev_addr[2] +
+                    tp->dev->dev_addr[3] +
+                    tp->dev->dev_addr[4] +
+                    tp->dev->dev_addr[5]) &
+               TX_BACKOFF_SEED_MASK;
+       tw32(MAC_TX_BACKOFF_SEED, addr_high);
+}
+
 static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
 {
        u32 misc_host_ctrl;
+       bool device_should_wake, do_low_power;
 
        /* Make sure register accesses (indirect or otherwise)
         * will function correctly.
@@ -2045,11 +2156,16 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
        tw32(TG3PCI_MISC_HOST_CTRL,
             misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
 
+       device_should_wake = pci_pme_capable(tp->pdev, state) &&
+                            device_may_wakeup(&tp->pdev->dev) &&
+                            (tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
+
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+               do_low_power = false;
                if ((tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) &&
                    !tp->link_config.phy_is_low_power) {
                        struct phy_device *phydev;
-                       u32 advertising;
+                       u32 phyid, advertising;
 
                        phydev = tp->mdio_bus->phy_map[PHY_ADDR];
 
@@ -2066,7 +2182,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                                      ADVERTISED_10baseT_Half;
 
                        if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
-                           (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) {
+                           device_should_wake) {
                                if (tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB)
                                        advertising |=
                                                ADVERTISED_100baseT_Half |
@@ -2079,8 +2195,19 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                        phydev->advertising = advertising;
 
                        phy_start_aneg(phydev);
+
+                       phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask;
+                       if (phyid != TG3_PHY_ID_BCMAC131) {
+                               phyid &= TG3_PHY_OUI_MASK;
+                               if (phyid == TG3_PHY_OUI_1 &&
+                                   phyid == TG3_PHY_OUI_2 &&
+                                   phyid == TG3_PHY_OUI_3)
+                                       do_low_power = true;
+                       }
                }
        } else {
+               do_low_power = false;
+
                if (tp->link_config.phy_is_low_power == 0) {
                        tp->link_config.phy_is_low_power = 1;
                        tp->link_config.orig_speed = tp->link_config.speed;
@@ -2096,6 +2223,8 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                }
        }
 
+       __tg3_set_mac_addr(tp, 0);
+
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
                u32 val;
 
@@ -2118,11 +2247,11 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                                                     WOL_DRV_WOL |
                                                     WOL_SET_MAGIC_PKT);
 
-       if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) {
+       if (device_should_wake) {
                u32 mac_mode;
 
                if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
-                       if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
+                       if (do_low_power) {
                                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
                                udelay(40);
                        }
@@ -2150,9 +2279,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                if (!(tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
                        tw32(MAC_LED_CTRL, tp->led_ctrl);
 
-               if (pci_pme_capable(tp->pdev, state) &&
-                    (tp->tg3_flags & TG3_FLAG_WOL_ENABLE))
-                       mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
+               mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
+               if (((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
+                   !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) &&
+                   ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
+                    (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)))
+                       mac_mode |= MAC_MODE_KEEP_FRAME_IN_WOL;
 
                if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
                        mac_mode |= tp->mac_mode &
@@ -2224,10 +2356,10 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                }
        }
 
-       if (!(tp->tg3_flags & TG3_FLAG_WOL_ENABLE) &&
+       if (!(device_should_wake) &&
            !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
            !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
-               tg3_power_down_phy(tp);
+               tg3_power_down_phy(tp, do_low_power);
 
        tg3_frob_aux_power(tp);
 
@@ -2250,7 +2382,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
 
        tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
 
-       if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)
+       if (device_should_wake)
                pci_enable_wake(tp->pdev, state, true);
 
        /* Finally, set the new power state. */
@@ -3765,8 +3897,7 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
                err = tg3_setup_copper_phy(tp, force_reset);
        }
 
-       if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
-           tp->pci_chip_rev_id == CHIPREV_ID_5784_A1) {
+       if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX) {
                u32 val, scale;
 
                val = tr32(TG3_CPMU_CLCK_STAT) & CPMU_CLCK_STAT_MAC_CLCK_MASK;
@@ -4157,7 +4288,6 @@ static int tg3_rx(struct tg3 *tp, int budget)
 #endif
                        netif_receive_skb(skb);
 
-               tp->dev->last_rx = jiffies;
                received++;
                budget--;
 
@@ -5557,6 +5687,13 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind)
                        event = APE_EVENT_STATUS_STATE_START;
                        break;
                case RESET_KIND_SHUTDOWN:
+                       /* With the interface we are currently using,
+                        * APE does not track driver state.  Wiping
+                        * out the HOST SEGMENT SIGNATURE forces
+                        * the APE to assume OS absent status.
+                        */
+                       tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, 0x0);
+
                        event = APE_EVENT_STATUS_STATE_UNLOAD;
                        break;
                case RESET_KIND_SUSPEND:
@@ -5721,13 +5858,15 @@ static void tg3_restore_pci_state(struct tg3 *tp)
 
        pci_write_config_word(tp->pdev, PCI_COMMAND, tp->pci_cmd);
 
-       if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)
-               pcie_set_readrq(tp->pdev, 4096);
-       else {
-               pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
-                                     tp->pci_cacheline_sz);
-               pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER,
-                                     tp->pci_lat_timer);
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) {
+               if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)
+                       pcie_set_readrq(tp->pdev, 4096);
+               else {
+                       pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
+                                             tp->pci_cacheline_sz);
+                       pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER,
+                                             tp->pci_lat_timer);
+               }
        }
 
        /* Make sure PCI-X relaxed ordering bit is clear. */
@@ -5884,8 +6023,9 @@ static int tg3_chip_reset(struct tg3 *tp)
                        pci_write_config_dword(tp->pdev, 0xc4,
                                               cfg_val | (1 << 15));
                }
-               /* Set PCIE max payload size and clear error status.  */
-               pci_write_config_dword(tp->pdev, 0xd8, 0xf5000);
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785)
+                       /* Set PCIE max payload size and clear error status.  */
+                       pci_write_config_dword(tp->pdev, 0xd8, 0xf5000);
        }
 
        tg3_restore_pci_state(tp);
@@ -6883,43 +7023,6 @@ static int tg3_load_tso_firmware(struct tg3 *tp)
 }
 
 
-/* tp->lock is held. */
-static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
-{
-       u32 addr_high, addr_low;
-       int i;
-
-       addr_high = ((tp->dev->dev_addr[0] << 8) |
-                    tp->dev->dev_addr[1]);
-       addr_low = ((tp->dev->dev_addr[2] << 24) |
-                   (tp->dev->dev_addr[3] << 16) |
-                   (tp->dev->dev_addr[4] <<  8) |
-                   (tp->dev->dev_addr[5] <<  0));
-       for (i = 0; i < 4; i++) {
-               if (i == 1 && skip_mac_1)
-                       continue;
-               tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high);
-               tw32(MAC_ADDR_0_LOW + (i * 8), addr_low);
-       }
-
-       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
-               for (i = 0; i < 12; i++) {
-                       tw32(MAC_EXTADDR_0_HIGH + (i * 8), addr_high);
-                       tw32(MAC_EXTADDR_0_LOW + (i * 8), addr_low);
-               }
-       }
-
-       addr_high = (tp->dev->dev_addr[0] +
-                    tp->dev->dev_addr[1] +
-                    tp->dev->dev_addr[2] +
-                    tp->dev->dev_addr[3] +
-                    tp->dev->dev_addr[4] +
-                    tp->dev->dev_addr[5]) &
-               TX_BACKOFF_SEED_MASK;
-       tw32(MAC_TX_BACKOFF_SEED, addr_high);
-}
-
 static int tg3_set_mac_addr(struct net_device *dev, void *p)
 {
        struct tg3 *tp = netdev_priv(dev);
@@ -7024,8 +7127,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 
        tg3_write_sig_legacy(tp, RESET_KIND_INIT);
 
-       if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
-           tp->pci_chip_rev_id == CHIPREV_ID_5784_A1) {
+       if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX) {
                val = tr32(TG3_CPMU_CTRL);
                val &= ~(CPMU_CTRL_LINK_AWARE_MODE | CPMU_CTRL_LINK_IDLE_MODE);
                tw32(TG3_CPMU_CTRL, val);
@@ -7091,8 +7193,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                return err;
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
-           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761 &&
-           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) {
+           GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) {
                /* This value is determined during the probe time DMA
                 * engine test, tg3_test_dma.
                 */
@@ -9066,7 +9167,8 @@ static void tg3_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        else
                wol->supported = 0;
        wol->wolopts = 0;
-       if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)
+       if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) &&
+           device_can_wakeup(&tp->pdev->dev))
                wol->wolopts = WAKE_MAGIC;
        memset(&wol->sopass, 0, sizeof(wol->sopass));
 }
@@ -11299,7 +11401,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                    (val & VCPU_CFGSHDW_WOL_MAGPKT) &&
                    device_may_wakeup(&tp->pdev->dev))
                        tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
-               return;
+               goto done;
        }
 
        tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
@@ -11421,15 +11523,17 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                        if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
                                tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE;
                }
-               if (nic_cfg & NIC_SRAM_DATA_CFG_APE_ENABLE)
+
+               if ((nic_cfg & NIC_SRAM_DATA_CFG_APE_ENABLE) &&
+                       (tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
                        tp->tg3_flags3 |= TG3_FLG3_ENABLE_APE;
+
                if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES &&
                    !(nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL))
                        tp->tg3_flags &= ~TG3_FLAG_WOL_CAP;
 
                if ((tp->tg3_flags & TG3_FLAG_WOL_CAP) &&
-                   (nic_cfg & NIC_SRAM_DATA_CFG_WOL_ENABLE) &&
-                   device_may_wakeup(&tp->pdev->dev))
+                   (nic_cfg & NIC_SRAM_DATA_CFG_WOL_ENABLE))
                        tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
 
                if (cfg2 & (1 << 17))
@@ -11455,6 +11559,10 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
                if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_TX_EN)
                        tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_TX_EN;
        }
+done:
+       device_init_wakeup(&tp->pdev->dev, tp->tg3_flags & TG3_FLAG_WOL_CAP);
+       device_set_wakeup_enable(&tp->pdev->dev,
+                                tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
 }
 
 static int __devinit tg3_issue_otp_command(struct tg3 *tp, u32 cmd)
@@ -12091,7 +12199,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                        if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN)
                                tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2;
                }
-       }
+       } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+               tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
 
        /* If we have an AMD 762 or VIA K8T800 chipset, write
         * reordering to the mailbox registers done by the host
@@ -12263,16 +12372,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
+           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
                tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
 
-               if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
-                   tp->pci_chip_rev_id == CHIPREV_ID_5784_A1 ||
-                   tp->pci_chip_rev_id == CHIPREV_ID_5761_A0 ||
-                   tp->pci_chip_rev_id == CHIPREV_ID_5761_A1)
-                       tp->tg3_flags3 |= TG3_FLG3_5761_5784_AX_FIXES;
-       }
-
        /* Set up tp->grc_local_ctrl before calling tg3_set_power_state().
         * GPIO1 driven high will bring 5700's external PHY out of reset.
         * It is also used as eeprom write protect on LOMs.
@@ -13245,14 +13347,12 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                                  const struct pci_device_id *ent)
 {
        static int tg3_version_printed = 0;
-       resource_size_t tg3reg_base;
-       unsigned long tg3reg_len;
+       resource_size_t tg3reg_len;
        struct net_device *dev;
        struct tg3 *tp;
        int err, pm_cap;
        char str[40];
        u64 dma_mask, persist_dma_mask;
-       DECLARE_MAC_BUF(mac);
 
        if (tg3_version_printed++ == 0)
                printk(KERN_INFO "%s", version);
@@ -13264,7 +13364,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                return err;
        }
 
-       if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+       if (!(pci_resource_flags(pdev, BAR_0) & IORESOURCE_MEM)) {
                printk(KERN_ERR PFX "Cannot find proper PCI device "
                       "base address, aborting.\n");
                err = -ENODEV;
@@ -13289,9 +13389,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_free_res;
        }
 
-       tg3reg_base = pci_resource_start(pdev, 0);
-       tg3reg_len = pci_resource_len(pdev, 0);
-
        dev = alloc_etherdev(sizeof(*tp));
        if (!dev) {
                printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
@@ -13343,7 +13440,11 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        spin_lock_init(&tp->indirect_lock);
        INIT_WORK(&tp->reset_task, tg3_reset_task);
 
-       tp->regs = ioremap_nocache(tg3reg_base, tg3reg_len);
+       dev->mem_start = pci_resource_start(pdev, BAR_0);
+       tg3reg_len = pci_resource_len(pdev, BAR_0);
+       dev->mem_end = dev->mem_start + tg3reg_len;
+
+       tp->regs = ioremap_nocache(dev->mem_start, tg3reg_len);
        if (!tp->regs) {
                printk(KERN_ERR PFX "Cannot map device registers, "
                       "aborting.\n");
@@ -13466,17 +13567,14 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        }
 
        if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
-               if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
+               if (!(pci_resource_flags(pdev, BAR_2) & IORESOURCE_MEM)) {
                        printk(KERN_ERR PFX "Cannot find proper PCI device "
                               "base address for APE, aborting.\n");
                        err = -ENODEV;
                        goto err_out_iounmap;
                }
 
-               tg3reg_base = pci_resource_start(pdev, 2);
-               tg3reg_len = pci_resource_len(pdev, 2);
-
-               tp->aperegs = ioremap_nocache(tg3reg_base, tg3reg_len);
+               tp->aperegs = pci_ioremap_bar(pdev, BAR_2);
                if (!tp->aperegs) {
                        printk(KERN_ERR PFX "Cannot map APE registers, "
                               "aborting.\n");
@@ -13535,26 +13633,34 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_apeunmap;
        }
 
-       printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] "
-              "(%s) %s Ethernet %s\n",
+       printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x] (%s) MAC address %pM\n",
               dev->name,
               tp->board_part_number,
               tp->pci_chip_rev_id,
-              tg3_phy_string(tp),
               tg3_bus_string(tp, str),
-              ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100Base-TX" :
-               ((tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) ? "1000Base-SX" :
-                "10/100/1000Base-T")),
-              print_mac(mac, dev->dev_addr));
+              dev->dev_addr);
 
-       printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] "
-              "MIirq[%d] ASF[%d] WireSpeed[%d] TSOcap[%d]\n",
+       if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)
+               printk(KERN_INFO
+                      "%s: attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
+                      tp->dev->name,
+                      tp->mdio_bus->phy_map[PHY_ADDR]->drv->name,
+                      dev_name(&tp->mdio_bus->phy_map[PHY_ADDR]->dev));
+       else
+               printk(KERN_INFO
+                      "%s: attached PHY is %s (%s Ethernet) (WireSpeed[%d])\n",
+                      tp->dev->name, tg3_phy_string(tp),
+                      ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100Base-TX" :
+                       ((tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) ? "1000Base-SX" :
+                        "10/100/1000Base-T")),
+                      (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0);
+
+       printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] MIirq[%d] ASF[%d] TSOcap[%d]\n",
               dev->name,
               (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0,
               (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0,
               (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0,
               (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0,
-              (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0,
               (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
        printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n",
               dev->name, tp->dma_rwctrl,
index be252abe8985faf0fb2d7c75bec2d10095ef4f7c..599e490cf62c1164e3b9710d443b488fa1b79ffa 100644 (file)
@@ -38,6 +38,8 @@
 #define  TG3PCI_DEVICE_TIGON3_2                 0x1645 /* BCM5701 */
 #define  TG3PCI_DEVICE_TIGON3_3                 0x1646 /* BCM5702 */
 #define  TG3PCI_DEVICE_TIGON3_4                 0x1647 /* BCM5703 */
+#define  TG3PCI_DEVICE_TIGON3_5761S     0x1688
+#define  TG3PCI_DEVICE_TIGON3_5761SE    0x1689
 #define TG3PCI_COMMAND                 0x00000004
 #define TG3PCI_STATUS                  0x00000006
 #define TG3PCI_CCREVID                 0x00000008
 #define  MAC_MODE_TDE_ENABLE            0x00200000
 #define  MAC_MODE_RDE_ENABLE            0x00400000
 #define  MAC_MODE_FHDE_ENABLE           0x00800000
+#define  MAC_MODE_KEEP_FRAME_IN_WOL     0x01000000
 #define  MAC_MODE_APE_RX_EN             0x08000000
 #define  MAC_MODE_APE_TX_EN             0x10000000
 #define MAC_STATUS                     0x00000404
 #define  MI_COM_DATA_MASK               0x0000ffff
 #define MAC_MI_STAT                    0x00000450
 #define  MAC_MI_STAT_LNKSTAT_ATTN_ENAB  0x00000001
+#define  MAC_MI_STAT_10MBPS_MODE        0x00000002
 #define MAC_MI_MODE                    0x00000454
 #define  MAC_MI_MODE_CLK_10MHZ          0x00000001
 #define  MAC_MI_MODE_SHORT_PREAMBLE     0x00000002
 #define  MAC_PHYCFG1_TXC_DRV            0x20000000
 #define MAC_PHYCFG2                    0x000005a4
 #define  MAC_PHYCFG2_INBAND_ENABLE      0x00000001
+#define  MAC_PHYCFG2_EMODE_MASK_MASK    0x000001c0
+#define  MAC_PHYCFG2_EMODE_MASK_AC131   0x000000c0
+#define  MAC_PHYCFG2_EMODE_MASK_50610   0x00000100
+#define  MAC_PHYCFG2_EMODE_MASK_RT8211  0x00000000
+#define  MAC_PHYCFG2_EMODE_MASK_RT8201  0x000001c0
+#define  MAC_PHYCFG2_EMODE_COMP_MASK    0x00000e00
+#define  MAC_PHYCFG2_EMODE_COMP_AC131   0x00000600
+#define  MAC_PHYCFG2_EMODE_COMP_50610   0x00000400
+#define  MAC_PHYCFG2_EMODE_COMP_RT8211  0x00000800
+#define  MAC_PHYCFG2_EMODE_COMP_RT8201  0x00000000
+#define  MAC_PHYCFG2_FMODE_MASK_MASK    0x00007000
+#define  MAC_PHYCFG2_FMODE_MASK_AC131   0x00006000
+#define  MAC_PHYCFG2_FMODE_MASK_50610   0x00004000
+#define  MAC_PHYCFG2_FMODE_MASK_RT8211  0x00000000
+#define  MAC_PHYCFG2_FMODE_MASK_RT8201  0x00007000
+#define  MAC_PHYCFG2_FMODE_COMP_MASK    0x00038000
+#define  MAC_PHYCFG2_FMODE_COMP_AC131   0x00030000
+#define  MAC_PHYCFG2_FMODE_COMP_50610   0x00008000
+#define  MAC_PHYCFG2_FMODE_COMP_RT8211  0x00038000
+#define  MAC_PHYCFG2_FMODE_COMP_RT8201  0x00000000
+#define  MAC_PHYCFG2_GMODE_MASK_MASK    0x001c0000
+#define  MAC_PHYCFG2_GMODE_MASK_AC131   0x001c0000
+#define  MAC_PHYCFG2_GMODE_MASK_50610   0x00100000
+#define  MAC_PHYCFG2_GMODE_MASK_RT8211  0x00000000
+#define  MAC_PHYCFG2_GMODE_MASK_RT8201  0x001c0000
+#define  MAC_PHYCFG2_GMODE_COMP_MASK    0x00e00000
+#define  MAC_PHYCFG2_GMODE_COMP_AC131   0x00e00000
+#define  MAC_PHYCFG2_GMODE_COMP_50610   0x00000000
+#define  MAC_PHYCFG2_GMODE_COMP_RT8211  0x00200000
+#define  MAC_PHYCFG2_GMODE_COMP_RT8201  0x00000000
+#define  MAC_PHYCFG2_ACT_MASK_MASK      0x03000000
+#define  MAC_PHYCFG2_ACT_MASK_AC131     0x03000000
+#define  MAC_PHYCFG2_ACT_MASK_50610     0x01000000
+#define  MAC_PHYCFG2_ACT_MASK_RT8211    0x03000000
+#define  MAC_PHYCFG2_ACT_MASK_RT8201    0x01000000
+#define  MAC_PHYCFG2_ACT_COMP_MASK      0x0c000000
+#define  MAC_PHYCFG2_ACT_COMP_AC131     0x00000000
+#define  MAC_PHYCFG2_ACT_COMP_50610     0x00000000
+#define  MAC_PHYCFG2_ACT_COMP_RT8211    0x00000000
+#define  MAC_PHYCFG2_ACT_COMP_RT8201    0x08000000
+#define  MAC_PHYCFG2_QUAL_MASK_MASK     0x30000000
+#define  MAC_PHYCFG2_QUAL_MASK_AC131    0x30000000
+#define  MAC_PHYCFG2_QUAL_MASK_50610    0x30000000
+#define  MAC_PHYCFG2_QUAL_MASK_RT8211   0x30000000
+#define  MAC_PHYCFG2_QUAL_MASK_RT8201   0x30000000
+#define  MAC_PHYCFG2_QUAL_COMP_MASK     0xc0000000
+#define  MAC_PHYCFG2_QUAL_COMP_AC131    0x00000000
+#define  MAC_PHYCFG2_QUAL_COMP_50610    0x00000000
+#define  MAC_PHYCFG2_QUAL_COMP_RT8211   0x00000000
+#define  MAC_PHYCFG2_QUAL_COMP_RT8201   0x00000000
+#define MAC_PHYCFG2_50610_LED_MODES \
+       (MAC_PHYCFG2_EMODE_MASK_50610 | \
+        MAC_PHYCFG2_EMODE_COMP_50610 | \
+        MAC_PHYCFG2_FMODE_MASK_50610 | \
+        MAC_PHYCFG2_FMODE_COMP_50610 | \
+        MAC_PHYCFG2_GMODE_MASK_50610 | \
+        MAC_PHYCFG2_GMODE_COMP_50610 | \
+        MAC_PHYCFG2_ACT_MASK_50610 | \
+        MAC_PHYCFG2_ACT_COMP_50610 | \
+        MAC_PHYCFG2_QUAL_MASK_50610 | \
+        MAC_PHYCFG2_QUAL_COMP_50610)
+#define MAC_PHYCFG2_AC131_LED_MODES \
+       (MAC_PHYCFG2_EMODE_MASK_AC131 | \
+        MAC_PHYCFG2_EMODE_COMP_AC131 | \
+        MAC_PHYCFG2_FMODE_MASK_AC131 | \
+        MAC_PHYCFG2_FMODE_COMP_AC131 | \
+        MAC_PHYCFG2_GMODE_MASK_AC131 | \
+        MAC_PHYCFG2_GMODE_COMP_AC131 | \
+        MAC_PHYCFG2_ACT_MASK_AC131 | \
+        MAC_PHYCFG2_ACT_COMP_AC131 | \
+        MAC_PHYCFG2_QUAL_MASK_AC131 | \
+        MAC_PHYCFG2_QUAL_COMP_AC131)
+#define MAC_PHYCFG2_RTL8211C_LED_MODES \
+       (MAC_PHYCFG2_EMODE_MASK_RT8211 | \
+        MAC_PHYCFG2_EMODE_COMP_RT8211 | \
+        MAC_PHYCFG2_FMODE_MASK_RT8211 | \
+        MAC_PHYCFG2_FMODE_COMP_RT8211 | \
+        MAC_PHYCFG2_GMODE_MASK_RT8211 | \
+        MAC_PHYCFG2_GMODE_COMP_RT8211 | \
+        MAC_PHYCFG2_ACT_MASK_RT8211 | \
+        MAC_PHYCFG2_ACT_COMP_RT8211 | \
+        MAC_PHYCFG2_QUAL_MASK_RT8211 | \
+        MAC_PHYCFG2_QUAL_COMP_RT8211)
+#define MAC_PHYCFG2_RTL8201E_LED_MODES \
+       (MAC_PHYCFG2_EMODE_MASK_RT8201 | \
+        MAC_PHYCFG2_EMODE_COMP_RT8201 | \
+        MAC_PHYCFG2_FMODE_MASK_RT8201 | \
+        MAC_PHYCFG2_FMODE_COMP_RT8201 | \
+        MAC_PHYCFG2_GMODE_MASK_RT8201 | \
+        MAC_PHYCFG2_GMODE_COMP_RT8201 | \
+        MAC_PHYCFG2_ACT_MASK_RT8201 | \
+        MAC_PHYCFG2_ACT_COMP_RT8201 | \
+        MAC_PHYCFG2_QUAL_MASK_RT8201 | \
+        MAC_PHYCFG2_QUAL_COMP_RT8201)
 #define MAC_EXT_RGMII_MODE             0x000005a8
 #define  MAC_RGMII_MODE_TX_ENABLE       0x00000001
 #define  MAC_RGMII_MODE_TX_LOWPWR       0x00000002
 
 #define MII_TG3_AUX_CTRL               0x18 /* auxilliary control register */
 
+#define MII_TG3_AUXCTL_PCTL_100TX_LPWR 0x0010
+#define MII_TG3_AUXCTL_PCTL_SPR_ISOLATE        0x0020
+#define MII_TG3_AUXCTL_PCTL_VREG_11V   0x0180
+#define MII_TG3_AUXCTL_SHDWSEL_PWRCTL  0x0002
+
 #define MII_TG3_AUXCTL_MISC_WREN       0x8000
 #define MII_TG3_AUXCTL_MISC_FORCE_AMDIX        0x0200
 #define MII_TG3_AUXCTL_MISC_RDSEL_MISC 0x7000
@@ -2507,7 +2610,6 @@ struct tg3 {
        u32                             tg3_flags3;
 #define TG3_FLG3_NO_NVRAM_ADDR_TRANS   0x00000001
 #define TG3_FLG3_ENABLE_APE            0x00000002
-#define TG3_FLG3_5761_5784_AX_FIXES    0x00000004
 #define TG3_FLG3_5701_DMA_BUG          0x00000008
 #define TG3_FLG3_USE_PHYLIB            0x00000010
 #define TG3_FLG3_MDIOBUS_INITED                0x00000020
@@ -2588,7 +2690,12 @@ struct tg3 {
 #define PHY_REV_BCM5411_X0             0x1 /* Found on Netgear GA302T */
 #define TG3_PHY_ID_BCM50610            0x143bd60
 #define TG3_PHY_ID_BCMAC131            0x143bc70
-
+#define TG3_PHY_ID_RTL8211C            0x001cc910
+#define TG3_PHY_ID_RTL8201E            0x00008200
+#define TG3_PHY_OUI_MASK               0xfffffc00
+#define TG3_PHY_OUI_1                  0x00206000
+#define TG3_PHY_OUI_2                  0x0143bc00
+#define TG3_PHY_OUI_3                  0x03625c00
 
        u32                             led_ctrl;
        u32                             phy_otp;
index c41d68761364550ebe2d2d8376f2a8c293b5d799..055d3429851fff14615320b30df5e80e4d015722 100644 (file)
@@ -1649,8 +1649,6 @@ drop_and_reuse:
                }
        }
 
-       dev->last_rx = jiffies;
-
        return ack;
 
 } /* TLan_HandleRxEOF */
index bf621328b6019e3a89bc21406ecaf4f8370218d9..87509a65b3bfa6fd8ab8fd8d071a842637181195 100644 (file)
@@ -974,7 +974,6 @@ static void xl_rx(struct net_device *dev)
 
                        netif_rx(skb2) ;                
                 } /* if multiple buffers */
-               dev->last_rx = jiffies ;        
        } /* while packet to do */
 
        /* Clear the updComplete interrupt */
@@ -1571,7 +1570,6 @@ static void xl_arb_cmd(struct net_device *dev)
                 * anyway.
                 */
 
-               dev->last_rx = jiffies ; 
                /* Acknowledge interrupt, this tells nic we are done with the arb */
                writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; 
 
index 7a7de0469eae098412036df35e8b9b636e291622..b566d6d79ecdbe7ce0a5f58f7546f50e77600ec5 100644 (file)
@@ -99,7 +99,6 @@ static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_
        struct net_local *tp;
        int ret, pci_irq_line;
        unsigned long pci_ioaddr;
-       DECLARE_MAC_BUF(mac);
        
        if (versionprinted++ == 0)
                printk("%s", version);
@@ -147,8 +146,7 @@ static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_
 
        abyss_read_eeprom(dev);
 
-       printk("%s:    Ring Station Address: %s\n",
-              dev->name, print_mac(mac, dev->dev_addr));
+       printk("%s:    Ring Station Address: %pM\n", dev->name, dev->dev_addr);
 
        tp = netdev_priv(dev);
        tp->setnselout = abyss_setnselout_pins;
index e494c63bfbd9643088c0c30680fdc956becf8b60..9fd09938d45b8e2410e3706cc27b3bffb7efdd37 100644 (file)
@@ -389,7 +389,6 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
         unsigned long timeout;
        static int version_printed;
 #endif
-       DECLARE_MAC_BUF(mac);
 
        /*    Query the adapter PIO base port which will return
         *    indication of where MMIO was placed. We also have a
@@ -703,8 +702,7 @@ static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
                channel_def[cardpresent - 1], adapter_def(ti->adapter_type));
        DPRINTK("using irq %d, PIOaddr %hx, %dK shared RAM.\n",
                        irq, PIOaddr, ti->mapped_ram_size / 2);
-       DPRINTK("Hardware address : %s\n",
-               print_mac(mac, dev->dev_addr));
+       DPRINTK("Hardware address : %pM\n", dev->dev_addr);
        if (ti->page_mask)
                DPRINTK("Shared RAM paging enabled. "
                        "Page size: %uK Shared Ram size %dK\n",
@@ -1741,8 +1739,6 @@ static void tr_rx(struct net_device *dev)
                void __iomem *trhhdr = rbuf + offsetof(struct rec_buf, data);
                u8 saddr[6];
                u8 daddr[6];
-               DECLARE_MAC_BUF(mac);
-               DECLARE_MAC_BUF(mac2);
                int i;
                for (i = 0 ; i < 6 ; i++)
                        saddr[i] = readb(trhhdr + SADDR_OFST + i);
@@ -1750,9 +1746,9 @@ static void tr_rx(struct net_device *dev)
                        daddr[i] = readb(trhhdr + DADDR_OFST + i);
                DPRINTK("Probably non-IP frame received.\n");
                DPRINTK("ssap: %02X dsap: %02X "
-                       "saddr: %s daddr: %$s\n",
+                       "saddr: %pM daddr: %pM\n",
                        readb(llc + SSAP_OFST), readb(llc + DSAP_OFST),
-                       print_mac(mac, saddr), print_mac(mac2, daddr));
+                       saddr, daddr);
        }
 #endif
 
@@ -1826,7 +1822,6 @@ static void tr_rx(struct net_device *dev)
                skb->ip_summed = CHECKSUM_COMPLETE;
        }
        netif_rx(skb);
-       dev->last_rx = jiffies;
 }                              /*tr_rx */
 
 /*****************************************************************************/
index 59d1673f9387febe69304c48e1c6a17a6e19e538..239c75217b120624d7ae500ce919552a869507b5 100644 (file)
@@ -446,9 +446,6 @@ static int streamer_reset(struct net_device *dev)
        unsigned int uaa_addr;
        struct sk_buff *skb = NULL;
        __u16 misr;
-#if STREAMER_DEBUG
-       DECLARE_MAC_BUF(mac);
-#endif
 
        streamer_priv = netdev_priv(dev);
        streamer_mmio = streamer_priv->streamer_mmio;
@@ -577,8 +574,7 @@ static int streamer_reset(struct net_device *dev)
                        dev->dev_addr[i+1]= addr & 0xff;
                }
 #if STREAMER_DEBUG
-               printk("Adapter address: %s\n",
-                      print_mac(mac, dev->dev_addr));
+               printk("Adapter address: %pM\n", dev->dev_addr);
 #endif
        }
        return 0;
@@ -1013,7 +1009,6 @@ static void streamer_rx(struct net_device *dev)
                                        /* send up to the protocol */
                                        netif_rx(skb);
                                }
-                               dev->last_rx = jiffies;
                                streamer_priv->streamer_stats.rx_packets++;
                                streamer_priv->streamer_stats.rx_bytes += length;
                        }       /* if skb == null */
@@ -1538,7 +1533,6 @@ static void streamer_arb_cmd(struct net_device *dev)
 
 #if STREAMER_NETWORK_MONITOR
        struct trh_hdr *mac_hdr;
-       DECLARE_MAC_BUF(mac);
 #endif
 
        writew(streamer_priv->arb, streamer_mmio + LAPA);
@@ -1611,11 +1605,11 @@ static void streamer_arb_cmd(struct net_device *dev)
                       dev->name);
                mac_hdr = tr_hdr(mac_frame);
                printk(KERN_WARNING
-                      "%s: MAC Frame Dest. Addr: %s\n",
-                      dev->name, print_mac(mac, mac_hdr->daddr));
+                      "%s: MAC Frame Dest. Addr: %pM\n",
+                      dev->name, mac_hdr->daddr);
                printk(KERN_WARNING
-                      "%s: MAC Frame Srce. Addr: %s\n",
-                      dev->name, DEV->ADDR6(mac_hdr->saddr));
+                      "%s: MAC Frame Srce. Addr: %pM\n",
+                      dev->name, mac_hdr->saddr);
 #endif
                netif_rx(mac_frame);
 
@@ -1850,8 +1844,6 @@ static int sprintf_info(char *buffer, struct net_device *dev)
        struct streamer_parameters_table spt;
        int size = 0;
        int i;
-       DECLARE_MAC_BUF(mac);
-       DECLARE_MAC_BUF(mac2);
 
        writew(streamer_priv->streamer_addr_table_addr, streamer_mmio + LAPA);
        for (i = 0; i < 14; i += 2) {
@@ -1873,9 +1865,8 @@ static int sprintf_info(char *buffer, struct net_device *dev)
        size = sprintf(buffer, "\n%6s: Adapter Address   : Node Address      : Functional Addr\n", dev->name);
 
        size += sprintf(buffer + size,
-                       "%6s: %s : %s : %02x:%02x:%02x:%02x\n",
-                       dev->name, print_mac(mac, dev->dev_addr),
-                       print_mac(mac2, sat.node_addr),
+                       "%6s: %pM : %pM : %02x:%02x:%02x:%02x\n",
+                       dev->name, dev->dev_addr, sat.node_addr,
                        sat.func_addr[0], sat.func_addr[1],
                        sat.func_addr[2], sat.func_addr[3]);
 
@@ -1884,19 +1875,18 @@ static int sprintf_info(char *buffer, struct net_device *dev)
        size += sprintf(buffer + size, "%6s: Physical Addr : Up Node Address   : Poll Address      : AccPri : Auth Src : Att Code :\n", dev->name);
 
        size += sprintf(buffer + size,
-                   "%6s: %02x:%02x:%02x:%02x   : %s : %s : %04x   : %04x     :  %04x    :\n",
+                   "%6s: %02x:%02x:%02x:%02x   : %pM : %pM : %04x   : %04x     :  %04x    :\n",
                    dev->name, spt.phys_addr[0], spt.phys_addr[1],
                    spt.phys_addr[2], spt.phys_addr[3],
-                   print_mac(mac, spt.up_node_addr),
-                   print_mac(mac2, spt.poll_addr),
+                   spt.up_node_addr, spt.poll_addr,
                    ntohs(spt.acc_priority), ntohs(spt.auth_source_class),
                    ntohs(spt.att_code));
 
        size += sprintf(buffer + size, "%6s: Source Address    : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n", dev->name);
 
        size += sprintf(buffer + size,
-                   "%6s: %s : %04x  : %04x   : %04x   : %04x   : %04x    :     %04x     : \n",
-                   dev->name, print_mac(mac, spt.source_addr),
+                   "%6s: %pM : %04x  : %04x   : %04x   : %04x   : %04x    :     %04x     : \n",
+                   dev->name, spt.source_addr,
                    ntohs(spt.beacon_type), ntohs(spt.major_vector),
                    ntohs(spt.lan_status), ntohs(spt.local_ring),
                    ntohs(spt.mon_error), ntohs(spt.frame_correl));
@@ -1905,10 +1895,10 @@ static int sprintf_info(char *buffer, struct net_device *dev)
                    dev->name);
 
        size += sprintf(buffer + size,
-                   "%6s:                :  %02x  :  %02x  : %s : %02x:%02x:%02x:%02x    : \n",
+                   "%6s:                :  %02x  :  %02x  : %pM : %02x:%02x:%02x:%02x    : \n",
                    dev->name, ntohs(spt.beacon_transmit),
                    ntohs(spt.beacon_receive),
-                   print_mac(mac, spt.beacon_naun),
+                   spt.beacon_naun,
                    spt.beacon_phys[0], spt.beacon_phys[1],
                    spt.beacon_phys[2], spt.beacon_phys[3]);
        return size;
index c9c5a2b1ed9e9ea6a49d8e5f2af22e9799adb403..0ba6f0bc7c00352d6e5253e84d2df56e6c4dd850 100644 (file)
@@ -152,7 +152,6 @@ static int __devinit madgemc_probe(struct device *device)
        struct card_info *card;
        struct mca_device *mdev = to_mca_device(device);
        int ret = 0;
-       DECLARE_MAC_BUF(mac);
 
        if (versionprinted++ == 0)
                printk("%s", version);
@@ -323,8 +322,8 @@ static int __devinit madgemc_probe(struct device *device)
        mca_device_set_name(mdev, (card->cardtype == 0x08)?MADGEMC16_CARDNAME:MADGEMC32_CARDNAME);
        mca_set_adapter_procfn(mdev->slot, madgemc_mcaproc, dev);
 
-       printk("%s:     Ring Station Address: %s\n",
-              dev->name, print_mac(mac, dev->dev_addr));
+       printk("%s:     Ring Station Address: %pM\n",
+              dev->name, dev->dev_addr);
 
        if (tmsdev_init(dev, device)) {
                printk("%s: unable to get memory for dev->priv.\n", 
@@ -690,7 +689,6 @@ static int madgemc_mcaproc(char *buf, int slot, void *d)
        struct net_local *tp = netdev_priv(dev);
        struct card_info *curcard = tp->tmspriv;
        int len = 0;
-       DECLARE_MAC_BUF(mac);
        
        len += sprintf(buf+len, "-------\n");
        if (curcard) {
@@ -714,8 +712,8 @@ static int madgemc_mcaproc(char *buf, int slot, void *d)
                }
                len += sprintf(buf+len, " (%s)\n", (curcard->fairness)?"Unfair":"Fair");
                
-               len += sprintf(buf+len, "Ring Station Address: %s\n",
-                              print_mac(mac, dev->dev_addr));
+               len += sprintf(buf+len, "Ring Station Address: %pM\n",
+                              dev->dev_addr);
        } else 
                len += sprintf(buf+len, "Card not configured\n");
 
index 0ab51a0f35fc9cc5ae811610bc776759ff49c453..ecb5c7c969105ff6d79622f17f50a47c6ea3bd3e 100644 (file)
@@ -421,10 +421,7 @@ static int olympic_init(struct net_device *dev)
        memcpy_fromio(&dev->dev_addr[0], adapter_addr,6);
 
 #if OLYMPIC_DEBUG
- {
-       DECLARE_MAC_BUF(mac);
-       printk("adapter address: %s\n", print_mac(mac, dev->dev_addr));
- }
+       printk("adapter address: %pM\n", dev->dev_addr);
 #endif
 
        olympic_priv->olympic_addr_table_addr = swab16(readw(init_srb + 12)); 
@@ -441,7 +438,6 @@ static int olympic_open(struct net_device *dev)
        unsigned long flags, t;
        int i, open_finished = 1 ;
        u8 resp, err;
-       DECLARE_MAC_BUF(mac);
 
        DECLARE_WAITQUEUE(wait,current) ; 
 
@@ -569,8 +565,8 @@ static int olympic_open(struct net_device *dev)
                        goto out;
 
                case 0x32:
-                       printk(KERN_WARNING "%s: Invalid LAA: %s\n",
-                              dev->name, print_mac(mac, olympic_priv->olympic_laa));
+                       printk(KERN_WARNING "%s: Invalid LAA: %pM\n",
+                              dev->name, olympic_priv->olympic_laa);
                        goto out;
 
                default:
@@ -704,13 +700,12 @@ static int olympic_open(struct net_device *dev)
                u8 __iomem *opt;
                int i;
                u8 addr[6];
-               DECLARE_MAC_BUF(mac);
                oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr);
                opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr);
 
                for (i = 0; i < 6; i++)
                        addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+i);
-               printk("%s: Node Address: %s\n",dev->name, print_mac(mac, addr));
+               printk("%s: Node Address: %pM\n", dev->name, addr);
                printk("%s: Functional Address: %02x:%02x:%02x:%02x\n",dev->name, 
                        readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)), 
                        readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1),
@@ -719,7 +714,7 @@ static int olympic_open(struct net_device *dev)
 
                for (i = 0; i < 6; i++)
                        addr[i] = readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+i);
-               printk("%s: NAUN Address: %s\n",dev->name, print_mac(mac, addr));
+               printk("%s: NAUN Address: %pM\n", dev->name, addr);
        }
        
        netif_start_queue(dev);
@@ -867,7 +862,6 @@ static void olympic_rx(struct net_device *dev)
                                                skb->protocol = tr_type_trans(skb,dev);
                                                netif_rx(skb) ; 
                                        } 
-                                       dev->last_rx = jiffies ; 
                                        olympic_priv->olympic_stats.rx_packets++ ; 
                                        olympic_priv->olympic_stats.rx_bytes += length ; 
                                } /* if skb == null */
@@ -1440,19 +1434,12 @@ static void olympic_arb_cmd(struct net_device *dev)
                        struct trh_hdr *mac_hdr;
                        printk(KERN_WARNING "%s: Received MAC Frame, details: \n",dev->name);
                        mac_hdr = tr_hdr(mac_frame);
-                       printk(KERN_WARNING "%s: MAC Frame Dest. Addr: "
-                              MAC_FMT " \n", dev->name,
-                              mac_hdr->daddr[0], mac_hdr->daddr[1],
-                              mac_hdr->daddr[2], mac_hdr->daddr[3],
-                              mac_hdr->daddr[4], mac_hdr->daddr[5]);
-                       printk(KERN_WARNING "%s: MAC Frame Srce. Addr: "
-                              MAC_FMT " \n", dev->name,
-                              mac_hdr->saddr[0], mac_hdr->saddr[1],
-                              mac_hdr->saddr[2], mac_hdr->saddr[3],
-                              mac_hdr->saddr[4], mac_hdr->saddr[5]);
+                       printk(KERN_WARNING "%s: MAC Frame Dest. Addr: %pM\n",
+                              dev->name, mac_hdr->daddr);
+                       printk(KERN_WARNING "%s: MAC Frame Srce. Addr: %pM\n",
+                              dev->name, mac_hdr->saddr);
                }
                netif_rx(mac_frame);
-               dev->last_rx = jiffies;
 
 drop_frame:
                /* Now tell the card we have dealt with the received frame */
@@ -1647,8 +1634,6 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt
        u8 addr[6];
        u8 addr2[6];
        int i;
-       DECLARE_MAC_BUF(mac);
-       DECLARE_MAC_BUF(mac2);
 
        size = sprintf(buffer, 
                "IBM Pit/Pit-Phy/Olympic Chipset Token Ring Adapter %s\n",dev->name);
@@ -1658,10 +1643,9 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt
        for (i = 0 ; i < 6 ; i++)
                addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr) + i);
 
-       size += sprintf(buffer+size, "%6s: %s : %s : %02x:%02x:%02x:%02x\n",
+       size += sprintf(buffer+size, "%6s: %pM : %pM : %02x:%02x:%02x:%02x\n",
           dev->name,
-          print_mac(mac, dev->dev_addr),
-          print_mac(mac2, addr),
+          dev->dev_addr, addr,
           readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)), 
           readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1),
           readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2),
@@ -1677,14 +1661,13 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt
        for (i = 0 ; i < 6 ; i++)
                addr2[i] =  readb(opt+offsetof(struct olympic_parameters_table, poll_addr) + i);
 
-       size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x   : %s : %s : %04x   : %04x     :  %04x    :\n",
+       size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x   : %pM : %pM : %04x   : %04x     :  %04x    :\n",
          dev->name,
          readb(opt+offsetof(struct olympic_parameters_table, phys_addr)),
          readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+1),
          readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+2),
          readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+3),
-         print_mac(mac, addr),
-         print_mac(mac2, addr2),
+         addr, addr2,
          swab16(readw(opt+offsetof(struct olympic_parameters_table, acc_priority))),
          swab16(readw(opt+offsetof(struct olympic_parameters_table, auth_source_class))),
          swab16(readw(opt+offsetof(struct olympic_parameters_table, att_code))));
@@ -1694,9 +1677,8 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt
        
        for (i = 0 ; i < 6 ; i++)
                addr[i] = readb(opt+offsetof(struct olympic_parameters_table, source_addr) + i);
-       size += sprintf(buffer+size, "%6s: %s : %04x  : %04x   : %04x   : %04x   : %04x    :     %04x     : \n",
-         dev->name,
-         print_mac(mac, addr),
+       size += sprintf(buffer+size, "%6s: %pM : %04x  : %04x   : %04x   : %04x   : %04x    :     %04x     : \n",
+         dev->name, addr,
          swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_type))),
          swab16(readw(opt+offsetof(struct olympic_parameters_table, major_vector))),
          swab16(readw(opt+offsetof(struct olympic_parameters_table, lan_status))),
@@ -1709,11 +1691,11 @@ static int olympic_proc_info(char *buffer, char **start, off_t offset, int lengt
 
        for (i = 0 ; i < 6 ; i++)
                addr[i] = readb(opt+offsetof(struct olympic_parameters_table, beacon_naun) + i);
-       size += sprintf(buffer+size, "%6s:                :  %02x  :  %02x  : %s : %02x:%02x:%02x:%02x    : \n",
+       size += sprintf(buffer+size, "%6s:                :  %02x  :  %02x  : %pM : %02x:%02x:%02x:%02x    : \n",
          dev->name,
          swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_transmit))),
          swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_receive))),
-         print_mac(mac, addr),
+         addr,
          readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)),
          readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+1),
          readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+2),
index 00ea94513460d5e118b811a3496625b98ad4a9cb..cd2d62f76079b6710d479e7ab5bbb93c25303072 100644 (file)
@@ -122,7 +122,6 @@ static int __init setup_card(struct net_device *dev, struct device *pdev)
         static int versionprinted;
        const unsigned *port;
        int j,err = 0;
-       DECLARE_MAC_BUF(mac);
 
        if (!dev)
                return -ENOMEM;
@@ -153,8 +152,8 @@ static int __init setup_card(struct net_device *dev, struct device *pdev)
                
        proteon_read_eeprom(dev);
 
-       printk(KERN_DEBUG "proteon.c:    Ring Station Address: %s\n",
-              print_mac(mac, dev->dev_addr));
+       printk(KERN_DEBUG "proteon.c:    Ring Station Address: %pM\n",
+              dev->dev_addr);
                
        tp = netdev_priv(dev);
        tp->setnselout = proteon_setnselout_pins;
index 41b6999a0f33487719f56898a489c9748b975f7f..b578744311b0f77ee099c30bd409955c2527fbcf 100644 (file)
@@ -139,7 +139,6 @@ static int __init setup_card(struct net_device *dev, struct device *pdev)
         static int versionprinted;
        const unsigned *port;
        int j, err = 0;
-       DECLARE_MAC_BUF(mac);
 
        if (!dev)
                return -ENOMEM;
@@ -170,8 +169,8 @@ static int __init setup_card(struct net_device *dev, struct device *pdev)
                
        sk_isa_read_eeprom(dev);
 
-       printk(KERN_DEBUG "skisa.c:    Ring Station Address: %s\n",
-              print_mac(mac, dev->dev_addr));
+       printk(KERN_DEBUG "skisa.c:    Ring Station Address: %pM\n",
+              dev->dev_addr);
                
        tp = netdev_priv(dev);
        tp->setnselout = sk_isa_setnselout_pins;
index ed50d288e4940a79bdefca127a6c92d5713ab45d..a011666342ffb62af52bdea2a8eba09980ee777f 100644 (file)
@@ -3910,7 +3910,6 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
                 /* Kick the packet on up. */
                 skb->protocol = tr_type_trans(skb, dev);
                 netif_rx(skb);
-               dev->last_rx = jiffies;
                 err = 0;
         }
 
@@ -4496,7 +4495,6 @@ static int smctr_rx_frame(struct net_device *dev)
                                        /* Kick the packet on up. */
                                        skb->protocol = tr_type_trans(skb, dev);
                                        netif_rx(skb);
-                                       dev->last_rx = jiffies;
                                } else {
                                }
                         }
index d07c4523c847a1ceb3c4e98876c1cce025459b2c..5be34c2fd48385751844d82dc0c12b1e6d5390d4 100644 (file)
@@ -180,10 +180,14 @@ void              tms380tr_wait(unsigned long time);
 static void    tms380tr_write_rpl_status(RPL *rpl, unsigned int Status);
 static void    tms380tr_write_tpl_status(TPL *tpl, unsigned int Status);
 
-#define SIFREADB(reg) (((struct net_local *)dev->priv)->sifreadb(dev, reg))
-#define SIFWRITEB(val, reg) (((struct net_local *)dev->priv)->sifwriteb(dev, val, reg))
-#define SIFREADW(reg) (((struct net_local *)dev->priv)->sifreadw(dev, reg))
-#define SIFWRITEW(val, reg) (((struct net_local *)dev->priv)->sifwritew(dev, val, reg))
+#define SIFREADB(reg) \
+       (((struct net_local *)netdev_priv(dev))->sifreadb(dev, reg))
+#define SIFWRITEB(val, reg) \
+       (((struct net_local *)netdev_priv(dev))->sifwriteb(dev, val, reg))
+#define SIFREADW(reg) \
+       (((struct net_local *)netdev_priv(dev))->sifreadw(dev, reg))
+#define SIFWRITEW(val, reg) \
+       (((struct net_local *)netdev_priv(dev))->sifwritew(dev, val, reg))
 
 
 
@@ -2186,7 +2190,6 @@ static void tms380tr_rcv_status_irq(struct net_device *dev)
                                skb_trim(skb,Length);
                                skb->protocol = tr_type_trans(skb,dev);
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                        }
                }
                else    /* Invalid frame */
@@ -2331,7 +2334,7 @@ int tmsdev_init(struct net_device *dev, struct device *pdev)
 {
        struct net_local *tms_local;
 
-       memset(dev->priv, 0, sizeof(struct net_local));
+       memset(netdev_priv(dev), 0, sizeof(struct net_local));
        tms_local = netdev_priv(dev);
        init_waitqueue_head(&tms_local->wait_for_tok_int);
        if (pdev->dma_mask)
index 5f0ee880cfff1f7fa4d7c5096265322f043bef39..5f601773c26064e7962e6bc5026018f5f1c666af 100644 (file)
@@ -100,7 +100,6 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic
        unsigned int pci_irq_line;
        unsigned long pci_ioaddr;
        struct card_info *cardinfo = &card_info_table[ent->driver_data];
-       DECLARE_MAC_BUF(mac);
 
        if (versionprinted++ == 0)
                printk("%s", version);
@@ -137,8 +136,8 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic
                
        tms_pci_read_eeprom(dev);
 
-       printk("%s:    Ring Station Address: %s\n",
-              dev->name, print_mac(mac, dev->dev_addr));
+       printk("%s:    Ring Station Address: %pM\n",
+              dev->name, dev->dev_addr);
                
        ret = tmsdev_init(dev, &pdev->dev);
        if (ret) {
index eb1da6f0b0863cbd827224ddebbc3d5e19275e35..271bc230c8a9145ee9b24a302cc7a902d4216d62 100644 (file)
@@ -788,7 +788,6 @@ static int tsi108_complete_rx(struct net_device *dev, int budget)
                skb_put(skb, data->rxring[rx].len);
                skb->protocol = eth_type_trans(skb, dev);
                netif_receive_skb(skb);
-               dev->last_rx = jiffies;
        }
 
        return done;
@@ -1569,7 +1568,6 @@ tsi108_init_one(struct platform_device *pdev)
        struct tsi108_prv_data *data = NULL;
        hw_info *einfo;
        int err = 0;
-       DECLARE_MAC_BUF(mac);
 
        einfo = pdev->dev.platform_data;
 
@@ -1659,8 +1657,8 @@ tsi108_init_one(struct platform_device *pdev)
        }
 
        platform_set_drvdata(pdev, dev);
-       printk(KERN_INFO "%s: Tsi108 Gigabit Ethernet, MAC: %s\n",
-              dev->name, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: Tsi108 Gigabit Ethernet, MAC: %pM\n",
+              dev->name, dev->dev_addr);
 #ifdef DEBUG
        data->msg_enable = DEBUG;
        dump_eth_one(dev);
index 124d5d690dde2508a29b8d5ae7bd907bcd259c38..3aa60fad68c7aa1b20b11a6616f650d21834eba2 100644 (file)
@@ -459,7 +459,6 @@ static void de_rx (struct de_private *de)
 
                de->net_stats.rx_packets++;
                de->net_stats.rx_bytes += skb->len;
-               de->dev->last_rx = jiffies;
                rc = netif_rx (skb);
                if (rc == NET_RX_DROP)
                        drop = 1;
@@ -484,7 +483,7 @@ rx_next:
 static irqreturn_t de_interrupt (int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
        u32 status;
 
        status = dr32(MacStatus);
@@ -590,7 +589,7 @@ next:
 
 static int de_start_xmit (struct sk_buff *skb, struct net_device *dev)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
        unsigned int entry, tx_free;
        u32 mapping, len, flags = FirstFrag | LastFrag;
        struct de_desc *txd;
@@ -653,7 +652,7 @@ static int de_start_xmit (struct sk_buff *skb, struct net_device *dev)
 
 static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
        u16 hash_table[32];
        struct dev_mc_list *mclist;
        int i;
@@ -684,7 +683,7 @@ static void build_setup_frame_hash(u16 *setup_frm, struct net_device *dev)
 
 static void build_setup_frame_perfect(u16 *setup_frm, struct net_device *dev)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
        struct dev_mc_list *mclist;
        int i;
        u16 *eaddrs;
@@ -712,7 +711,7 @@ static void build_setup_frame_perfect(u16 *setup_frm, struct net_device *dev)
 
 static void __de_set_rx_mode (struct net_device *dev)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
        u32 macmode;
        unsigned int entry;
        u32 mapping;
@@ -797,7 +796,7 @@ out:
 static void de_set_rx_mode (struct net_device *dev)
 {
        unsigned long flags;
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
 
        spin_lock_irqsave (&de->lock, flags);
        __de_set_rx_mode(dev);
@@ -821,7 +820,7 @@ static void __de_get_stats(struct de_private *de)
 
 static struct net_device_stats *de_get_stats(struct net_device *dev)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
 
        /* The chip only need report frame silently dropped. */
        spin_lock_irq(&de->lock);
@@ -1355,7 +1354,7 @@ static void de_free_rings (struct de_private *de)
 
 static int de_open (struct net_device *dev)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
        int rc;
 
        if (netif_msg_ifup(de))
@@ -1400,7 +1399,7 @@ err_out_free:
 
 static int de_close (struct net_device *dev)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
        unsigned long flags;
 
        if (netif_msg_ifdown(de))
@@ -1423,7 +1422,7 @@ static int de_close (struct net_device *dev)
 
 static void de_tx_timeout (struct net_device *dev)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
 
        printk(KERN_DEBUG "%s: NIC status %08x mode %08x sia %08x desc %u/%u/%u\n",
               dev->name, dr32(MacStatus), dr32(MacMode), dr32(SIAStatus),
@@ -1574,7 +1573,7 @@ static int __de_set_settings(struct de_private *de, struct ethtool_cmd *ecmd)
 
 static void de_get_drvinfo (struct net_device *dev,struct ethtool_drvinfo *info)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
 
        strcpy (info->driver, DRV_NAME);
        strcpy (info->version, DRV_VERSION);
@@ -1589,7 +1588,7 @@ static int de_get_regs_len(struct net_device *dev)
 
 static int de_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
        int rc;
 
        spin_lock_irq(&de->lock);
@@ -1601,7 +1600,7 @@ static int de_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 
 static int de_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
        int rc;
 
        spin_lock_irq(&de->lock);
@@ -1613,14 +1612,14 @@ static int de_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 
 static u32 de_get_msglevel(struct net_device *dev)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
 
        return de->msg_enable;
 }
 
 static void de_set_msglevel(struct net_device *dev, u32 msglvl)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
 
        de->msg_enable = msglvl;
 }
@@ -1628,7 +1627,7 @@ static void de_set_msglevel(struct net_device *dev, u32 msglvl)
 static int de_get_eeprom(struct net_device *dev,
                         struct ethtool_eeprom *eeprom, u8 *data)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
 
        if (!de->ee_data)
                return -EOPNOTSUPP;
@@ -1642,7 +1641,7 @@ static int de_get_eeprom(struct net_device *dev,
 
 static int de_nway_reset(struct net_device *dev)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
        u32 status;
 
        if (de->media_type != DE_MEDIA_TP_AUTO)
@@ -1661,7 +1660,7 @@ static int de_nway_reset(struct net_device *dev)
 static void de_get_regs(struct net_device *dev, struct ethtool_regs *regs,
                        void *data)
 {
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
 
        regs->version = (DE_REGS_VER << 2) | de->de21040;
 
@@ -1932,7 +1931,6 @@ static int __devinit de_init_one (struct pci_dev *pdev,
        void __iomem *regs;
        unsigned long pciaddr;
        static int board_idx = -1;
-       DECLARE_MAC_BUF(mac);
 
        board_idx++;
 
@@ -1956,7 +1954,7 @@ static int __devinit de_init_one (struct pci_dev *pdev,
        dev->tx_timeout = de_tx_timeout;
        dev->watchdog_timeo = TX_TIMEOUT;
 
-       de = dev->priv;
+       de = netdev_priv(dev);
        de->de21040 = ent->driver_data == 0 ? 1 : 0;
        de->pdev = pdev;
        de->dev = dev;
@@ -2046,11 +2044,11 @@ static int __devinit de_init_one (struct pci_dev *pdev,
                goto err_out_iomap;
 
        /* print info about board and interface just registered */
-       printk (KERN_INFO "%s: %s at 0x%lx, %s, IRQ %d\n",
+       printk (KERN_INFO "%s: %s at 0x%lx, %pM, IRQ %d\n",
                dev->name,
                de->de21040 ? "21040" : "21041",
                dev->base_addr,
-               print_mac(mac, dev->dev_addr),
+               dev->dev_addr,
                dev->irq);
 
        pci_set_drvdata(pdev, dev);
@@ -2078,7 +2076,7 @@ err_out_free:
 static void __devexit de_remove_one (struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
 
        BUG_ON(!dev);
        unregister_netdev(dev);
@@ -2095,7 +2093,7 @@ static void __devexit de_remove_one (struct pci_dev *pdev)
 static int de_suspend (struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *dev = pci_get_drvdata (pdev);
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
 
        rtnl_lock();
        if (netif_running (dev)) {
@@ -2130,7 +2128,7 @@ static int de_suspend (struct pci_dev *pdev, pm_message_t state)
 static int de_resume (struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata (pdev);
-       struct de_private *de = dev->priv;
+       struct de_private *de = netdev_priv(dev);
        int retval = 0;
 
        rtnl_lock();
index 6444cbec0bdc8dd02a0a9eca4c2066af15be2a96..67bfd6f4336617854f1c627544a4181b226ad585 100644 (file)
@@ -1085,7 +1085,6 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev)
     struct de4x5_private *lp = netdev_priv(dev);
     struct pci_dev *pdev = NULL;
     int i, status=0;
-    DECLARE_MAC_BUF(mac);
 
     gendev->driver_data = dev;
 
@@ -1119,10 +1118,10 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev)
     }
 
     dev->base_addr = iobase;
-    printk ("%s: %s at 0x%04lx", gendev->bus_id, name, iobase);
+    printk ("%s: %s at 0x%04lx", dev_name(gendev), name, iobase);
 
     status = get_hw_addr(dev);
-    printk(", h/w address %s\n", print_mac(mac, dev->dev_addr));
+    printk(", h/w address %pM\n", dev->dev_addr);
 
     if (status != 0) {
        printk("      which has an Ethernet PROM CRC error.\n");
@@ -1154,7 +1153,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev)
             }
         }
        lp->fdx = lp->params.fdx;
-       sprintf(lp->adapter_name,"%s (%s)", name, gendev->bus_id);
+       sprintf(lp->adapter_name,"%s (%s)", name, dev_name(gendev));
 
        lp->dma_size = (NUM_RX_DESC + NUM_TX_DESC) * sizeof(struct de4x5_desc);
 #if defined(__alpha__) || defined(__powerpc__) || defined(CONFIG_SPARC) || defined(DE4X5_DO_MEMCPY)
@@ -1647,7 +1646,6 @@ de4x5_rx(struct net_device *dev)
                    netif_rx(skb);
 
                    /* Update stats */
-                   dev->last_rx = jiffies;
                    lp->stats.rx_packets++;
                    lp->stats.rx_bytes += pkt_len;
                }
@@ -5401,7 +5399,6 @@ static void
 de4x5_dbg_srom(struct de4x5_srom *p)
 {
     int i;
-    DECLARE_MAC_BUF(mac);
 
     if (de4x5_debug & DEBUG_SROM) {
        printk("Sub-system Vendor ID: %04x\n", *((u_short *)p->sub_vendor_id));
@@ -5410,7 +5407,7 @@ de4x5_dbg_srom(struct de4x5_srom *p)
        printk("SROM version:         %02x\n", (u_char)(p->version));
        printk("# controllers:        %02x\n", (u_char)(p->num_controllers));
 
-       printk("Hardware Address:     %s\n", print_mac(mac, p->ieee_addr));
+       printk("Hardware Address:     %pM\n", p->ieee_addr);
        printk("CRC checksum:         %04x\n", (u_short)(p->chksum));
        for (i=0; i<64; i++) {
            printk("%3d %04x\n", i<<1, (u_short)*((u_short *)p+i));
@@ -5424,12 +5421,10 @@ static void
 de4x5_dbg_rx(struct sk_buff *skb, int len)
 {
     int i, j;
-    DECLARE_MAC_BUF(mac);
-    DECLARE_MAC_BUF(mac2);
 
     if (de4x5_debug & DEBUG_RX) {
-       printk("R: %s <- %s len/SAP:%02x%02x [%d]\n",
-              print_mac(mac, skb->data), print_mac(mac2, &skb->data[6]),
+       printk("R: %pM <- %pM len/SAP:%02x%02x [%d]\n",
+              skb->data, &skb->data[6],
               (u_char)skb->data[12],
               (u_char)skb->data[13],
               len);
index c91852f49a48e015cfc6056d337607087263f837..28a5c51b43a0654a846a2a4fa33f92f64d516602 100644 (file)
@@ -362,7 +362,6 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
        struct net_device *dev;
        u32 pci_pmr;
        int i, err;
-       DECLARE_MAC_BUF(mac);
 
        DMFE_DBUG(0, "dmfe_init_one()", 0);
 
@@ -475,12 +474,11 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
        if (err)
                goto err_out_free_buf;
 
-       printk(KERN_INFO "%s: Davicom DM%04lx at pci%s, "
-              "%s, irq %d.\n",
+       printk(KERN_INFO "%s: Davicom DM%04lx at pci%s, %pM, irq %d.\n",
               dev->name,
               ent->driver_data >> 16,
               pci_name(pdev),
-              print_mac(mac, dev->dev_addr),
+              dev->dev_addr,
               dev->irq);
 
        pci_set_master(pdev);
@@ -1010,7 +1008,6 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db)
 
                                        skb->protocol = eth_type_trans(skb, dev);
                                        netif_rx(skb);
-                                       dev->last_rx = jiffies;
                                        db->stats.rx_packets++;
                                        db->stats.rx_bytes += rxlen;
                                }
index 0dcced1263b9879fdf072b02d65f4d879da761d2..391acd32a6a5c04cc6234ddcb1b8833bff3f7a18 100644 (file)
@@ -337,7 +337,7 @@ int __devinit tulip_read_eeprom(struct net_device *dev, int location, int addr_l
 {
        int i;
        unsigned retval = 0;
-       struct tulip_private *tp = dev->priv;
+       struct tulip_private *tp = netdev_priv(dev);
        void __iomem *ee_addr = tp->base_addr + CSR9;
        int read_cmd = location | (EE_READ_CMD << addr_len);
 
index c6bad987d63e744c452ed9d8b999aa0affe441d0..739d610d18c5e6ab7958e52e545405a12b1babe3 100644 (file)
@@ -231,7 +231,6 @@ int tulip_poll(struct napi_struct *napi, int budget)
 
                                netif_receive_skb(skb);
 
-                               dev->last_rx = jiffies;
                                tp->stats.rx_packets++;
                                tp->stats.rx_bytes += pkt_len;
                        }
@@ -444,7 +443,6 @@ static int tulip_rx(struct net_device *dev)
 
                        netif_rx(skb);
 
-                       dev->last_rx = jiffies;
                        tp->stats.rx_packets++;
                        tp->stats.rx_bytes += pkt_len;
                }
index cafa89e6016772b0a5442df05dd348ae4984c857..1c5ef230b7709d4db904ff5ba74a70c61a11e9a1 100644 (file)
@@ -1050,13 +1050,11 @@ static void set_rx_mode(struct net_device *dev)
                                        filterbit = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
                                filterbit &= 0x3f;
                                mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
-                               if (tulip_debug > 2) {
-                                       DECLARE_MAC_BUF(mac);
-                                       printk(KERN_INFO "%s: Added filter for %s"
+                               if (tulip_debug > 2)
+                                       printk(KERN_INFO "%s: Added filter for %pM"
                                               "  %8.8x bit %d.\n",
-                                              dev->name, print_mac(mac, mclist->dmi_addr),
+                                              dev->name, mclist->dmi_addr,
                                               ether_crc(ETH_ALEN, mclist->dmi_addr), filterbit);
-                               }
                        }
                        if (mc_filter[0] == tp->mc_filter[0]  &&
                                mc_filter[1] == tp->mc_filter[1])
@@ -1250,7 +1248,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        const char *chip_name = tulip_tbl[chip_idx].chip_name;
        unsigned int eeprom_missing = 0;
        unsigned int force_csr0 = 0;
-       DECLARE_MAC_BUF(mac);
 
 #ifndef MODULE
        static int did_version;         /* Already printed version info. */
@@ -1635,7 +1632,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
 
        if (eeprom_missing)
                printk(" EEPROM not present,");
-       printk(" %s", print_mac(mac, dev->dev_addr));
+       printk(" %pM", dev->dev_addr);
        printk(", IRQ %d.\n", irq);
 
         if (tp->chip_id == PNIC2)
index e9e628621639b6d5d8ceaf850086bf8da9587ab1..00cbc5251dccd16d083c69a93664fa5bb627e991 100644 (file)
@@ -261,7 +261,6 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev,
        struct uli526x_board_info *db;  /* board information structure */
        struct net_device *dev;
        int i, err;
-       DECLARE_MAC_BUF(mac);
 
        ULI526X_DBUG(0, "uli526x_init_one()", 0);
 
@@ -379,9 +378,9 @@ static int __devinit uli526x_init_one (struct pci_dev *pdev,
        if (err)
                goto err_out_res;
 
-       printk(KERN_INFO "%s: ULi M%04lx at pci%s, %s, irq %d.\n",
+       printk(KERN_INFO "%s: ULi M%04lx at pci%s, %pM, irq %d.\n",
               dev->name,ent->driver_data >> 16,pci_name(pdev),
-              print_mac(mac, dev->dev_addr), dev->irq);
+              dev->dev_addr, dev->irq);
 
        pci_set_master(pdev);
 
@@ -855,7 +854,6 @@ static void uli526x_rx_packet(struct net_device *dev, struct uli526x_board_info
 
                                skb->protocol = eth_type_trans(skb, dev);
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                                db->stats.rx_packets++;
                                db->stats.rx_bytes += rxlen;
 
@@ -892,7 +890,7 @@ static struct net_device_stats * uli526x_get_stats(struct net_device *dev)
 
 static void uli526x_set_filter_mode(struct net_device * dev)
 {
-       struct uli526x_board_info *db = dev->priv;
+       struct uli526x_board_info *db = netdev_priv(dev);
        unsigned long flags;
 
        ULI526X_DBUG(0, "uli526x_set_filter_mode()", 0);
index 50068194c163e55baec8c6e00bce96c970f56798..022d99af8646303bb25b1e0b7c7c4c6929fbee88 100644 (file)
@@ -355,7 +355,6 @@ static int __devinit w840_probe1 (struct pci_dev *pdev,
        int irq;
        int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;
        void __iomem *ioaddr;
-       DECLARE_MAC_BUF(mac);
 
        i = pci_enable_device(pdev);
        if (i) return i;
@@ -435,9 +434,9 @@ static int __devinit w840_probe1 (struct pci_dev *pdev,
        if (i)
                goto err_out_cleardev;
 
-       printk(KERN_INFO "%s: %s at %p, %s, IRQ %d.\n",
+       printk(KERN_INFO "%s: %s at %p, %pM, IRQ %d.\n",
               dev->name, pci_id_tbl[chip_idx].name, ioaddr,
-              print_mac(mac, dev->dev_addr), irq);
+              dev->dev_addr, irq);
 
        if (np->drv_flags & CanHaveMII) {
                int phy, phy_idx = 0;
@@ -1245,20 +1244,15 @@ static int netdev_rx(struct net_device *dev)
                        }
 #ifndef final_version                          /* Remove after testing. */
                        /* You will want this info for the initial debug. */
-                       if (debug > 5) {
-                               DECLARE_MAC_BUF(mac);
-                               DECLARE_MAC_BUF(mac2);
-
-                               printk(KERN_DEBUG "  Rx data %s %s"
+                       if (debug > 5)
+                               printk(KERN_DEBUG "  Rx data %pM %pM"
                                       " %2.2x%2.2x %d.%d.%d.%d.\n",
-                                      print_mac(mac, &skb->data[0]), print_mac(mac2, &skb->data[6]),
+                                      &skb->data[0], &skb->data[6],
                                       skb->data[12], skb->data[13],
                                       skb->data[14], skb->data[15], skb->data[16], skb->data[17]);
-                       }
 #endif
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        np->stats.rx_packets++;
                        np->stats.rx_bytes += pkt_len;
                }
index 6b93d016911650e0ef778ffeaf3dd9c06e370069..13c8703ecb9f0794e4ca718797a8ea0ea3ef8ed9 100644 (file)
@@ -1072,7 +1072,6 @@ static void read_mac_address(struct xircom_private *card)
        unsigned char j, tuple, link, data_id, data_count;
        unsigned long flags;
        int i;
-       DECLARE_MAC_BUF(mac);
 
        enter("read_mac_address");
 
@@ -1102,7 +1101,7 @@ static void read_mac_address(struct xircom_private *card)
                }
        }
        spin_unlock_irqrestore(&card->lock, flags);
-       pr_debug(" %s\n", print_mac(mac, card->dev->dev_addr));
+       pr_debug(" %pM\n", card->dev->dev_addr);
        leave("read_mac_address");
 }
 
@@ -1202,7 +1201,6 @@ static void investigate_read_descriptor(struct net_device *dev,struct xircom_pri
                        skb_put(skb, pkt_len);
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        card->stats.rx_packets++;
                        card->stats.rx_bytes += pkt_len;
 
index 33b6d1b122fb59fdadfdd2f156a0596f37efcc25..5a6203072ce71f0694540210cf33a6ad44dc17e7 100644 (file)
@@ -529,7 +529,6 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
        }
 
        netif_rx_ni(skb);
-       tun->dev->last_rx = jiffies;
 
        tun->dev->stats.rx_packets++;
        tun->dev->stats.rx_bytes += len;
@@ -883,7 +882,6 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
        void __user* argp = (void __user*)arg;
        struct ifreq ifr;
        int ret;
-       DECLARE_MAC_BUF(mac);
 
        if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
                if (copy_from_user(&ifr, argp, sizeof ifr))
@@ -1011,8 +1009,8 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
 
        case SIOCSIFHWADDR:
                /* Set hw address */
-               DBG(KERN_DEBUG "%s: set hw address: %s\n",
-                       tun->dev->name, print_mac(mac, ifr.ifr_hwaddr.sa_data));
+               DBG(KERN_DEBUG "%s: set hw address: %pM\n",
+                       tun->dev->name, ifr.ifr_hwaddr.sa_data);
 
                rtnl_lock();
                ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr);
index 734ce0977f02891e1c6d7a0ac0ba666e3f36ec49..5386d9b73e6aa78798138e703c9fc520dcea0cbf 100644 (file)
@@ -1729,7 +1729,6 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * read
                        netif_receive_skb(new_skb);
                spin_unlock(&tp->state_lock);
 
-               tp->dev->last_rx = jiffies;
                received++;
                budget--;
        }
@@ -1798,7 +1797,7 @@ static irqreturn_t
 typhoon_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
-       struct typhoon *tp = dev->priv;
+       struct typhoon *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->ioaddr;
        u32 intr_status;
 
@@ -2311,7 +2310,6 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        struct cmd_desc xp_cmd;
        struct resp_desc xp_resp[3];
        int err = 0;
-       DECLARE_MAC_BUF(mac);
 
        if(!did_version++)
                printk(KERN_INFO "%s", version);
@@ -2526,11 +2524,11 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        pci_set_drvdata(pdev, dev);
 
-       printk(KERN_INFO "%s: %s at %s 0x%llx, %s\n",
+       printk(KERN_INFO "%s: %s at %s 0x%llx, %pM\n",
               dev->name, typhoon_card_info[card_id].name,
               use_mmio ? "MMIO" : "IO",
               (unsigned long long)pci_resource_start(pdev, use_mmio),
-              print_mac(mac, dev->dev_addr));
+              dev->dev_addr);
 
        /* xp_resp still contains the response to the READ_VERSIONS command.
         * For debugging, let the user know what version he has.
index c87747bb24c55eb9ea2ac58992eabfdf348b664b..0a5b817fd7ac9e66ac7a5c7ab379a973fdd3888b 100644 (file)
@@ -1615,8 +1615,8 @@ static int init_phy(struct net_device *dev)
        priv->oldspeed = 0;
        priv->oldduplex = -1;
 
-       snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, priv->ug_info->mdio_bus,
-                       priv->ug_info->phy_address);
+       snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, priv->ug_info->mdio_bus,
+                priv->ug_info->phy_address);
 
        phydev = phy_connect(dev, phy_id, &adjust_link, 0, priv->phy_interface);
 
@@ -3502,8 +3502,6 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
                        netif_receive_skb(skb);
                }
 
-               ugeth->dev->last_rx = jiffies;
-
                skb = get_new_skb(ugeth, bd);
                if (!skb) {
                        if (netif_msg_rx_err(ugeth))
index 466a89e244445cb59bdd3a94c43c184be4fee185..d7621239059a52bab6de340941f625868bfd50b1 100644 (file)
@@ -271,8 +271,6 @@ static void catc_rx_done(struct urb *urb)
 
        } while (pkt_start - (u8 *) urb->transfer_buffer < urb->actual_length);
 
-       catc->netdev->last_rx = jiffies;
-
        if (catc->is_f5u011) {
                if (atomic_read(&catc->recq_sz)) {
                        int status;
index b5143509e8be1f70e0433939d30ac44ef9a7e28f..bbcc76ae3c9cde15298c9079ef7542d82c9a89b8 100644 (file)
@@ -344,14 +344,14 @@ out:
 static int mcs7830_mdio_read(struct net_device *netdev, int phy_id,
                             int location)
 {
-       struct usbnet *dev = netdev->priv;
+       struct usbnet *dev = netdev_priv(netdev);
        return mcs7830_read_phy(dev, location);
 }
 
 static void mcs7830_mdio_write(struct net_device *netdev, int phy_id,
                                int location, int val)
 {
-       struct usbnet *dev = netdev->priv;
+       struct usbnet *dev = netdev_priv(netdev);
        mcs7830_write_phy(dev, location, val);
 }
 
index 7914867110ed74ef3e0f17f4dcba685ea4450d73..075e8e94225e29aae6f4ed9a0c13bcc358392d31 100644 (file)
@@ -1213,7 +1213,7 @@ static void pegasus_set_multicast(struct net_device *net)
                pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST;
                pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
                if (netif_msg_link(pegasus))
-                       pr_info("%s: set allmulti\n", net->name);
+                       pr_debug("%s: set allmulti\n", net->name);
        } else {
                pegasus->eth_regs[EthCtrl0] &= ~RX_MULTICAST;
                pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
@@ -1273,6 +1273,7 @@ static inline void setup_pegasus_II(pegasus_t * pegasus)
 }
 
 
+static int pegasus_count;
 static struct workqueue_struct *pegasus_workqueue = NULL;
 #define CARRIER_CHECK_DELAY (2 * HZ)
 
@@ -1301,6 +1302,18 @@ static int pegasus_blacklisted(struct usb_device *udev)
        return 0;
 }
 
+/* we rely on probe() and remove() being serialized so we
+ * don't need extra locking on pegasus_count.
+ */
+static void pegasus_dec_workqueue(void)
+{
+       pegasus_count--;
+       if (pegasus_count == 0) {
+               destroy_workqueue(pegasus_workqueue);
+               pegasus_workqueue = NULL;
+       }
+}
+
 static int pegasus_probe(struct usb_interface *intf,
                         const struct usb_device_id *id)
 {
@@ -1309,14 +1322,18 @@ static int pegasus_probe(struct usb_interface *intf,
        pegasus_t *pegasus;
        int dev_index = id - pegasus_ids;
        int res = -ENOMEM;
-       DECLARE_MAC_BUF(mac);
 
-       usb_get_dev(dev);
+       if (pegasus_blacklisted(dev))
+               return -ENODEV;
 
-       if (pegasus_blacklisted(dev)) {
-               res = -ENODEV;
-               goto out;
+       if (pegasus_count == 0) {
+               pegasus_workqueue = create_singlethread_workqueue("pegasus");
+               if (!pegasus_workqueue)
+                       return -ENOMEM;
        }
+       pegasus_count++;
+
+       usb_get_dev(dev);
 
        net = alloc_etherdev(sizeof(struct pegasus));
        if (!net) {
@@ -1386,10 +1403,10 @@ static int pegasus_probe(struct usb_interface *intf,
        queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check,
                                CARRIER_CHECK_DELAY);
 
-       dev_info(&intf->dev, "%s, %s, %s\n",
+       dev_info(&intf->dev, "%s, %s, %pM\n",
                 net->name,
                 usb_dev_id[dev_index].name,
-                print_mac(mac, net->dev_addr));
+                net->dev_addr);
        return 0;
 
 out3:
@@ -1401,6 +1418,7 @@ out1:
        free_netdev(net);
 out:
        usb_put_dev(dev);
+       pegasus_dec_workqueue();
        return res;
 }
 
@@ -1426,6 +1444,7 @@ static void pegasus_disconnect(struct usb_interface *intf)
                pegasus->rx_skb = NULL;
        }
        free_netdev(pegasus->net);
+       pegasus_dec_workqueue();
 }
 
 static int pegasus_suspend (struct usb_interface *intf, pm_message_t message)
@@ -1469,7 +1488,7 @@ static struct usb_driver pegasus_driver = {
        .resume = pegasus_resume,
 };
 
-static void parse_id(char *id)
+static void __init parse_id(char *id)
 {
        unsigned int vendor_id=0, device_id=0, flags=0, i=0;
        char *token, *name=NULL;
@@ -1505,15 +1524,11 @@ static int __init pegasus_init(void)
        pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION);
        if (devid)
                parse_id(devid);
-       pegasus_workqueue = create_singlethread_workqueue("pegasus");
-       if (!pegasus_workqueue)
-               return -ENOMEM;
        return usb_register(&pegasus_driver);
 }
 
 static void __exit pegasus_exit(void)
 {
-       destroy_workqueue(pegasus_workqueue);
        usb_deregister(&pegasus_driver);
 }
 
index 51e2f5d7d14e5d5eaead2064c64d9cdef7df51ac..e0d349f7464212e4e28fb50c804f81451409f9b3 100644 (file)
@@ -759,7 +759,6 @@ static int smsc95xx_reset(struct usbnet *dev)
        struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
        u32 read_buf, write_buf, burst_cap;
        int ret = 0, timeout;
-       DECLARE_MAC_BUF(mac);
 
        if (netif_msg_ifup(dev))
                devdbg(dev, "entering smsc95xx_reset");
@@ -818,8 +817,7 @@ static int smsc95xx_reset(struct usbnet *dev)
                return ret;
 
        if (netif_msg_ifup(dev))
-               devdbg(dev, "MAC Address: %s",
-                       print_mac(mac, dev->net->dev_addr));
+               devdbg(dev, "MAC Address: %pM", dev->net->dev_addr);
 
        ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
        if (ret < 0) {
index 02d25c743994e3f5539744587697ae1685187e16..aa31490788880bb3b609acae0a9ab7332cce28c7 100644 (file)
@@ -1125,7 +1125,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
        struct usb_device               *xdev;
        int                             status;
        const char                      *name;
-       DECLARE_MAC_BUF(mac);
 
        name = udev->dev.driver->name;
        info = (struct driver_info *) prod->driver_info;
@@ -1236,11 +1235,11 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
        if (status)
                goto out3;
        if (netif_msg_probe (dev))
-               devinfo (dev, "register '%s' at usb-%s-%s, %s, %s",
+               devinfo (dev, "register '%s' at usb-%s-%s, %s, %pM",
                        udev->dev.driver->name,
                        xdev->bus->bus_name, xdev->devpath,
                        dev->driver_info->description,
-                       print_mac(mac, net->dev_addr));
+                       net->dev_addr);
 
        // ok, it's ready to go.
        usb_set_intfdata (udev, dev);
index 31cd817f33f97be658d31bed4ba93ec101312255..75b40fefc4ee446b2d073f4d5dc3351f6a15b996 100644 (file)
@@ -8,7 +8,6 @@
  *
  */
 
-#include <linux/list.h>
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
 #include <linux/etherdevice.h>
@@ -30,14 +29,10 @@ struct veth_net_stats {
 
 struct veth_priv {
        struct net_device *peer;
-       struct net_device *dev;
-       struct list_head list;
        struct veth_net_stats *stats;
        unsigned ip_summed;
 };
 
-static LIST_HEAD(veth_list);
-
 /*
  * ethtool interface
  */
@@ -420,14 +415,10 @@ static int veth_newlink(struct net_device *dev,
         */
 
        priv = netdev_priv(dev);
-       priv->dev = dev;
        priv->peer = peer;
-       list_add(&priv->list, &veth_list);
 
        priv = netdev_priv(peer);
-       priv->dev = peer;
        priv->peer = dev;
-       INIT_LIST_HEAD(&priv->list);
        return 0;
 
 err_register_dev:
@@ -449,13 +440,6 @@ static void veth_dellink(struct net_device *dev)
        priv = netdev_priv(dev);
        peer = priv->peer;
 
-       if (!list_empty(&priv->list))
-               list_del(&priv->list);
-
-       priv = netdev_priv(peer);
-       if (!list_empty(&priv->list))
-               list_del(&priv->list);
-
        unregister_netdevice(dev);
        unregister_netdevice(peer);
 }
index 5b7870080c5661d36325c72c95ee9975d36fd4a3..9a650d0a67958663b5b3c97dffb9fe1677457dd4 100644 (file)
@@ -631,7 +631,6 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
 #else
        int bar = 0;
 #endif
-       DECLARE_MAC_BUF(mac);
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -787,14 +786,14 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
        if (rc)
                goto err_out_unmap;
 
-       printk(KERN_INFO "%s: VIA %s at 0x%lx, %s, IRQ %d.\n",
+       printk(KERN_INFO "%s: VIA %s at 0x%lx, %pM, IRQ %d.\n",
               dev->name, name,
 #ifdef USE_MMIO
               memaddr,
 #else
               (long)ioaddr,
 #endif
-              print_mac(mac, dev->dev_addr), pdev->irq);
+              dev->dev_addr, pdev->irq);
 
        pci_set_drvdata(pdev, dev);
 
@@ -1505,7 +1504,6 @@ static int rhine_rx(struct net_device *dev, int limit)
                        }
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_receive_skb(skb);
-                       dev->last_rx = jiffies;
                        rp->stats.rx_bytes += pkt_len;
                        rp->stats.rx_packets++;
                }
index 11cb3e504e1cb43e16c4eb5b81dda369ab4c75c1..dcbc152306e25404085228b7f99d990edb541203 100644 (file)
@@ -1412,8 +1412,6 @@ static int velocity_rx_srv(struct velocity_info *vptr, int status)
 
                rd->size |= RX_INTEN;
 
-               vptr->dev->last_rx = jiffies;
-
                rd_curr++;
                if (rd_curr >= vptr->options.numrx)
                        rd_curr = 0;
index 0196a0df90210995ec6a5abe228eb23bb22d494c..e6b5d6ef9ea8223868375a0d2f184869b200b447 100644 (file)
@@ -34,6 +34,7 @@ module_param(gso, bool, 0444);
 
 /* FIXME: MTU in config. */
 #define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN)
+#define GOOD_COPY_LEN  128
 
 struct virtnet_info
 {
@@ -58,6 +59,9 @@ struct virtnet_info
        /* I like... big packets and I cannot lie! */
        bool big_packets;
 
+       /* Host will merge rx buffers for big packets (shake it! shake it!) */
+       bool mergeable_rx_bufs;
+
        /* Receive & send queues. */
        struct sk_buff_head recv;
        struct sk_buff_head send;
@@ -66,22 +70,27 @@ struct virtnet_info
        struct page *pages;
 };
 
-static inline struct virtio_net_hdr *skb_vnet_hdr(struct sk_buff *skb)
+static inline void *skb_vnet_hdr(struct sk_buff *skb)
 {
        return (struct virtio_net_hdr *)skb->cb;
 }
 
-static inline void vnet_hdr_to_sg(struct scatterlist *sg, struct sk_buff *skb)
-{
-       sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr));
-}
-
 static void give_a_page(struct virtnet_info *vi, struct page *page)
 {
        page->private = (unsigned long)vi->pages;
        vi->pages = page;
 }
 
+static void trim_pages(struct virtnet_info *vi, struct sk_buff *skb)
+{
+       unsigned int i;
+
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
+               give_a_page(vi, skb_shinfo(skb)->frags[i].page);
+       skb_shinfo(skb)->nr_frags = 0;
+       skb->data_len = 0;
+}
+
 static struct page *get_a_page(struct virtnet_info *vi, gfp_t gfp_mask)
 {
        struct page *p = vi->pages;
@@ -111,31 +120,97 @@ static void skb_xmit_done(struct virtqueue *svq)
 static void receive_skb(struct net_device *dev, struct sk_buff *skb,
                        unsigned len)
 {
+       struct virtnet_info *vi = netdev_priv(dev);
        struct virtio_net_hdr *hdr = skb_vnet_hdr(skb);
        int err;
+       int i;
 
        if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
                pr_debug("%s: short packet %i\n", dev->name, len);
                dev->stats.rx_length_errors++;
                goto drop;
        }
-       len -= sizeof(struct virtio_net_hdr);
 
-       if (len <= MAX_PACKET_LEN) {
-               unsigned int i;
+       if (vi->mergeable_rx_bufs) {
+               struct virtio_net_hdr_mrg_rxbuf *mhdr = skb_vnet_hdr(skb);
+               unsigned int copy;
+               char *p = page_address(skb_shinfo(skb)->frags[0].page);
 
-               for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-                       give_a_page(dev->priv, skb_shinfo(skb)->frags[i].page);
-               skb->data_len = 0;
-               skb_shinfo(skb)->nr_frags = 0;
-       }
+               if (len > PAGE_SIZE)
+                       len = PAGE_SIZE;
+               len -= sizeof(struct virtio_net_hdr_mrg_rxbuf);
 
-       err = pskb_trim(skb, len);
-       if (err) {
-               pr_debug("%s: pskb_trim failed %i %d\n", dev->name, len, err);
-               dev->stats.rx_dropped++;
-               goto drop;
+               memcpy(hdr, p, sizeof(*mhdr));
+               p += sizeof(*mhdr);
+
+               copy = len;
+               if (copy > skb_tailroom(skb))
+                       copy = skb_tailroom(skb);
+
+               memcpy(skb_put(skb, copy), p, copy);
+
+               len -= copy;
+
+               if (!len) {
+                       give_a_page(vi, skb_shinfo(skb)->frags[0].page);
+                       skb_shinfo(skb)->nr_frags--;
+               } else {
+                       skb_shinfo(skb)->frags[0].page_offset +=
+                               sizeof(*mhdr) + copy;
+                       skb_shinfo(skb)->frags[0].size = len;
+                       skb->data_len += len;
+                       skb->len += len;
+               }
+
+               while (--mhdr->num_buffers) {
+                       struct sk_buff *nskb;
+
+                       i = skb_shinfo(skb)->nr_frags;
+                       if (i >= MAX_SKB_FRAGS) {
+                               pr_debug("%s: packet too long %d\n", dev->name,
+                                        len);
+                               dev->stats.rx_length_errors++;
+                               goto drop;
+                       }
+
+                       nskb = vi->rvq->vq_ops->get_buf(vi->rvq, &len);
+                       if (!nskb) {
+                               pr_debug("%s: rx error: %d buffers missing\n",
+                                        dev->name, mhdr->num_buffers);
+                               dev->stats.rx_length_errors++;
+                               goto drop;
+                       }
+
+                       __skb_unlink(nskb, &vi->recv);
+                       vi->num--;
+
+                       skb_shinfo(skb)->frags[i] = skb_shinfo(nskb)->frags[0];
+                       skb_shinfo(nskb)->nr_frags = 0;
+                       kfree_skb(nskb);
+
+                       if (len > PAGE_SIZE)
+                               len = PAGE_SIZE;
+
+                       skb_shinfo(skb)->frags[i].size = len;
+                       skb_shinfo(skb)->nr_frags++;
+                       skb->data_len += len;
+                       skb->len += len;
+               }
+       } else {
+               len -= sizeof(struct virtio_net_hdr);
+
+               if (len <= MAX_PACKET_LEN)
+                       trim_pages(vi, skb);
+
+               err = pskb_trim(skb, len);
+               if (err) {
+                       pr_debug("%s: pskb_trim failed %i %d\n", dev->name,
+                                len, err);
+                       dev->stats.rx_dropped++;
+                       goto drop;
+               }
        }
+
        skb->truesize += skb->data_len;
        dev->stats.rx_bytes += skb->len;
        dev->stats.rx_packets++;
@@ -194,7 +269,7 @@ drop:
        dev_kfree_skb(skb);
 }
 
-static void try_fill_recv(struct virtnet_info *vi)
+static void try_fill_recv_maxbufs(struct virtnet_info *vi)
 {
        struct sk_buff *skb;
        struct scatterlist sg[2+MAX_SKB_FRAGS];
@@ -202,12 +277,16 @@ static void try_fill_recv(struct virtnet_info *vi)
 
        sg_init_table(sg, 2+MAX_SKB_FRAGS);
        for (;;) {
+               struct virtio_net_hdr *hdr;
+
                skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN);
                if (unlikely(!skb))
                        break;
 
                skb_put(skb, MAX_PACKET_LEN);
-               vnet_hdr_to_sg(sg, skb);
+
+               hdr = skb_vnet_hdr(skb);
+               sg_init_one(sg, hdr, sizeof(*hdr));
 
                if (vi->big_packets) {
                        for (i = 0; i < MAX_SKB_FRAGS; i++) {
@@ -230,6 +309,55 @@ static void try_fill_recv(struct virtnet_info *vi)
                skb_queue_head(&vi->recv, skb);
 
                err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb);
+               if (err) {
+                       skb_unlink(skb, &vi->recv);
+                       trim_pages(vi, skb);
+                       kfree_skb(skb);
+                       break;
+               }
+               vi->num++;
+       }
+       if (unlikely(vi->num > vi->max))
+               vi->max = vi->num;
+       vi->rvq->vq_ops->kick(vi->rvq);
+}
+
+static void try_fill_recv(struct virtnet_info *vi)
+{
+       struct sk_buff *skb;
+       struct scatterlist sg[1];
+       int err;
+
+       if (!vi->mergeable_rx_bufs) {
+               try_fill_recv_maxbufs(vi);
+               return;
+       }
+
+       for (;;) {
+               skb_frag_t *f;
+
+               skb = netdev_alloc_skb(vi->dev, GOOD_COPY_LEN + NET_IP_ALIGN);
+               if (unlikely(!skb))
+                       break;
+
+               skb_reserve(skb, NET_IP_ALIGN);
+
+               f = &skb_shinfo(skb)->frags[0];
+               f->page = get_a_page(vi, GFP_ATOMIC);
+               if (!f->page) {
+                       kfree_skb(skb);
+                       break;
+               }
+
+               f->page_offset = 0;
+               f->size = PAGE_SIZE;
+
+               skb_shinfo(skb)->nr_frags++;
+
+               sg_init_one(sg, page_address(f->page), PAGE_SIZE);
+               skb_queue_head(&vi->recv, skb);
+
+               err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, 1, skb);
                if (err) {
                        skb_unlink(skb, &vi->recv);
                        kfree_skb(skb);
@@ -320,17 +448,14 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
 {
        int num, err;
        struct scatterlist sg[2+MAX_SKB_FRAGS];
-       struct virtio_net_hdr *hdr;
+       struct virtio_net_hdr_mrg_rxbuf *mhdr = skb_vnet_hdr(skb);
+       struct virtio_net_hdr *hdr = skb_vnet_hdr(skb);
        const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
 
        sg_init_table(sg, 2+MAX_SKB_FRAGS);
 
-       pr_debug("%s: xmit %p " MAC_FMT "\n", vi->dev->name, skb,
-                dest[0], dest[1], dest[2],
-                dest[3], dest[4], dest[5]);
+       pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest);
 
-       /* Encode metadata header at front. */
-       hdr = skb_vnet_hdr(skb);
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
                hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
                hdr->csum_start = skb->csum_start - skb_headroom(skb);
@@ -358,7 +483,14 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
                hdr->gso_size = hdr->hdr_len = 0;
        }
 
-       vnet_hdr_to_sg(sg, skb);
+       mhdr->num_buffers = 0;
+
+       /* Encode metadata header at front. */
+       if (vi->mergeable_rx_bufs)
+               sg_init_one(sg, mhdr, sizeof(*mhdr));
+       else
+               sg_init_one(sg, hdr, sizeof(*hdr));
+
        num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
 
        err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb);
@@ -478,6 +610,7 @@ static int virtnet_set_tx_csum(struct net_device *dev, u32 data)
 static struct ethtool_ops virtnet_ethtool_ops = {
        .set_tx_csum = virtnet_set_tx_csum,
        .set_sg = ethtool_op_set_sg,
+       .set_tso = ethtool_op_set_tso,
 };
 
 static int virtnet_probe(struct virtio_device *vdev)
@@ -547,6 +680,9 @@ static int virtnet_probe(struct virtio_device *vdev)
            || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN))
                vi->big_packets = true;
 
+       if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
+               vi->mergeable_rx_bufs = true;
+
        /* We expect two virtqueues, receive then send. */
        vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done);
        if (IS_ERR(vi->rvq)) {
@@ -639,6 +775,7 @@ static unsigned int features[] = {
        VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
        VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
        VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */
+       VIRTIO_NET_F_MRG_RXBUF,
        VIRTIO_F_NOTIFY_ON_EMPTY,
 };
 
index 7f97f8d08c39eeba79eaa4da5cdfc5368d59487d..d80b72e22dea6be26d69b4e2d0fd016541a546f8 100644 (file)
@@ -754,7 +754,6 @@ static int cosa_net_rx_done(struct channel_data *chan)
        chan->netdev->stats.rx_bytes += chan->cosa->rxsize;
        netif_rx(chan->rx_skb);
        chan->rx_skb = NULL;
-       chan->netdev->last_rx = jiffies;
        return 0;
 }
 
index 5a7303dc0965e7b5db3f8af3aa35202755602a51..aeea321e4a9d15208adc14e9b09a5a1f420fcaa8 100644 (file)
@@ -843,7 +843,6 @@ static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
 
        skb_reset_mac_header(skb);
        netif_rx(skb);
-       dev->last_rx = jiffies;         /* timestamp */
 }
 
 /* Connect interrupt handler. */
@@ -1494,7 +1493,6 @@ static void cycx_x25_chan_send_event(struct net_device *dev, u8 event)
 
        skb->protocol = x25_type_trans(skb, dev);
        netif_rx(skb);
-       dev->last_rx = jiffies;         /* timestamp */
 }
 
 /* Convert line speed in bps to a number used by cyclom 2x code. */
index b14242768fad19c381cff1d3d232d4abcf5f7e24..a297e3efa05dd32369d0c1c23c14378675c51436 100644 (file)
@@ -74,7 +74,7 @@ static int dlci_header(struct sk_buff *skb, struct net_device *dev,
        unsigned int            hlen;
        char                    *dest;
 
-       dlp = dev->priv;
+       dlp = netdev_priv(dev);
 
        hdr.control = FRAD_I_UI;
        switch(type)
@@ -110,7 +110,7 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
        struct frhdr            *hdr;
        int                                     process, header;
 
-       dlp = dev->priv;
+       dlp = netdev_priv(dev);
        if (!pskb_may_pull(skb, sizeof(*hdr))) {
                printk(KERN_NOTICE "%s: invalid data no header\n",
                       dev->name);
@@ -181,7 +181,6 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
                dlp->stats.rx_bytes += skb->len;
                netif_rx(skb);
                dlp->stats.rx_packets++;
-               dev->last_rx = jiffies;
        }
        else
                dev_kfree_skb(skb);
@@ -197,7 +196,7 @@ static int dlci_transmit(struct sk_buff *skb, struct net_device *dev)
        if (!skb || !dev)
                return(0);
 
-       dlp = dev->priv;
+       dlp = netdev_priv(dev);
 
        netif_stop_queue(dev);
        
@@ -235,9 +234,9 @@ static int dlci_config(struct net_device *dev, struct dlci_conf __user *conf, in
        struct frad_local       *flp;
        int                     err;
 
-       dlp = dev->priv;
+       dlp = netdev_priv(dev);
 
-       flp = dlp->slave->priv;
+       flp = netdev_priv(dlp->slave);
 
        if (!get)
        {
@@ -269,7 +268,7 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        if (!capable(CAP_NET_ADMIN))
                return(-EPERM);
 
-       dlp = dev->priv;
+       dlp = netdev_priv(dev);
 
        switch(cmd)
        {
@@ -298,7 +297,7 @@ static int dlci_change_mtu(struct net_device *dev, int new_mtu)
 {
        struct dlci_local *dlp;
 
-       dlp = dev->priv;
+       dlp = netdev_priv(dev);
 
        return((*dlp->slave->change_mtu)(dlp->slave, new_mtu));
 }
@@ -309,7 +308,7 @@ static int dlci_open(struct net_device *dev)
        struct frad_local       *flp;
        int                     err;
 
-       dlp = dev->priv;
+       dlp = netdev_priv(dev);
 
        if (!*(short *)(dev->dev_addr))
                return(-EINVAL);
@@ -317,7 +316,7 @@ static int dlci_open(struct net_device *dev)
        if (!netif_running(dlp->slave))
                return(-ENOTCONN);
 
-       flp = dlp->slave->priv;
+       flp = netdev_priv(dlp->slave);
        err = (*flp->activate)(dlp->slave, dev);
        if (err)
                return(err);
@@ -335,9 +334,9 @@ static int dlci_close(struct net_device *dev)
 
        netif_stop_queue(dev);
 
-       dlp = dev->priv;
+       dlp = netdev_priv(dev);
 
-       flp = dlp->slave->priv;
+       flp = netdev_priv(dlp->slave);
        err = (*flp->deactivate)(dlp->slave, dev);
 
        return 0;
@@ -347,7 +346,7 @@ static struct net_device_stats *dlci_get_stats(struct net_device *dev)
 {
        struct dlci_local *dlp;
 
-       dlp = dev->priv;
+       dlp = netdev_priv(dev);
 
        return(&dlp->stats);
 }
@@ -365,7 +364,7 @@ static int dlci_add(struct dlci_add *dlci)
        if (!slave)
                return -ENODEV;
 
-       if (slave->type != ARPHRD_FRAD || slave->priv == NULL)
+       if (slave->type != ARPHRD_FRAD || netdev_priv(slave) == NULL)
                goto err1;
 
        /* create device name */
@@ -391,11 +390,11 @@ static int dlci_add(struct dlci_add *dlci)
 
        *(short *)(master->dev_addr) = dlci->dlci;
 
-       dlp = (struct dlci_local *) master->priv;
+       dlp = netdev_priv(master);
        dlp->slave = slave;
        dlp->master = master;
 
-       flp = slave->priv;
+       flp = netdev_priv(slave);
        err = (*flp->assoc)(slave, master);
        if (err < 0)
                goto err2;
@@ -435,9 +434,9 @@ static int dlci_del(struct dlci_add *dlci)
                return(-EBUSY);
        }
 
-       dlp = master->priv;
+       dlp = netdev_priv(master);
        slave = dlp->slave;
-       flp = slave->priv;
+       flp = netdev_priv(slave);
 
        rtnl_lock();
        err = (*flp->deassoc)(slave, master);
@@ -491,7 +490,7 @@ static const struct header_ops dlci_header_ops = {
 
 static void dlci_setup(struct net_device *dev)
 {
-       struct dlci_local *dlp = dev->priv;
+       struct dlci_local *dlp = netdev_priv(dev);
 
        dev->flags              = 0;
        dev->open               = dlci_open;
index 5f1ccb2b08b11d1dbe0f4a7cab308b6ec92105ef..888025db2f022616d6c0bd4343835be5e5c6a989 100644 (file)
@@ -659,7 +659,6 @@ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv,
                skb_put(skb, pkt_len);
                if (netif_running(dev))
                        skb->protocol = hdlc_type_trans(skb, dev);
-               skb->dev->last_rx = jiffies;
                netif_rx(skb);
        } else {
                if (skb->data[pkt_len] & FrameRdo)
@@ -730,8 +729,7 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev,
                goto err_free_mmio_region_1;
        }
 
-       ioaddr = ioremap(pci_resource_start(pdev, 0),
-                                       pci_resource_len(pdev, 0));
+       ioaddr = pci_ioremap_bar(pdev, 0);
        if (!ioaddr) {
                printk(KERN_ERR "%s: cannot remap MMIO region %llx @ %llx\n",
                        DRV_NAME, (unsigned long long)pci_resource_len(pdev, 0),
index 9557ad078ab802e711496516d950f2d04cff3727..48a2c9d28950fc875a72334623343300bda21181 100644 (file)
@@ -896,7 +896,6 @@ fst_rx_dma_complete(struct fst_card_info *card, struct fst_port_info *port,
        fst_process_rx_status(rx_status, port_to_dev(port)->name);
        if (rx_status == NET_RX_DROP)
                dev->stats.rx_dropped++;
-       dev->last_rx = jiffies;
 }
 
 /*
@@ -1322,7 +1321,6 @@ fst_intr_rx(struct fst_card_info *card, struct fst_port_info *port)
                fst_process_rx_status(rx_status, port_to_dev(port)->name);
                if (rx_status == NET_RX_DROP)
                        dev->stats.rx_dropped++;
-               dev->last_rx = jiffies;
        } else {
                card->dma_skb_rx = skb;
                card->dma_port_rx = port;
index 591fb45a7c68d01748fa8a15c1581ae0debb5720..434583a94b32b5ed9c9c74e9d31ecf0144130808 100644 (file)
@@ -328,7 +328,6 @@ static inline void sca_rx(card_t *card, port_t *port, pkt_desc __iomem *desc, u1
 #endif
        dev->stats.rx_packets++;
        dev->stats.rx_bytes += skb->len;
-       dev->last_rx = jiffies;
        skb->protocol = hdlc_type_trans(skb, dev);
        netif_rx(skb);
 }
index e299313f828a74e20aee499e39739d1c79eef0fd..af54f0cf1b35fcc2d6f0130411df5432d5b55cc2 100644 (file)
@@ -66,7 +66,6 @@ static void hostess_input(struct z8530_channel *c, struct sk_buff *skb)
         *      it right now.
         */
        netif_rx(skb);
-       c->netdevice->last_rx = jiffies;
 }
 
 /*
index 24fd613466b7ea0925d5c98c5aada6a82a1fc6cc..5b61b3eef45f5b19da53e8e249b02895eaa6657a 100644 (file)
@@ -143,7 +143,6 @@ static int lapbeth_data_indication(struct net_device *dev, struct sk_buff *skb)
        *ptr = 0x00;
 
        skb->protocol = x25_type_trans(skb, dev);
-       skb->dev->last_rx = jiffies;
        return netif_rx(skb);
 }
 
@@ -235,7 +234,6 @@ static void lapbeth_connected(struct net_device *dev, int reason)
        *ptr = 0x01;
 
        skb->protocol = x25_type_trans(skb, dev);
-       skb->dev->last_rx = jiffies;
        netif_rx(skb);
 }
 
@@ -253,7 +251,6 @@ static void lapbeth_disconnected(struct net_device *dev, int reason)
        *ptr = 0x02;
 
        skb->protocol = x25_type_trans(skb, dev);
-       skb->dev->last_rx = jiffies;
        netif_rx(skb);
 }
 
index d7bb63e616b5e41f9ca72f2c52fa583dddcff113..feac3b99f8fe7f42192062fca6b63189b73ec62b 100644 (file)
@@ -1594,7 +1594,6 @@ static int lmc_rx(struct net_device *dev)
             goto skip_packet;
         }
         
-        dev->last_rx = jiffies;
        sc->lmc_device->stats.rx_packets++;
        sc->lmc_device->stats.rx_bytes += len;
 
index be9877ff551e23da4ca16ad1bc4ac24ae2537901..94b4c208b013e1a0a936ed25afc46785f90ab5a0 100644 (file)
@@ -142,7 +142,6 @@ void lmc_proto_netif(lmc_softc_t *sc, struct sk_buff *skb) /*FOLD00*/
     case LMC_PPP:
     case LMC_NET:
     default:
-        skb->dev->last_rx = jiffies;
         netif_rx(skb);
         break;
     case LMC_RAW:
index bf1b01590429d00ee45f3947c632726c4078b4de..2226711652239fa7a1322b33e08534ff156c6da3 100644 (file)
@@ -379,7 +379,7 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
        card->scabase = ioremap(scaphys, PC300_SCA_SIZE);
 
        ramphys = pci_resource_start(pdev,3) & PCI_BASE_ADDRESS_MEM_MASK;
-       card->rambase = ioremap(ramphys, pci_resource_len(pdev,3));
+       card->rambase = pci_ioremap_bar(pdev, 3);
 
        if (card->plxbase == NULL ||
            card->scabase == NULL ||
index b595b64e753809205151ae658d61ca2014f46d43..bba111cdeebeff8c43f04fc10cd960449a48f1cd 100644 (file)
@@ -343,7 +343,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
        card->scabase = ioremap(scaphys, PCI200SYN_SCA_SIZE);
 
        ramphys = pci_resource_start(pdev,3) & PCI_BASE_ADDRESS_MEM_MASK;
-       card->rambase = ioremap(ramphys, pci_resource_len(pdev,3));
+       card->rambase = pci_ioremap_bar(pdev, 3);
 
        if (card->plxbase == NULL ||
            card->scabase == NULL ||
index ee51b6a5e60569be9d955e2bb0259a5341d0f6f5..6db063e2d5bbfbd88233793156ef0de41f6b87ed 100644 (file)
@@ -1013,13 +1013,11 @@ indicate_pkt( struct net_device  *dev )
 #ifdef CONFIG_SBNI_MULTILINE
        skb->protocol = eth_type_trans( skb, nl->master );
        netif_rx( skb );
-       dev->last_rx = jiffies;
        ++((struct net_local *) nl->master->priv)->stats.rx_packets;
        ((struct net_local *) nl->master->priv)->stats.rx_bytes += nl->inppos;
 #else
        skb->protocol = eth_type_trans( skb, dev );
        netif_rx( skb );
-       dev->last_rx = jiffies;
        ++nl->stats.rx_packets;
        nl->stats.rx_bytes += nl->inppos;
 #endif
index 73e2f278093220e4bd3f8f5094c9ab55a1d190f5..6a07ba9371dbd5b0cd257eb87c1cf11cecd7bdcd 100644 (file)
@@ -185,7 +185,7 @@ static void sdla_stop(struct net_device *dev)
 {
        struct frad_local *flp;
 
-       flp = dev->priv;
+       flp = netdev_priv(dev);
        switch(flp->type)
        {
                case SDLA_S502A:
@@ -212,7 +212,7 @@ static void sdla_start(struct net_device *dev)
 {
        struct frad_local *flp;
 
-       flp = dev->priv;
+       flp = netdev_priv(dev);
        switch(flp->type)
        {
                case SDLA_S502A:
@@ -432,7 +432,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags,
        int                      ret, waiting, len;
        long                     window;
 
-       flp = dev->priv;
+       flp = netdev_priv(dev);
        window = flp->type == SDLA_S508 ? SDLA_508_CMD_BUF : SDLA_502_CMD_BUF;
        cmd_buf = (struct sdla_cmd *)(dev->mem_start + (window & SDLA_ADDR_MASK));
        ret = 0;
@@ -509,7 +509,7 @@ static int sdla_activate(struct net_device *slave, struct net_device *master)
        struct frad_local *flp;
        int i;
 
-       flp = slave->priv;
+       flp = netdev_priv(slave);
 
        for(i=0;i<CONFIG_DLCI_MAX;i++)
                if (flp->master[i] == master)
@@ -531,7 +531,7 @@ static int sdla_deactivate(struct net_device *slave, struct net_device *master)
        struct frad_local *flp;
        int               i;
 
-       flp = slave->priv;
+       flp = netdev_priv(slave);
 
        for(i=0;i<CONFIG_DLCI_MAX;i++)
                if (flp->master[i] == master)
@@ -556,7 +556,7 @@ static int sdla_assoc(struct net_device *slave, struct net_device *master)
        if (master->type != ARPHRD_DLCI)
                return(-EINVAL);
 
-       flp = slave->priv;
+       flp = netdev_priv(slave);
 
        for(i=0;i<CONFIG_DLCI_MAX;i++)
        {
@@ -589,7 +589,7 @@ static int sdla_deassoc(struct net_device *slave, struct net_device *master)
        struct frad_local *flp;
        int               i;
 
-       flp = slave->priv;
+       flp = netdev_priv(slave);
 
        for(i=0;i<CONFIG_DLCI_MAX;i++)
                if (flp->master[i] == master)
@@ -619,7 +619,7 @@ static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, i
        int               i;
        short             len, ret;
 
-       flp = slave->priv;
+       flp = netdev_priv(slave);
 
        for(i=0;i<CONFIG_DLCI_MAX;i++)
                if (flp->master[i] == master)
@@ -628,7 +628,7 @@ static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, i
        if (i == CONFIG_DLCI_MAX)
                return(-ENODEV);
 
-       dlp = master->priv;
+       dlp = netdev_priv(master);
 
        ret = SDLA_RET_OK;
        len = sizeof(struct dlci_conf);
@@ -659,7 +659,7 @@ static int sdla_transmit(struct sk_buff *skb, struct net_device *dev)
        unsigned long     flags;
        struct buf_entry  *pbuf;
 
-       flp = dev->priv;
+       flp = netdev_priv(dev);
        ret = 0;
        accept = 1;
 
@@ -755,7 +755,7 @@ static void sdla_receive(struct net_device *dev)
        int               i=0, received, success, addr, buf_base, buf_top;
        short             dlci, len, len2, split;
 
-       flp = dev->priv;
+       flp = netdev_priv(dev);
        success = 1;
        received = addr = buf_top = buf_base = 0;
        len = dlci = 0;
@@ -860,7 +860,7 @@ static void sdla_receive(struct net_device *dev)
        if (success)
        {
                flp->stats.rx_packets++;
-               dlp = master->priv;
+               dlp = netdev_priv(master);
                (*dlp->receive)(skb, master);
        }
 
@@ -925,7 +925,7 @@ static void sdla_poll(unsigned long device)
        struct frad_local *flp;
 
        dev = (struct net_device *) device;
-       flp = dev->priv;
+       flp = netdev_priv(dev);
 
        if (sdla_byte(dev, SDLA_502_RCV_BUF))
                sdla_receive(dev);
@@ -941,7 +941,7 @@ static int sdla_close(struct net_device *dev)
        int               len, i;
        short             dlcis[CONFIG_DLCI_MAX];
 
-       flp = dev->priv;
+       flp = netdev_priv(dev);
 
        len = 0;
        for(i=0;i<CONFIG_DLCI_MAX;i++)
@@ -1002,7 +1002,7 @@ static int sdla_open(struct net_device *dev)
        int               len, i;
        char              byte;
 
-       flp = dev->priv;
+       flp = netdev_priv(dev);
 
        if (!flp->initialized)
                return(-EPERM);
@@ -1079,7 +1079,7 @@ static int sdla_open(struct net_device *dev)
        for(i=0;i<CONFIG_DLCI_MAX;i++)
                if (flp->dlci[i])
                {
-                       dlp = flp->master[i]->priv;
+                       dlp = netdev_priv(flp->master[i]);
                        if (dlp->configured)
                                sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, &dlp->config, sizeof(struct dlci_conf), NULL, NULL);
                }
@@ -1099,7 +1099,7 @@ static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, in
        if (dev->type == 0xFFFF)
                return(-EUNATCH);
 
-       flp = dev->priv;
+       flp = netdev_priv(dev);
 
        if (!get)
        {
@@ -1230,7 +1230,7 @@ static int sdla_reconfig(struct net_device *dev)
        struct conf_data  data;
        int               i, len;
 
-       flp = dev->priv;
+       flp = netdev_priv(dev);
 
        len = 0;
        for(i=0;i<CONFIG_DLCI_MAX;i++)
@@ -1255,7 +1255,7 @@ static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        if(!capable(CAP_NET_ADMIN))
                return -EPERM;
                
-       flp = dev->priv;
+       flp = netdev_priv(dev);
 
        if (!flp->initialized)
                return(-EINVAL);
@@ -1321,7 +1321,7 @@ static int sdla_change_mtu(struct net_device *dev, int new_mtu)
 {
        struct frad_local *flp;
 
-       flp = dev->priv;
+       flp = netdev_priv(dev);
 
        if (netif_running(dev))
                return(-EBUSY);
@@ -1338,7 +1338,7 @@ static int sdla_set_config(struct net_device *dev, struct ifmap *map)
        unsigned base;
        int err = -EINVAL;
 
-       flp = dev->priv;
+       flp = netdev_priv(dev);
 
        if (flp->initialized)
                return(-EINVAL);
@@ -1593,14 +1593,14 @@ fail:
 static struct net_device_stats *sdla_stats(struct net_device *dev)
 {
        struct frad_local *flp;
-       flp = dev->priv;
+       flp = netdev_priv(dev);
 
        return(&flp->stats);
 }
 
 static void setup_sdla(struct net_device *dev)
 {
-       struct frad_local *flp = dev->priv;
+       struct frad_local *flp = netdev_priv(dev);
 
        netdev_boot_setup_check(dev);
 
@@ -1651,7 +1651,7 @@ static int __init init_sdla(void)
 
 static void __exit exit_sdla(void)
 {
-       struct frad_local *flp = sdla->priv;
+       struct frad_local *flp = netdev_priv(sdla);
 
        unregister_netdev(sdla);
        if (flp->initialized) {
index c0235844a4d594e5cee2b243d4105b54c0f47eb9..0941a26f6e3f9b94d794bc2f43ecce49a35290cb 100644 (file)
@@ -68,7 +68,6 @@ static void sealevel_input(struct z8530_channel *c, struct sk_buff *skb)
        skb_reset_mac_header(skb);
        skb->dev = c->netdevice;
        netif_rx(skb);
-       c->netdevice->last_rx = jiffies;
 }
 
 /*
index 6e92f7b44b1aa6d315d84898ce6a990b96ed3a0a..58ae8a2223afb250e3f3866925ca7e15cbfba0d5 100644 (file)
@@ -284,7 +284,6 @@ static void sppp_input (struct net_device *dev, struct sk_buff *skb)
                                        printk(KERN_DEBUG "Yow an IP frame.\n");
                                skb->protocol=htons(ETH_P_IP);
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                                goto done;
                        }
                        break;
@@ -294,7 +293,6 @@ static void sppp_input (struct net_device *dev, struct sk_buff *skb)
                        if (sp->lcp.state == LCP_STATE_OPENED) {
                                skb->protocol=htons(ETH_P_IPX);
                                netif_rx(skb);
-                               dev->last_rx = jiffies;
                                goto done;
                        }
                        break;
@@ -321,14 +319,12 @@ static void sppp_input (struct net_device *dev, struct sk_buff *skb)
                case ETH_P_IP:
                        skb->protocol=htons(ETH_P_IP);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        goto done;
 #endif
 #ifdef CONFIG_IPX
                case ETH_P_IPX:
                        skb->protocol=htons(ETH_P_IPX);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        goto done;
 #endif
                }
index a8a5ca0ee6c2dc8d59f16ee5e29a48d2b5db4dce..88459490ecd2e3bcfeb5f0b48060ca17127d482c 100644 (file)
@@ -220,7 +220,6 @@ static inline void wanxl_rx_intr(card_t *card)
 #endif
                                dev->stats.rx_packets++;
                                dev->stats.rx_bytes += skb->len;
-                               dev->last_rx = jiffies;
                                skb->protocol = hdlc_type_trans(skb, dev);
                                netif_rx(skb);
                                skb = NULL;
index 2a6c7a60756f38a8c5ad00064562c4059de1089c..85d789147300eab1b16f57d7f3325e8c4df30204 100644 (file)
@@ -64,7 +64,7 @@ static struct x25_asy *x25_asy_alloc(void)
                if (dev == NULL)
                        break;
 
-               sl = dev->priv;
+               sl = netdev_priv(dev);
                /* Not in use ? */
                if (!test_and_set_bit(SLF_INUSE, &sl->flags))
                        return sl;
@@ -86,7 +86,7 @@ static struct x25_asy *x25_asy_alloc(void)
                        return NULL;
 
                /* Initialize channel control data */
-               sl = dev->priv;
+               sl = netdev_priv(dev);
                dev->base_addr    = i;
 
                /* register device so that it can be ifconfig'ed       */
@@ -120,7 +120,7 @@ static void x25_asy_free(struct x25_asy *sl)
 
 static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
 {
-       struct x25_asy *sl = dev->priv;
+       struct x25_asy *sl = netdev_priv(dev);
        unsigned char *xbuff, *rbuff;
        int len = 2 * newmtu;
 
@@ -211,7 +211,6 @@ static void x25_asy_bump(struct x25_asy *sl)
                printk(KERN_DEBUG "x25_asy: data received err - %d\n", err);
        } else {
                netif_rx(skb);
-               sl->dev->last_rx = jiffies;
                sl->stats.rx_packets++;
        }
 }
@@ -280,7 +279,7 @@ static void x25_asy_write_wakeup(struct tty_struct *tty)
 
 static void x25_asy_timeout(struct net_device *dev)
 {
-       struct x25_asy *sl = dev->priv;
+       struct x25_asy *sl = netdev_priv(dev);
 
        spin_lock(&sl->lock);
        if (netif_queue_stopped(dev)) {
@@ -301,7 +300,7 @@ static void x25_asy_timeout(struct net_device *dev)
 
 static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct x25_asy *sl = dev->priv;
+       struct x25_asy *sl = netdev_priv(dev);
        int err;
 
        if (!netif_running(sl->dev)) {
@@ -361,7 +360,6 @@ static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb)
 {
-       skb->dev->last_rx = jiffies;
        return netif_rx(skb);
 }
 
@@ -373,7 +371,7 @@ static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb)
 
 static void x25_asy_data_transmit(struct net_device *dev, struct sk_buff *skb)
 {
-       struct x25_asy *sl = dev->priv;
+       struct x25_asy *sl = netdev_priv(dev);
 
        spin_lock(&sl->lock);
        if (netif_queue_stopped(sl->dev) || sl->tty == NULL) {
@@ -398,7 +396,7 @@ static void x25_asy_data_transmit(struct net_device *dev, struct sk_buff *skb)
 
 static void x25_asy_connected(struct net_device *dev, int reason)
 {
-       struct x25_asy *sl = dev->priv;
+       struct x25_asy *sl = netdev_priv(dev);
        struct sk_buff *skb;
        unsigned char *ptr;
 
@@ -413,12 +411,11 @@ static void x25_asy_connected(struct net_device *dev, int reason)
 
        skb->protocol = x25_type_trans(skb, sl->dev);
        netif_rx(skb);
-       sl->dev->last_rx = jiffies;
 }
 
 static void x25_asy_disconnected(struct net_device *dev, int reason)
 {
-       struct x25_asy *sl = dev->priv;
+       struct x25_asy *sl = netdev_priv(dev);
        struct sk_buff *skb;
        unsigned char *ptr;
 
@@ -433,7 +430,6 @@ static void x25_asy_disconnected(struct net_device *dev, int reason)
 
        skb->protocol = x25_type_trans(skb, sl->dev);
        netif_rx(skb);
-       sl->dev->last_rx = jiffies;
 }
 
 static struct lapb_register_struct x25_asy_callbacks = {
@@ -450,7 +446,7 @@ static struct lapb_register_struct x25_asy_callbacks = {
 /* Open the low-level part of the X.25 channel. Easy! */
 static int x25_asy_open(struct net_device *dev)
 {
-       struct x25_asy *sl = dev->priv;
+       struct x25_asy *sl = netdev_priv(dev);
        unsigned long len;
        int err;
 
@@ -499,7 +495,7 @@ norbuff:
 /* Close the low-level part of the X.25 channel. Easy! */
 static int x25_asy_close(struct net_device *dev)
 {
-       struct x25_asy *sl = dev->priv;
+       struct x25_asy *sl = netdev_priv(dev);
        int err;
 
        spin_lock(&sl->lock);
@@ -615,7 +611,7 @@ static void x25_asy_close_tty(struct tty_struct *tty)
 
 static struct net_device_stats *x25_asy_get_stats(struct net_device *dev)
 {
-       struct x25_asy *sl = dev->priv;
+       struct x25_asy *sl = netdev_priv(dev);
        return &sl->stats;
 }
 
@@ -717,7 +713,7 @@ static int x25_asy_ioctl(struct tty_struct *tty, struct file *file,
 
 static int x25_asy_open_dev(struct net_device *dev)
 {
-       struct x25_asy *sl = dev->priv;
+       struct x25_asy *sl = netdev_priv(dev);
        if (sl->tty == NULL)
                return -ENODEV;
        return 0;
@@ -726,7 +722,7 @@ static int x25_asy_open_dev(struct net_device *dev)
 /* Initialise the X.25 driver.  Called by the device init code */
 static void x25_asy_setup(struct net_device *dev)
 {
-       struct x25_asy *sl = dev->priv;
+       struct x25_asy *sl = netdev_priv(dev);
 
        sl->magic  = X25_ASY_MAGIC;
        sl->dev    = dev;
@@ -793,7 +789,7 @@ static void __exit exit_x25_asy(void)
        for (i = 0; i < x25_asy_maxdev; i++) {
                dev = x25_asy_devs[i];
                if (dev) {
-                       struct x25_asy *sl = dev->priv;
+                       struct x25_asy *sl = netdev_priv(dev);
 
                        spin_lock_bh(&sl->lock);
                        if (sl->tty)
index fa14255282afe96770d5b44cc887fbaba22814df..6d96ed472119a3f2f51206d039f6aa60eb9db39c 100644 (file)
@@ -156,7 +156,6 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
        int word16 = 0;                         /* 0 = 8 bit, 1 = 16 bit */
        const char *model_name;
        static unsigned version_printed;
-       DECLARE_MAC_BUF(mac);
 
        for (i = 0; i < 8; i++)
                checksum += inb(ioaddr + 8 + i);
@@ -178,8 +177,8 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = inb(ioaddr + 8 + i);
 
-       printk("%s: WD80x3 at %#3x, %s",
-              dev->name, ioaddr, print_mac(mac, dev->dev_addr));
+       printk("%s: WD80x3 at %#3x, %pM",
+              dev->name, ioaddr, dev->dev_addr);
 
        /* The following PureData probe code was contributed by
           Mike Jagdis <jaggy@purplet.demon.co.uk>. Puredata does software
index 45bdf0b339bb55f0aa132b2256385014079a8731..42afaedbb21931a94b414245d8d705b8b617ec02 100644 (file)
@@ -271,6 +271,7 @@ config LIBERTAS
        tristate "Marvell 8xxx Libertas WLAN driver support"
        depends on WLAN_80211
        select WIRELESS_EXT
+       select LIB80211
        select FW_LOADER
        ---help---
          A library for Marvell Libertas 8xxx devices.
index 59d2d805f60b4591b1332944b51ac7cf380b5006..78820840fe21285b54d5d9ca5ed03e8168b0071a 100644 (file)
@@ -16,14 +16,7 @@ obj-$(CONFIG_WAVELAN)                += wavelan.o
 obj-$(CONFIG_PCMCIA_NETWAVE)   += netwave_cs.o
 obj-$(CONFIG_PCMCIA_WAVELAN)   += wavelan_cs.o
 
-obj-$(CONFIG_HERMES)           += orinoco.o hermes.o hermes_dld.o
-obj-$(CONFIG_PCMCIA_HERMES)    += orinoco_cs.o
-obj-$(CONFIG_APPLE_AIRPORT)    += airport.o
-obj-$(CONFIG_PLX_HERMES)       += orinoco_plx.o
-obj-$(CONFIG_PCI_HERMES)       += orinoco_pci.o
-obj-$(CONFIG_TMD_HERMES)       += orinoco_tmd.o
-obj-$(CONFIG_NORTEL_HERMES)    += orinoco_nortel.o
-obj-$(CONFIG_PCMCIA_SPECTRUM)  += spectrum_cs.o
+obj-$(CONFIG_HERMES)           += orinoco/
 
 obj-$(CONFIG_AIRO)             += airo.o
 obj-$(CONFIG_AIRO_CS)          += airo_cs.o airo.o
index b2c050b68890a2f0d496a85d39314c95282d07e9..fc0897fb22390c87d908ceefdc0a4ea05193e383 100644 (file)
@@ -341,15 +341,14 @@ static void adm8211_interrupt_tci(struct ieee80211_hw *dev)
                pci_unmap_single(priv->pdev, info->mapping,
                                 info->skb->len, PCI_DMA_TODEVICE);
 
-               memset(&txi->status, 0, sizeof(txi->status));
+               ieee80211_tx_info_clear_status(txi);
+
                skb_pull(skb, sizeof(struct adm8211_tx_hdr));
                memcpy(skb_push(skb, info->hdrlen), skb->cb, info->hdrlen);
-               if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK)) {
-                       if (status & TDES0_STATUS_ES)
-                               txi->status.excessive_retries = 1;
-                       else
-                               txi->flags |= IEEE80211_TX_STAT_ACK;
-               }
+               if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) &&
+                   !(status & TDES0_STATUS_ES))
+                       txi->flags |= IEEE80211_TX_STAT_ACK;
+
                ieee80211_tx_status_irqsafe(dev, skb);
 
                info->skb = NULL;
@@ -1298,25 +1297,10 @@ static void adm8211_set_bssid(struct ieee80211_hw *dev, const u8 *bssid)
        ADM8211_CSR_WRITE(ABDA1, reg);
 }
 
-static int adm8211_set_ssid(struct ieee80211_hw *dev, u8 *ssid, size_t ssid_len)
-{
-       struct adm8211_priv *priv = dev->priv;
-       u8 buf[36];
-
-       if (ssid_len > 32)
-               return -EINVAL;
-
-       memset(buf, 0, sizeof(buf));
-       buf[0] = ssid_len;
-       memcpy(buf + 1, ssid, ssid_len);
-       adm8211_write_sram_bytes(dev, ADM8211_SRAM_SSID, buf, 33);
-       /* TODO: configure beacon for adhoc? */
-       return 0;
-}
-
-static int adm8211_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
+static int adm8211_config(struct ieee80211_hw *dev, u32 changed)
 {
        struct adm8211_priv *priv = dev->priv;
+       struct ieee80211_conf *conf = &dev->conf;
        int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
 
        if (channel != priv->channel) {
@@ -1338,13 +1322,6 @@ static int adm8211_config_interface(struct ieee80211_hw *dev,
                memcpy(priv->bssid, conf->bssid, ETH_ALEN);
        }
 
-       if (conf->ssid_len != priv->ssid_len ||
-           memcmp(conf->ssid, priv->ssid, conf->ssid_len)) {
-               adm8211_set_ssid(dev, conf->ssid, conf->ssid_len);
-               priv->ssid_len = conf->ssid_len;
-               memcpy(priv->ssid, conf->ssid, conf->ssid_len);
-       }
-
        return 0;
 }
 
@@ -1690,8 +1667,10 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        struct ieee80211_hdr *hdr;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ieee80211_rate *txrate = ieee80211_get_tx_rate(dev, info);
+       u8 rc_flags;
 
-       short_preamble = !!(txrate->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE);
+       rc_flags = info->control.rates[0].flags;
+       short_preamble = !!(rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
        plcp_signal = txrate->bitrate;
 
        hdr = (struct ieee80211_hdr *)skb->data;
@@ -1723,10 +1702,10 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        if (short_preamble)
                txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_SHORT_PREAMBLE);
 
-       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
+       if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS)
                txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS);
 
-       txhdr->retry_limit = info->control.retry_limit;
+       txhdr->retry_limit = info->control.rates[0].count;
 
        adm8211_tx_raw(dev, skb, plcp_signal, hdrlen);
 
@@ -1791,7 +1770,6 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
        int err;
        u32 reg;
        u8 perm_addr[ETH_ALEN];
-       DECLARE_MAC_BUF(mac);
 
        err = pci_enable_device(pdev);
        if (err) {
@@ -1925,8 +1903,8 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
                goto err_free_desc;
        }
 
-       printk(KERN_INFO "%s: hwaddr %s, Rev 0x%02x\n",
-              wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
+       printk(KERN_INFO "%s: hwaddr %pM, Rev 0x%02x\n",
+              wiphy_name(dev->wiphy), dev->wiphy->perm_addr,
               pdev->revision);
 
        return 0;
index 9b190ee26e903c291fa54aaa0c51e5153ace4d67..4f6ab1322189805660e99b0e5b3bc3acf2fba9d8 100644 (file)
@@ -553,8 +553,6 @@ struct adm8211_priv {
 
        int channel;
        u8 bssid[ETH_ALEN];
-       u8 ssid[32];
-       size_t ssid_len;
 
        u8 soft_rx_crc;
        u8 retry_limit;
index 370133e492d259431df941fc3eee94bb770fa117..67d504e32290da0519ed527f8d31ae5b2f07e133 100644 (file)
 #include <linux/ioport.h>
 #include <linux/pci.h>
 #include <asm/uaccess.h>
-#include <net/ieee80211.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 
+#include <linux/ieee80211.h>
+
 #include "airo.h"
 
 #define DRV_NAME "airo"
@@ -1270,6 +1271,7 @@ static int flashrestart(struct airo_info *ai,struct net_device *dev);
 #define airo_print_err(name, fmt, args...) \
        airo_print(KERN_ERR, name, fmt, ##args)
 
+#define AIRO_FLASH(dev) (((struct airo_info *)dev->ml_priv)->flash)
 
 /***********************************************************************
  *                              MIC ROUTINES                           *
@@ -1865,7 +1867,7 @@ static void try_auto_wep(struct airo_info *ai)
 }
 
 static int airo_open(struct net_device *dev) {
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        int rc = 0;
 
        if (test_bit(FLAG_FLASHING, &ai->flags))
@@ -1912,7 +1914,7 @@ static int airo_open(struct net_device *dev) {
 static int mpi_start_xmit(struct sk_buff *skb, struct net_device *dev) {
        int npacks, pending;
        unsigned long flags;
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
 
        if (!skb) {
                airo_print_err(dev->name, "%s: skb == NULL!",__func__);
@@ -1956,7 +1958,7 @@ static int mpi_send_packet (struct net_device *dev)
        unsigned char *buffer;
        s16 len;
        __le16 *payloadLen;
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        u8 *sendbuf;
 
        /* get a packet to send */
@@ -2085,7 +2087,7 @@ static void get_tx_error(struct airo_info *ai, s32 fid)
 static void airo_end_xmit(struct net_device *dev) {
        u16 status;
        int i;
-       struct airo_info *priv = dev->priv;
+       struct airo_info *priv = dev->ml_priv;
        struct sk_buff *skb = priv->xmit.skb;
        int fid = priv->xmit.fid;
        u32 *fids = priv->fids;
@@ -2111,7 +2113,7 @@ static void airo_end_xmit(struct net_device *dev) {
 static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
        s16 len;
        int i, j;
-       struct airo_info *priv = dev->priv;
+       struct airo_info *priv = dev->ml_priv;
        u32 *fids = priv->fids;
 
        if ( skb == NULL ) {
@@ -2150,7 +2152,7 @@ static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
 static void airo_end_xmit11(struct net_device *dev) {
        u16 status;
        int i;
-       struct airo_info *priv = dev->priv;
+       struct airo_info *priv = dev->ml_priv;
        struct sk_buff *skb = priv->xmit11.skb;
        int fid = priv->xmit11.fid;
        u32 *fids = priv->fids;
@@ -2176,7 +2178,7 @@ static void airo_end_xmit11(struct net_device *dev) {
 static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
        s16 len;
        int i, j;
-       struct airo_info *priv = dev->priv;
+       struct airo_info *priv = dev->ml_priv;
        u32 *fids = priv->fids;
 
        if (test_bit(FLAG_MPI, &priv->flags)) {
@@ -2220,7 +2222,7 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
 
 static void airo_read_stats(struct net_device *dev)
 {
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        StatsRid stats_rid;
        __le32 *vals = stats_rid.vals;
 
@@ -2254,7 +2256,7 @@ static void airo_read_stats(struct net_device *dev)
 
 static struct net_device_stats *airo_get_stats(struct net_device *dev)
 {
-       struct airo_info *local =  dev->priv;
+       struct airo_info *local =  dev->ml_priv;
 
        if (!test_bit(JOB_STATS, &local->jobs)) {
                /* Get stats out of the card if available */
@@ -2281,7 +2283,7 @@ static void airo_set_promisc(struct airo_info *ai) {
 }
 
 static void airo_set_multicast_list(struct net_device *dev) {
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
 
        if ((dev->flags ^ ai->flags) & IFF_PROMISC) {
                change_bit(FLAG_PROMISC, &ai->flags);
@@ -2299,7 +2301,7 @@ static void airo_set_multicast_list(struct net_device *dev) {
 
 static int airo_set_mac_address(struct net_device *dev, void *p)
 {
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        struct sockaddr *addr = p;
 
        readConfigRid(ai, 1);
@@ -2339,7 +2341,7 @@ static void del_airo_dev(struct airo_info *ai)
 }
 
 static int airo_close(struct net_device *dev) {
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
 
        netif_stop_queue(dev);
 
@@ -2365,7 +2367,7 @@ static int airo_close(struct net_device *dev) {
 
 void stop_airo_card( struct net_device *dev, int freeres )
 {
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
 
        set_bit(FLAG_RADIO_DOWN, &ai->flags);
        disable_MAC(ai, 1);
@@ -2665,7 +2667,7 @@ static struct net_device *init_wifidev(struct airo_info *ai,
        struct net_device *dev = alloc_netdev(0, "wifi%d", wifi_setup);
        if (!dev)
                return NULL;
-       dev->priv = ethdev->priv;
+       dev->ml_priv = ethdev->ml_priv;
        dev->irq = ethdev->irq;
        dev->base_addr = ethdev->base_addr;
        dev->wireless_data = ethdev->wireless_data;
@@ -2680,7 +2682,7 @@ static struct net_device *init_wifidev(struct airo_info *ai,
 }
 
 static int reset_card( struct net_device *dev , int lock) {
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
 
        if (lock && down_interruptible(&ai->sem))
                return -1;
@@ -2757,7 +2759,6 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
        struct net_device *dev;
        struct airo_info *ai;
        int i, rc;
-       DECLARE_MAC_BUF(mac);
 
        /* Create the network device object. */
        dev = alloc_netdev(sizeof(*ai), "", ether_setup);
@@ -2766,7 +2767,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
                return NULL;
        }
 
-       ai = dev->priv;
+       ai = dev->ml_priv = netdev_priv(dev);
        ai->wifidev = NULL;
        ai->flags = 1 << FLAG_RADIO_DOWN;
        ai->jobs = 0;
@@ -2860,15 +2861,14 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
                goto err_out_reg;
 
        set_bit(FLAG_REGISTERED,&ai->flags);
-       airo_print_info(dev->name, "MAC enabled %s",
-                       print_mac(mac, dev->dev_addr));
+       airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
 
        /* Allocate the transmit buffers */
        if (probe && !test_bit(FLAG_MPI,&ai->flags))
                for( i = 0; i < MAX_FIDS; i++ )
                        ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
 
-       if (setup_proc_entry(dev, dev->priv) < 0)
+       if (setup_proc_entry(dev, dev->ml_priv) < 0)
                goto err_out_wifi;
 
        return dev;
@@ -2917,8 +2917,7 @@ static int waitbusy (struct airo_info *ai) {
 int reset_airo_card( struct net_device *dev )
 {
        int i;
-       struct airo_info *ai = dev->priv;
-       DECLARE_MAC_BUF(mac);
+       struct airo_info *ai = dev->ml_priv;
 
        if (reset_card (dev, 1))
                return -1;
@@ -2927,8 +2926,7 @@ int reset_airo_card( struct net_device *dev )
                airo_print_err(dev->name, "MAC could not be enabled");
                return -1;
        }
-       airo_print_info(dev->name, "MAC enabled %s",
-                       print_mac(mac, dev->dev_addr));
+       airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
        /* Allocate the transmit buffers if needed */
        if (!test_bit(FLAG_MPI,&ai->flags))
                for( i = 0; i < MAX_FIDS; i++ )
@@ -2942,7 +2940,7 @@ int reset_airo_card( struct net_device *dev )
 EXPORT_SYMBOL(reset_airo_card);
 
 static void airo_send_event(struct net_device *dev) {
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        union iwreq_data wrqu;
        StatusRid status_rid;
 
@@ -3019,7 +3017,7 @@ out:
 
 static int airo_thread(void *data) {
        struct net_device *dev = data;
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        int locked;
 
        set_freezable();
@@ -3134,7 +3132,7 @@ static irqreturn_t airo_interrupt(int irq, void *dev_id)
        struct net_device *dev = dev_id;
        u16 status;
        u16 fid;
-       struct airo_info *apriv = dev->priv;
+       struct airo_info *apriv = dev->ml_priv;
        u16 savedInterrupts = 0;
        int handled = 0;
 
@@ -3369,7 +3367,6 @@ badrx:
                                skb->protocol = htons(ETH_P_802_2);
                        } else
                                skb->protocol = eth_type_trans(skb,dev);
-                       skb->dev->last_rx = jiffies;
                        skb->ip_summed = CHECKSUM_NONE;
 
                        netif_rx( skb );
@@ -3599,7 +3596,6 @@ badmic:
 
                skb->ip_summed = CHECKSUM_NONE;
                skb->protocol = eth_type_trans(skb, ai->dev);
-               skb->dev->last_rx = jiffies;
                netif_rx(skb);
        }
 badrx:
@@ -3693,7 +3689,6 @@ void mpi_receive_802_11 (struct airo_info *ai)
        skb->pkt_type = PACKET_OTHERHOST;
        skb->dev = ai->wifidev;
        skb->protocol = htons(ETH_P_802_2);
-       skb->dev->last_rx = jiffies;
        skb->ip_summed = CHECKSUM_NONE;
        netif_rx( skb );
 badrx:
@@ -4604,7 +4599,7 @@ static int proc_status_open(struct inode *inode, struct file *file)
        struct proc_data *data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
-       struct airo_info *apriv = dev->priv;
+       struct airo_info *apriv = dev->ml_priv;
        CapabilityRid cap_rid;
        StatusRid status_rid;
        u16 mode;
@@ -4687,7 +4682,7 @@ static int proc_stats_rid_open( struct inode *inode,
        struct proc_data *data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
-       struct airo_info *apriv = dev->priv;
+       struct airo_info *apriv = dev->ml_priv;
        StatsRid stats;
        int i, j;
        __le32 *vals = stats.vals;
@@ -4750,7 +4745,7 @@ static void proc_config_on_close(struct inode *inode, struct file *file)
        struct proc_data *data = file->private_data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        char *line;
 
        if ( !data->writelen ) return;
@@ -4962,7 +4957,7 @@ static int proc_config_open(struct inode *inode, struct file *file)
        struct proc_data *data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        int i;
        __le16 mode;
 
@@ -5053,7 +5048,7 @@ static void proc_SSID_on_close(struct inode *inode, struct file *file)
        struct proc_data *data = (struct proc_data *)file->private_data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        SsidRid SSID_rid;
        int i;
        char *p = data->wbuffer;
@@ -5096,7 +5091,7 @@ static void proc_APList_on_close( struct inode *inode, struct file *file ) {
        struct proc_data *data = (struct proc_data *)file->private_data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        APListRid APList_rid;
        int i;
 
@@ -5191,7 +5186,7 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
        struct proc_data *data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        int i;
        char key[16];
        u16 index = 0;
@@ -5233,7 +5228,7 @@ static int proc_wepkey_open( struct inode *inode, struct file *file )
        struct proc_data *data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        char *ptr;
        WepKeyRid wkr;
        __le16 lastindex;
@@ -5282,7 +5277,7 @@ static int proc_SSID_open(struct inode *inode, struct file *file)
        struct proc_data *data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        int i;
        char *ptr;
        SsidRid SSID_rid;
@@ -5326,11 +5321,10 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
        struct proc_data *data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        int i;
        char *ptr;
        APListRid APList_rid;
-       DECLARE_MAC_BUF(mac);
 
        if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
                return -ENOMEM;
@@ -5354,8 +5348,7 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
 // We end when we find a zero MAC
                if ( !*(int*)APList_rid.ap[i] &&
                     !*(int*)&APList_rid.ap[i][2]) break;
-               ptr += sprintf(ptr, "%s\n",
-                              print_mac(mac, APList_rid.ap[i]));
+               ptr += sprintf(ptr, "%pM\n", APList_rid.ap[i]);
        }
        if (i==0) ptr += sprintf(ptr, "Not using specific APs\n");
 
@@ -5368,13 +5361,12 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
        struct proc_data *data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        char *ptr;
        BSSListRid BSSList_rid;
        int rc;
        /* If doLoseSync is not 1, we won't do a Lose Sync */
        int doLoseSync = -1;
-       DECLARE_MAC_BUF(mac);
 
        if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
                return -ENOMEM;
@@ -5411,8 +5403,8 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
            we have to add a spin lock... */
        rc = readBSSListRid(ai, doLoseSync, &BSSList_rid);
        while(rc == 0 && BSSList_rid.index != cpu_to_le16(0xffff)) {
-               ptr += sprintf(ptr, "%s %*s rssi = %d",
-                              print_mac(mac, BSSList_rid.bssid),
+               ptr += sprintf(ptr, "%pM %*s rssi = %d",
+                              BSSList_rid.bssid,
                                (int)BSSList_rid.ssidLen,
                                BSSList_rid.ssid,
                                le16_to_cpu(BSSList_rid.dBm));
@@ -5447,7 +5439,7 @@ static int proc_close( struct inode *inode, struct file *file )
    associated we will check every minute to see if anything has
    changed. */
 static void timer_func( struct net_device *dev ) {
-       struct airo_info *apriv = dev->priv;
+       struct airo_info *apriv = dev->ml_priv;
 
 /* We don't have a link so try changing the authtype */
        readConfigRid(apriv, 0);
@@ -5518,7 +5510,7 @@ static void __devexit airo_pci_remove(struct pci_dev *pdev)
 static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        Cmd cmd;
        Resp rsp;
 
@@ -5550,7 +5542,7 @@ static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 static int airo_pci_resume(struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        pci_power_t prev_state = pdev->current_state;
 
        pci_set_power_state(pdev, PCI_D0);
@@ -5729,7 +5721,7 @@ static int airo_set_freq(struct net_device *dev,
                         struct iw_freq *fwrq,
                         char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        int rc = -EINPROGRESS;          /* Call commit handler */
 
        /* If setting by frequency, convert to a channel */
@@ -5774,7 +5766,7 @@ static int airo_get_freq(struct net_device *dev,
                         struct iw_freq *fwrq,
                         char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        StatusRid status_rid;           /* Card status info */
        int ch;
 
@@ -5805,7 +5797,7 @@ static int airo_set_essid(struct net_device *dev,
                          struct iw_point *dwrq,
                          char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        SsidRid SSID_rid;               /* SSIDs */
 
        /* Reload the list of current SSID */
@@ -5851,7 +5843,7 @@ static int airo_get_essid(struct net_device *dev,
                          struct iw_point *dwrq,
                          char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        StatusRid status_rid;           /* Card status info */
 
        readStatusRid(local, &status_rid, 1);
@@ -5879,7 +5871,7 @@ static int airo_set_wap(struct net_device *dev,
                        struct sockaddr *awrq,
                        char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        Cmd cmd;
        Resp rsp;
        APListRid APList_rid;
@@ -5916,7 +5908,7 @@ static int airo_get_wap(struct net_device *dev,
                        struct sockaddr *awrq,
                        char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        StatusRid status_rid;           /* Card status info */
 
        readStatusRid(local, &status_rid, 1);
@@ -5937,7 +5929,7 @@ static int airo_set_nick(struct net_device *dev,
                         struct iw_point *dwrq,
                         char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
 
        /* Check the size of the string */
        if(dwrq->length > 16) {
@@ -5960,7 +5952,7 @@ static int airo_get_nick(struct net_device *dev,
                         struct iw_point *dwrq,
                         char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
 
        readConfigRid(local, 1);
        strncpy(extra, local->config.nodeName, 16);
@@ -5979,7 +5971,7 @@ static int airo_set_rate(struct net_device *dev,
                         struct iw_param *vwrq,
                         char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        CapabilityRid cap_rid;          /* Card capability info */
        u8      brate = 0;
        int     i;
@@ -6049,7 +6041,7 @@ static int airo_get_rate(struct net_device *dev,
                         struct iw_param *vwrq,
                         char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        StatusRid status_rid;           /* Card status info */
 
        readStatusRid(local, &status_rid, 1);
@@ -6071,7 +6063,7 @@ static int airo_set_rts(struct net_device *dev,
                        struct iw_param *vwrq,
                        char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        int rthr = vwrq->value;
 
        if(vwrq->disabled)
@@ -6095,7 +6087,7 @@ static int airo_get_rts(struct net_device *dev,
                        struct iw_param *vwrq,
                        char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
 
        readConfigRid(local, 1);
        vwrq->value = le16_to_cpu(local->config.rtsThres);
@@ -6114,7 +6106,7 @@ static int airo_set_frag(struct net_device *dev,
                         struct iw_param *vwrq,
                         char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        int fthr = vwrq->value;
 
        if(vwrq->disabled)
@@ -6139,7 +6131,7 @@ static int airo_get_frag(struct net_device *dev,
                         struct iw_param *vwrq,
                         char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
 
        readConfigRid(local, 1);
        vwrq->value = le16_to_cpu(local->config.fragThresh);
@@ -6158,7 +6150,7 @@ static int airo_set_mode(struct net_device *dev,
                         __u32 *uwrq,
                         char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        int reset = 0;
 
        readConfigRid(local, 1);
@@ -6221,7 +6213,7 @@ static int airo_get_mode(struct net_device *dev,
                         __u32 *uwrq,
                         char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
 
        readConfigRid(local, 1);
        /* If not managed, assume it's ad-hoc */
@@ -6258,7 +6250,7 @@ static int airo_set_encode(struct net_device *dev,
                           struct iw_point *dwrq,
                           char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        CapabilityRid cap_rid;          /* Card capability info */
        int perm = ( dwrq->flags & IW_ENCODE_TEMP ? 0 : 1 );
        __le16 currentAuthType = local->config.authType;
@@ -6345,7 +6337,7 @@ static int airo_get_encode(struct net_device *dev,
                           struct iw_point *dwrq,
                           char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
        CapabilityRid cap_rid;          /* Card capability info */
 
@@ -6393,7 +6385,7 @@ static int airo_set_encodeext(struct net_device *dev,
                            union iwreq_data *wrqu,
                            char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        struct iw_point *encoding = &wrqu->encoding;
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
        CapabilityRid cap_rid;          /* Card capability info */
@@ -6479,7 +6471,7 @@ static int airo_get_encodeext(struct net_device *dev,
                            union iwreq_data *wrqu,
                            char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        struct iw_point *encoding = &wrqu->encoding;
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
        CapabilityRid cap_rid;          /* Card capability info */
@@ -6542,7 +6534,7 @@ static int airo_set_auth(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        struct iw_param *param = &wrqu->param;
        __le16 currentAuthType = local->config.authType;
 
@@ -6610,7 +6602,7 @@ static int airo_get_auth(struct net_device *dev,
                               struct iw_request_info *info,
                               union iwreq_data *wrqu, char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        struct iw_param *param = &wrqu->param;
        __le16 currentAuthType = local->config.authType;
 
@@ -6659,7 +6651,7 @@ static int airo_set_txpow(struct net_device *dev,
                          struct iw_param *vwrq,
                          char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        CapabilityRid cap_rid;          /* Card capability info */
        int i;
        int rc = -EINVAL;
@@ -6696,7 +6688,7 @@ static int airo_get_txpow(struct net_device *dev,
                          struct iw_param *vwrq,
                          char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
 
        readConfigRid(local, 1);
        vwrq->value = le16_to_cpu(local->config.txPower);
@@ -6716,7 +6708,7 @@ static int airo_set_retry(struct net_device *dev,
                          struct iw_param *vwrq,
                          char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        int rc = -EINVAL;
 
        if(vwrq->disabled) {
@@ -6754,7 +6746,7 @@ static int airo_get_retry(struct net_device *dev,
                          struct iw_param *vwrq,
                          char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
 
        vwrq->disabled = 0;      /* Can't be disabled */
 
@@ -6785,7 +6777,7 @@ static int airo_get_range(struct net_device *dev,
                          struct iw_point *dwrq,
                          char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        struct iw_range *range = (struct iw_range *) extra;
        CapabilityRid cap_rid;          /* Card capability info */
        int             i;
@@ -6910,7 +6902,7 @@ static int airo_set_power(struct net_device *dev,
                          struct iw_param *vwrq,
                          char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
 
        readConfigRid(local, 1);
        if (vwrq->disabled) {
@@ -6967,7 +6959,7 @@ static int airo_get_power(struct net_device *dev,
                          struct iw_param *vwrq,
                          char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        __le16 mode;
 
        readConfigRid(local, 1);
@@ -6998,7 +6990,7 @@ static int airo_set_sens(struct net_device *dev,
                         struct iw_param *vwrq,
                         char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
 
        readConfigRid(local, 1);
        local->config.rssiThreshold =
@@ -7017,7 +7009,7 @@ static int airo_get_sens(struct net_device *dev,
                         struct iw_param *vwrq,
                         char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
 
        readConfigRid(local, 1);
        vwrq->value = le16_to_cpu(local->config.rssiThreshold);
@@ -7037,7 +7029,7 @@ static int airo_get_aplist(struct net_device *dev,
                           struct iw_point *dwrq,
                           char *extra)
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
        struct sockaddr *address = (struct sockaddr *) extra;
        struct iw_quality qual[IW_MAX_AP];
        BSSListRid BSSList;
@@ -7110,7 +7102,7 @@ static int airo_set_scan(struct net_device *dev,
                         struct iw_point *dwrq,
                         char *extra)
 {
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        Cmd cmd;
        Resp rsp;
        int wake = 0;
@@ -7156,7 +7148,7 @@ static inline char *airo_translate_scan(struct net_device *dev,
                                        char *end_buf,
                                        BSSListRid *bss)
 {
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        struct iw_event         iwe;            /* Temporary buffer */
        __le16                  capabilities;
        char *                  current_val;    /* For rates */
@@ -7274,56 +7266,53 @@ static inline char *airo_translate_scan(struct net_device *dev,
        if (test_bit(FLAG_WPA_CAPABLE, &ai->flags)) {
                unsigned int num_null_ies = 0;
                u16 length = sizeof (bss->extra.iep);
-               struct ieee80211_info_element *info_element =
-                       (struct ieee80211_info_element *) &bss->extra.iep;
+               u8 *ie = (void *)&bss->extra.iep;
 
-               while ((length >= sizeof(*info_element)) && (num_null_ies < 2)) {
-                       if (sizeof(*info_element) + info_element->len > length) {
+               while ((length >= 2) && (num_null_ies < 2)) {
+                       if (2 + ie[1] > length) {
                                /* Invalid element, don't continue parsing IE */
                                break;
                        }
 
-                       switch (info_element->id) {
-                       case MFIE_TYPE_SSID:
+                       switch (ie[0]) {
+                       case WLAN_EID_SSID:
                                /* Two zero-length SSID elements
                                 * mean we're done parsing elements */
-                               if (!info_element->len)
+                               if (!ie[1])
                                        num_null_ies++;
                                break;
 
-                       case MFIE_TYPE_GENERIC:
-                               if (info_element->len >= 4 &&
-                                   info_element->data[0] == 0x00 &&
-                                   info_element->data[1] == 0x50 &&
-                                   info_element->data[2] == 0xf2 &&
-                                   info_element->data[3] == 0x01) {
+                       case WLAN_EID_GENERIC:
+                               if (ie[1] >= 4 &&
+                                   ie[2] == 0x00 &&
+                                   ie[3] == 0x50 &&
+                                   ie[4] == 0xf2 &&
+                                   ie[5] == 0x01) {
                                        iwe.cmd = IWEVGENIE;
-                                       iwe.u.data.length = min(info_element->len + 2,
-                                                                 MAX_WPA_IE_LEN);
+                                       /* 64 is an arbitrary cut-off */
+                                       iwe.u.data.length = min(ie[1] + 2,
+                                                               64);
                                        current_ev = iwe_stream_add_point(
                                                        info, current_ev,
-                                                       end_buf, &iwe,
-                                                       (char *) info_element);
+                                                       end_buf, &iwe, ie);
                                }
                                break;
 
-                       case MFIE_TYPE_RSN:
+                       case WLAN_EID_RSN:
                                iwe.cmd = IWEVGENIE;
-                               iwe.u.data.length = min(info_element->len + 2,
-                                                         MAX_WPA_IE_LEN);
+                               /* 64 is an arbitrary cut-off */
+                               iwe.u.data.length = min(ie[1] + 2, 64);
                                current_ev = iwe_stream_add_point(
                                        info, current_ev, end_buf,
-                                       &iwe, (char *) info_element);
+                                       &iwe, ie);
                                break;
 
                        default:
                                break;
                        }
 
-                       length -= sizeof(*info_element) + info_element->len;
-                       info_element =
-                           (struct ieee80211_info_element *)&info_element->
-                           data[info_element->len];
+                       length -= 2 + ie[1];
+                       ie += 2 + ie[1];
                }
        }
        return current_ev;
@@ -7338,7 +7327,7 @@ static int airo_get_scan(struct net_device *dev,
                         struct iw_point *dwrq,
                         char *extra)
 {
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        BSSListElement *net;
        int err = 0;
        char *current_ev = extra;
@@ -7382,7 +7371,7 @@ static int airo_config_commit(struct net_device *dev,
                              void *zwrq,                       /* NULL */
                              char *extra)                      /* NULL */
 {
-       struct airo_info *local = dev->priv;
+       struct airo_info *local = dev->ml_priv;
 
        if (!test_bit (FLAG_COMMIT, &local->flags))
                return 0;
@@ -7527,7 +7516,7 @@ static const struct iw_handler_def        airo_handler_def =
 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        int rc = 0;
-       struct airo_info *ai = (struct airo_info *)dev->priv;
+       struct airo_info *ai = dev->ml_priv;
 
        if (ai->power.event)
                return 0;
@@ -7655,7 +7644,7 @@ static void airo_read_wireless_stats(struct airo_info *local)
 
 static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
 {
-       struct airo_info *local =  dev->priv;
+       struct airo_info *local =  dev->ml_priv;
 
        if (!test_bit(JOB_WSTATS, &local->jobs)) {
                /* Get stats out of the card if available */
@@ -7680,7 +7669,7 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) {
        unsigned short ridcode;
        unsigned char *iobuf;
        int len;
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
 
        if (test_bit(FLAG_FLASHING, &ai->flags))
                return -EIO;
@@ -7746,7 +7735,7 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) {
  */
 
 static int writerids(struct net_device *dev, aironet_ioctl *comp) {
-       struct airo_info *ai = dev->priv;
+       struct airo_info *ai = dev->ml_priv;
        int  ridcode;
         int  enabled;
        static int (* writer)(struct airo_info *, u16 rid, const void *, int, int);
@@ -7869,41 +7858,41 @@ static int flashcard(struct net_device *dev, aironet_ioctl *comp) {
        switch(comp->command)
        {
        case AIROFLSHRST:
-               return cmdreset((struct airo_info *)dev->priv);
+               return cmdreset((struct airo_info *)dev->ml_priv);
 
        case AIROFLSHSTFL:
-               if (!((struct airo_info *)dev->priv)->flash &&
-                       (((struct airo_info *)dev->priv)->flash = kmalloc (FLASHSIZE, GFP_KERNEL)) == NULL)
+               if (!AIRO_FLASH(dev) &&
+                   (AIRO_FLASH(dev) = kmalloc(FLASHSIZE, GFP_KERNEL)) == NULL)
                        return -ENOMEM;
-               return setflashmode((struct airo_info *)dev->priv);
+               return setflashmode((struct airo_info *)dev->ml_priv);
 
        case AIROFLSHGCHR: /* Get char from aux */
                if(comp->len != sizeof(int))
                        return -EINVAL;
                if (copy_from_user(&z,comp->data,comp->len))
                        return -EFAULT;
-               return flashgchar((struct airo_info *)dev->priv,z,8000);
+               return flashgchar((struct airo_info *)dev->ml_priv, z, 8000);
 
        case AIROFLSHPCHR: /* Send char to card. */
                if(comp->len != sizeof(int))
                        return -EINVAL;
                if (copy_from_user(&z,comp->data,comp->len))
                        return -EFAULT;
-               return flashpchar((struct airo_info *)dev->priv,z,8000);
+               return flashpchar((struct airo_info *)dev->ml_priv, z, 8000);
 
        case AIROFLPUTBUF: /* Send 32k to card */
-               if (!((struct airo_info *)dev->priv)->flash)
+               if (!AIRO_FLASH(dev))
                        return -ENOMEM;
                if(comp->len > FLASHSIZE)
                        return -EINVAL;
-               if(copy_from_user(((struct airo_info *)dev->priv)->flash,comp->data,comp->len))
+               if (copy_from_user(AIRO_FLASH(dev), comp->data, comp->len))
                        return -EFAULT;
 
-               flashputbuf((struct airo_info *)dev->priv);
+               flashputbuf((struct airo_info *)dev->ml_priv);
                return 0;
 
        case AIRORESTART:
-               if(flashrestart((struct airo_info *)dev->priv,dev))
+               if (flashrestart((struct airo_info *)dev->ml_priv, dev))
                        return -EIO;
                return 0;
        }
diff --git a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c
deleted file mode 100644 (file)
index ce03a2e..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/* airport.c
- *
- * A driver for "Hermes" chipset based Apple Airport wireless
- * card.
- *
- * Copyright notice & release notes in file orinoco.c
- * 
- * Note specific to airport stub:
- * 
- *  0.05 : first version of the new split driver
- *  0.06 : fix possible hang on powerup, add sleep support
- */
-
-#define DRIVER_NAME "airport"
-#define PFX DRIVER_NAME ": "
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <asm/pmac_feature.h>
-
-#include "orinoco.h"
-
-#define AIRPORT_IO_LEN (0x1000)        /* one page */
-
-struct airport {
-       struct macio_dev *mdev;
-       void __iomem *vaddr;
-       int irq_requested;
-       int ndev_registered;
-};
-
-static int
-airport_suspend(struct macio_dev *mdev, pm_message_t state)
-{
-       struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
-       struct orinoco_private *priv = netdev_priv(dev);
-       unsigned long flags;
-       int err;
-
-       printk(KERN_DEBUG "%s: Airport entering sleep mode\n", dev->name);
-
-       err = orinoco_lock(priv, &flags);
-       if (err) {
-               printk(KERN_ERR "%s: hw_unavailable on PBOOK_SLEEP_NOW\n",
-                      dev->name);
-               return 0;
-       }
-
-       err = __orinoco_down(dev);
-       if (err)
-               printk(KERN_WARNING "%s: PBOOK_SLEEP_NOW: Error %d downing interface\n",
-                      dev->name, err);
-
-       netif_device_detach(dev);
-
-       priv->hw_unavailable++;
-
-       orinoco_unlock(priv, &flags);
-
-       disable_irq(dev->irq);
-       pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 0);
-
-       return 0;
-}
-
-static int
-airport_resume(struct macio_dev *mdev)
-{
-       struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
-       struct orinoco_private *priv = netdev_priv(dev);
-       unsigned long flags;
-       int err;
-
-       printk(KERN_DEBUG "%s: Airport waking up\n", dev->name);
-
-       pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1);
-       msleep(200);
-
-       enable_irq(dev->irq);
-
-       err = orinoco_reinit_firmware(dev);
-       if (err) {
-               printk(KERN_ERR "%s: Error %d re-initializing firmware on PBOOK_WAKE\n",
-                      dev->name, err);
-               return 0;
-       }
-
-       spin_lock_irqsave(&priv->lock, flags);
-
-       netif_device_attach(dev);
-
-       priv->hw_unavailable--;
-
-       if (priv->open && (! priv->hw_unavailable)) {
-               err = __orinoco_up(dev);
-               if (err)
-                       printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n",
-                              dev->name, err);
-       }
-
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       return 0;
-}
-
-static int
-airport_detach(struct macio_dev *mdev)
-{
-       struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct airport *card = priv->card;
-
-       if (card->ndev_registered)
-               unregister_netdev(dev);
-       card->ndev_registered = 0;
-
-       if (card->irq_requested)
-               free_irq(dev->irq, dev);
-       card->irq_requested = 0;
-
-       if (card->vaddr)
-               iounmap(card->vaddr);
-       card->vaddr = NULL;
-
-       macio_release_resource(mdev, 0);
-
-       pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 0);
-       ssleep(1);
-
-       macio_set_drvdata(mdev, NULL);
-       free_orinocodev(dev);
-
-       return 0;
-}
-
-static int airport_hard_reset(struct orinoco_private *priv)
-{
-       /* It would be nice to power cycle the Airport for a real hard
-        * reset, but for some reason although it appears to
-        * re-initialize properly, it falls in a screaming heap
-        * shortly afterwards. */
-#if 0
-       struct net_device *dev = priv->ndev;
-       struct airport *card = priv->card;
-
-       /* Vitally important.  If we don't do this it seems we get an
-        * interrupt somewhere during the power cycle, since
-        * hw_unavailable is already set it doesn't get ACKed, we get
-        * into an interrupt loop and the PMU decides to turn us
-        * off. */
-       disable_irq(dev->irq);
-
-       pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(card->mdev), 0, 0);
-       ssleep(1);
-       pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(card->mdev), 0, 1);
-       ssleep(1);
-
-       enable_irq(dev->irq);
-       ssleep(1);
-#endif
-
-       return 0;
-}
-
-static int
-airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
-{
-       struct orinoco_private *priv;
-       struct net_device *dev;
-       struct airport *card;
-       unsigned long phys_addr;
-       hermes_t *hw;
-
-       if (macio_resource_count(mdev) < 1 || macio_irq_count(mdev) < 1) {
-               printk(KERN_ERR PFX "Wrong interrupt/addresses in OF tree\n");
-               return -ENODEV;
-       }
-
-       /* Allocate space for private device-specific data */
-       dev = alloc_orinocodev(sizeof(*card), &mdev->ofdev.dev,
-                              airport_hard_reset, NULL);
-       if (! dev) {
-               printk(KERN_ERR PFX "Cannot allocate network device\n");
-               return -ENODEV;
-       }
-       priv = netdev_priv(dev);
-       card = priv->card;
-
-       hw = &priv->hw;
-       card->mdev = mdev;
-
-       if (macio_request_resource(mdev, 0, "airport")) {
-               printk(KERN_ERR PFX "can't request IO resource !\n");
-               free_orinocodev(dev);
-               return -EBUSY;
-       }
-
-       SET_NETDEV_DEV(dev, &mdev->ofdev.dev);
-
-       macio_set_drvdata(mdev, dev);
-
-       /* Setup interrupts & base address */
-       dev->irq = macio_irq(mdev, 0);
-       phys_addr = macio_resource_start(mdev, 0);  /* Physical address */
-       printk(KERN_DEBUG PFX "Physical address %lx\n", phys_addr);
-       dev->base_addr = phys_addr;
-       card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
-       if (!card->vaddr) {
-               printk(KERN_ERR PFX "ioremap() failed\n");
-               goto failed;
-       }
-
-       hermes_struct_init(hw, card->vaddr, HERMES_16BIT_REGSPACING);
-               
-       /* Power up card */
-       pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1);
-       ssleep(1);
-
-       /* Reset it before we get the interrupt */
-       hermes_init(hw);
-
-       if (request_irq(dev->irq, orinoco_interrupt, 0, dev->name, dev)) {
-               printk(KERN_ERR PFX "Couldn't get IRQ %d\n", dev->irq);
-               goto failed;
-       }
-       card->irq_requested = 1;
-
-       /* Tell the stack we exist */
-       if (register_netdev(dev) != 0) {
-               printk(KERN_ERR PFX "register_netdev() failed\n");
-               goto failed;
-       }
-       printk(KERN_DEBUG PFX "Card registered for interface %s\n", dev->name);
-       card->ndev_registered = 1;
-       return 0;
- failed:
-       airport_detach(mdev);
-       return -ENODEV;
-}                              /* airport_attach */
-
-
-static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
-       " (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
-MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
-MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
-MODULE_LICENSE("Dual MPL/GPL");
-
-static struct of_device_id airport_match[] = 
-{
-       {
-       .name           = "radio",
-       },
-       {},
-};
-
-MODULE_DEVICE_TABLE (of, airport_match);
-
-static struct macio_driver airport_driver = 
-{
-       .name           = DRIVER_NAME,
-       .match_table    = airport_match,
-       .probe          = airport_attach,
-       .remove         = airport_detach,
-       .suspend        = airport_suspend,
-       .resume         = airport_resume,
-};
-
-static int __init
-init_airport(void)
-{
-       printk(KERN_DEBUG "%s\n", version);
-
-       return macio_register_driver(&airport_driver);
-}
-
-static void __exit
-exit_airport(void)
-{
-       return macio_unregister_driver(&airport_driver);
-}
-
-module_init(init_airport);
-module_exit(exit_airport);
index dec5e874a54db0aef692c1a4c6966631ad144121..bfca15da6f0f844fa379bcb7c7eade8914139e3c 100644 (file)
@@ -1467,19 +1467,17 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short
                                                else if (hw_dst_addr[1] == 0x40)
                                                        printk(KERN_ERR "%s m/bcast 0x0140 \n", dev->name);
                                        while (dmi)
-                                       {                                                       if (dmi->dmi_addrlen == 6)
-                                               {
-                                                       DECLARE_MAC_BUF(mac);
+                                       {
+                                               if (dmi->dmi_addrlen == 6) {
                                                        if (arlan_debug & ARLAN_DEBUG_HEADER_DUMP)
-                                                               printk(KERN_ERR "%s mcl %s\n",
-                                                                      dev->name, print_mac(mac, dmi->dmi_addr));
+                                                               printk(KERN_ERR "%s mcl %pM\n",
+                                                                      dev->name, dmi->dmi_addr);
                                                        for (i = 0; i < 6; i++)
                                                                if (dmi->dmi_addr[i] != hw_dst_addr[i])
                                                                        break;
                                                        if (i == 6)
                                                                break;
-                                               }
-                                               else
+                                               } else
                                                        printk(KERN_ERR "%s: invalid multicast address length given.\n", dev->name);
                                                dmi = dmi->next;
                                        }
@@ -1512,18 +1510,14 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short
                        {
                                char immedDestAddress[6];
                                char immedSrcAddress[6];
-                               DECLARE_MAC_BUF(mac);
-                               DECLARE_MAC_BUF(mac2);
-                               DECLARE_MAC_BUF(mac3);
-                               DECLARE_MAC_BUF(mac4);
                                memcpy_fromio(immedDestAddress, arlan->immedDestAddress, 6);
                                memcpy_fromio(immedSrcAddress, arlan->immedSrcAddress, 6);
 
-                               printk(KERN_WARNING "%s t %s f %s imd %s ims %s\n",
-                                      dev->name, print_mac(mac, skbtmp),
-                                      print_mac(mac2, &skbtmp[6]),
-                                      print_mac(mac3, immedDestAddress),
-                                      print_mac(mac4, immedSrcAddress));
+                               printk(KERN_WARNING "%s t %pM f %pM imd %pM ims %pM\n",
+                                      dev->name, skbtmp,
+                                      &skbtmp[6],
+                                      immedDestAddress,
+                                      immedSrcAddress);
                        }
                        skb->protocol = eth_type_trans(skb, dev);
                        IFDEBUG(ARLAN_DEBUG_HEADER_DUMP)
@@ -1535,7 +1529,6 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short
                                        printk(KERN_WARNING "arlan kernel pkt type trans %x \n", skb->protocol);
                                }
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                        dev->stats.rx_bytes += pkt_len;
                }
index 53ea439aff48a3e22f7f2fa7b63c376fa38c8af3..a725bb94a52d51f4118a58d58f01445e06370b59 100644 (file)
@@ -507,11 +507,15 @@ enum ath5k_tx_queue_id {
 #define AR5K_TXQ_FLAG_TXEOLINT_ENABLE          0x0004  /* Enable TXEOL interrupt -not used- */
 #define AR5K_TXQ_FLAG_TXDESCINT_ENABLE         0x0008  /* Enable TXDESC interrupt -not used- */
 #define AR5K_TXQ_FLAG_TXURNINT_ENABLE          0x0010  /* Enable TXURN interrupt */
-#define AR5K_TXQ_FLAG_BACKOFF_DISABLE          0x0020  /* Disable random post-backoff */
-#define AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE        0x0040  /* Enable ready time expiry policy (?)*/
-#define AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE        0x0080  /* Enable backoff while bursting */
-#define AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS                0x0100  /* Disable backoff while bursting */
-#define AR5K_TXQ_FLAG_COMPRESSION_ENABLE       0x0200  /* Enable hw compression -not implemented-*/
+#define AR5K_TXQ_FLAG_CBRORNINT_ENABLE         0x0020  /* Enable CBRORN interrupt */
+#define AR5K_TXQ_FLAG_CBRURNINT_ENABLE         0x0040  /* Enable CBRURN interrupt */
+#define AR5K_TXQ_FLAG_QTRIGINT_ENABLE          0x0080  /* Enable QTRIG interrupt */
+#define AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE                0x0100  /* Enable TXNOFRM interrupt */
+#define AR5K_TXQ_FLAG_BACKOFF_DISABLE          0x0200  /* Disable random post-backoff */
+#define AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE        0x0300  /* Enable ready time expiry policy (?)*/
+#define AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE        0x0800  /* Enable backoff while bursting */
+#define AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS                0x1000  /* Disable backoff while bursting */
+#define AR5K_TXQ_FLAG_COMPRESSION_ENABLE       0x2000  /* Enable hw compression -not implemented-*/
 
 /*
  * A struct to hold tx queue's parameters
@@ -853,7 +857,7 @@ enum ath5k_ant_setting {
  *     checked. We should do this with ath5k_hw_update_mib_counters() but
  *     it seems we should also then do some noise immunity work.
  * @AR5K_INT_RXPHY: RX PHY Error
- * @AR5K_INT_RXKCM: ??
+ * @AR5K_INT_RXKCM: RX Key cache miss
  * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a
  *     beacon that must be handled in software. The alternative is if you
  *     have VEOL support, in that case you let the hardware deal with things.
@@ -869,7 +873,7 @@ enum ath5k_ant_setting {
  * @AR5K_INT_FATAL: Fatal errors were encountered, typically caused by DMA
  *     errors. These types of errors we can enable seem to be of type
  *     AR5K_SIMR2_MCABT, AR5K_SIMR2_SSERR and AR5K_SIMR2_DPERR.
- * @AR5K_INT_GLOBAL: Seems to be used to clear and set the IER
+ * @AR5K_INT_GLOBAL: Used to clear and set the IER
  * @AR5K_INT_NOCARD: signals the card has been removed
  * @AR5K_INT_COMMON: common interrupts shared amogst MACs with the same
  *     bit value
@@ -881,36 +885,61 @@ enum ath5k_ant_setting {
  * MACs.
  */
 enum ath5k_int {
-       AR5K_INT_RX     = 0x00000001, /* Not common */
+       AR5K_INT_RXOK   = 0x00000001,
        AR5K_INT_RXDESC = 0x00000002,
+       AR5K_INT_RXERR  = 0x00000004,
        AR5K_INT_RXNOFRM = 0x00000008,
        AR5K_INT_RXEOL  = 0x00000010,
        AR5K_INT_RXORN  = 0x00000020,
-       AR5K_INT_TX     = 0x00000040, /* Not common */
+       AR5K_INT_TXOK   = 0x00000040,
        AR5K_INT_TXDESC = 0x00000080,
+       AR5K_INT_TXERR  = 0x00000100,
+       AR5K_INT_TXNOFRM = 0x00000200,
+       AR5K_INT_TXEOL  = 0x00000400,
        AR5K_INT_TXURN  = 0x00000800,
        AR5K_INT_MIB    = 0x00001000,
+       AR5K_INT_SWI    = 0x00002000,
        AR5K_INT_RXPHY  = 0x00004000,
        AR5K_INT_RXKCM  = 0x00008000,
        AR5K_INT_SWBA   = 0x00010000,
+       AR5K_INT_BRSSI  = 0x00020000,
        AR5K_INT_BMISS  = 0x00040000,
-       AR5K_INT_BNR    = 0x00100000, /* Not common */
-       AR5K_INT_GPIO   = 0x01000000,
-       AR5K_INT_FATAL  = 0x40000000, /* Not common */
-       AR5K_INT_GLOBAL = 0x80000000,
-
-       AR5K_INT_COMMON  = AR5K_INT_RXNOFRM
-                       | AR5K_INT_RXDESC
-                       | AR5K_INT_RXEOL
-                       | AR5K_INT_RXORN
-                       | AR5K_INT_TXURN
-                       | AR5K_INT_TXDESC
-                       | AR5K_INT_MIB
-                       | AR5K_INT_RXPHY
-                       | AR5K_INT_RXKCM
-                       | AR5K_INT_SWBA
-                       | AR5K_INT_BMISS
-                       | AR5K_INT_GPIO,
+       AR5K_INT_FATAL  = 0x00080000, /* Non common */
+       AR5K_INT_BNR    = 0x00100000, /* Non common */
+       AR5K_INT_TIM    = 0x00200000, /* Non common */
+       AR5K_INT_DTIM   = 0x00400000, /* Non common */
+       AR5K_INT_DTIM_SYNC =    0x00800000, /* Non common */
+       AR5K_INT_GPIO   =       0x01000000,
+       AR5K_INT_BCN_TIMEOUT =  0x02000000, /* Non common */
+       AR5K_INT_CAB_TIMEOUT =  0x04000000, /* Non common */
+       AR5K_INT_RX_DOPPLER =   0x08000000, /* Non common */
+       AR5K_INT_QCBRORN =      0x10000000, /* Non common */
+       AR5K_INT_QCBRURN =      0x20000000, /* Non common */
+       AR5K_INT_QTRIG  =       0x40000000, /* Non common */
+       AR5K_INT_GLOBAL =       0x80000000,
+
+       AR5K_INT_COMMON  = AR5K_INT_RXOK
+               | AR5K_INT_RXDESC
+               | AR5K_INT_RXERR
+               | AR5K_INT_RXNOFRM
+               | AR5K_INT_RXEOL
+               | AR5K_INT_RXORN
+               | AR5K_INT_TXOK
+               | AR5K_INT_TXDESC
+               | AR5K_INT_TXERR
+               | AR5K_INT_TXNOFRM
+               | AR5K_INT_TXEOL
+               | AR5K_INT_TXURN
+               | AR5K_INT_MIB
+               | AR5K_INT_SWI
+               | AR5K_INT_RXPHY
+               | AR5K_INT_RXKCM
+               | AR5K_INT_SWBA
+               | AR5K_INT_BRSSI
+               | AR5K_INT_BMISS
+               | AR5K_INT_GPIO
+               | AR5K_INT_GLOBAL,
+
        AR5K_INT_NOCARD = 0xffffffff
 };
 
@@ -1064,10 +1093,11 @@ struct ath5k_hw {
 
        u8                      ah_sta_id[ETH_ALEN];
 
-       /* Current BSSID we are trying to assoc to / creating.
+       /* Current BSSID we are trying to assoc to / create.
         * This is passed by mac80211 on config_interface() and cached here for
         * use in resets */
        u8                      ah_bssid[ETH_ALEN];
+       u8                      ah_bssid_mask[ETH_ALEN];
 
        u32                     ah_gpio[AR5K_MAX_GPIO];
        int                     ah_gpio_npins;
@@ -1081,6 +1111,11 @@ struct ath5k_hw {
        u32                     ah_txq_imr_txurn;
        u32                     ah_txq_imr_txdesc;
        u32                     ah_txq_imr_txeol;
+       u32                     ah_txq_imr_cbrorn;
+       u32                     ah_txq_imr_cbrurn;
+       u32                     ah_txq_imr_qtrig;
+       u32                     ah_txq_imr_nofrm;
+       u32                     ah_txq_isr;
        u32                     *ah_rf_banks;
        size_t                  ah_rf_banks_size;
        struct ath5k_gain       ah_gain;
index cfd4d052d666ea8cbda45b37c541cb2592dad3a0..c7ffcbb9062deb1ab80976866477e7abad69f1b1 100644 (file)
@@ -60,6 +60,9 @@
 #include "debug.h"
 
 static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
+static int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
 
 
 /******************\
@@ -219,8 +222,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
                struct ieee80211_if_init_conf *conf);
 static void ath5k_remove_interface(struct ieee80211_hw *hw,
                struct ieee80211_if_init_conf *conf);
-static int ath5k_config(struct ieee80211_hw *hw,
-               struct ieee80211_conf *conf);
+static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
 static int ath5k_config_interface(struct ieee80211_hw *hw,
                struct ieee80211_vif *vif,
                struct ieee80211_if_conf *conf);
@@ -238,8 +240,7 @@ static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
                struct ieee80211_tx_queue_stats *stats);
 static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
 static void ath5k_reset_tsf(struct ieee80211_hw *hw);
-static int ath5k_beacon_update(struct ieee80211_hw *hw,
-               struct sk_buff *skb);
+static int ath5k_beacon_update(struct ath5k_softc *sc, struct sk_buff *skb);
 
 static struct ieee80211_ops ath5k_hw_ops = {
        .tx             = ath5k_tx,
@@ -543,8 +544,8 @@ ath5k_pci_probe(struct pci_dev *pdev,
 
        /* set up multi-rate retry capabilities */
        if (sc->ah->ah_version == AR5K_AR5212) {
-               hw->max_altrates = 3;
-               hw->max_altrate_tries = 11;
+               hw->max_rates = 4;
+               hw->max_rate_tries = 11;
        }
 
        /* Finish private driver data initialization */
@@ -1183,7 +1184,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
                ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
                (sc->power_level * 2),
                ieee80211_get_tx_rate(sc->hw, info)->hw_value,
-               info->control.retry_limit, keyidx, 0, flags, 0, 0);
+               info->control.rates[0].count, keyidx, 0, flags, 0, 0);
        if (ret)
                goto err_unmap;
 
@@ -1195,7 +1196,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
                        break;
 
                mrr_rate[i] = rate->hw_value;
-               mrr_tries[i] = info->control.retries[i].limit;
+               mrr_tries[i] = info->control.rates[i + 1].count;
        }
 
        ah->ah_setup_mrr_tx_desc(ah, ds,
@@ -1780,7 +1781,17 @@ accept:
 
                rxs.noise = sc->ah->ah_noise_floor;
                rxs.signal = rxs.noise + rs.rs_rssi;
-               rxs.qual = rs.rs_rssi * 100 / 64;
+
+               /* An rssi of 35 indicates you should be able use
+                * 54 Mbps reliably. A more elaborate scheme can be used
+                * here but it requires a map of SNR/throughput for each
+                * possible mode used */
+               rxs.qual = rs.rs_rssi * 100 / 35;
+
+               /* rssi can be more than 35 though, anything above that
+                * should be considered at 100% */
+               if (rxs.qual > 100)
+                       rxs.qual = 100;
 
                rxs.antenna = rs.rs_antenna;
                rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
@@ -1841,30 +1852,26 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
                pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
                                PCI_DMA_TODEVICE);
 
-               memset(&info->status, 0, sizeof(info->status));
-               info->tx_rate_idx = ath5k_hw_to_driver_rix(sc,
-                               ts.ts_rate[ts.ts_final_idx]);
-               info->status.retry_count = ts.ts_longretry;
-
+               ieee80211_tx_info_clear_status(info);
                for (i = 0; i < 4; i++) {
-                       struct ieee80211_tx_altrate *r =
-                               &info->status.retries[i];
+                       struct ieee80211_tx_rate *r =
+                               &info->status.rates[i];
 
                        if (ts.ts_rate[i]) {
-                               r->rate_idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]);
-                               r->limit = ts.ts_retry[i];
+                               r->idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]);
+                               r->count = ts.ts_retry[i];
                        } else {
-                               r->rate_idx = -1;
-                               r->limit = 0;
+                               r->idx = -1;
+                               r->count = 0;
                        }
                }
 
-               info->status.excessive_retries = 0;
+               /* count the successful attempt as well */
+               info->status.rates[ts.ts_final_idx].count++;
+
                if (unlikely(ts.ts_status)) {
                        sc->ll_stats.dot11ACKFailureCount++;
-                       if (ts.ts_status & AR5K_TXERR_XRETRY)
-                               info->status.excessive_retries = 1;
-                       else if (ts.ts_status & AR5K_TXERR_FILT)
+                       if (ts.ts_status & AR5K_TXERR_FILT)
                                info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
                } else {
                        info->flags |= IEEE80211_TX_STAT_ACK;
@@ -2138,8 +2145,6 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
  *
  * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
  * interrupts to detect TSF updates only.
- *
- * AP mode is missing.
  */
 static void
 ath5k_beacon_config(struct ath5k_softc *sc)
@@ -2152,7 +2157,9 @@ ath5k_beacon_config(struct ath5k_softc *sc)
 
        if (sc->opmode == NL80211_IFTYPE_STATION) {
                sc->imask |= AR5K_INT_BMISS;
-       } else if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+       } else if (sc->opmode == NL80211_IFTYPE_ADHOC ||
+                       sc->opmode == NL80211_IFTYPE_MESH_POINT ||
+                       sc->opmode == NL80211_IFTYPE_AP) {
                /*
                 * In IBSS mode we use a self-linked tx descriptor and let the
                 * hardware send the beacons automatically. We have to load it
@@ -2164,13 +2171,15 @@ ath5k_beacon_config(struct ath5k_softc *sc)
 
                sc->imask |= AR5K_INT_SWBA;
 
-               if (ath5k_hw_hasveol(ah)) {
-                       spin_lock(&sc->block);
-                       ath5k_beacon_send(sc);
-                       spin_unlock(&sc->block);
-               }
+               if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+                       if (ath5k_hw_hasveol(ah)) {
+                               spin_lock(&sc->block);
+                               ath5k_beacon_send(sc);
+                               spin_unlock(&sc->block);
+                       }
+               } else
+                       ath5k_beacon_update_timers(sc, -1);
        }
-       /* TODO else AP */
 
        ath5k_hw_set_imr(ah, sc->imask);
 }
@@ -2210,7 +2219,7 @@ ath5k_init(struct ath5k_softc *sc, bool is_resume)
         */
        sc->curchan = sc->hw->conf.channel;
        sc->curband = &sc->sbands[sc->curchan->band];
-       sc->imask = AR5K_INT_RX | AR5K_INT_TX | AR5K_INT_RXEOL |
+       sc->imask = AR5K_INT_RXOK | AR5K_INT_TXOK | AR5K_INT_RXEOL |
                AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL |
                AR5K_INT_MIB;
        ret = ath5k_reset(sc, false, false);
@@ -2404,9 +2413,10 @@ ath5k_intr(int irq, void *dev_id)
                                /* bump tx trigger level */
                                ath5k_hw_update_tx_triglevel(ah, true);
                        }
-                       if (status & AR5K_INT_RX)
+                       if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR))
                                tasklet_schedule(&sc->rxtq);
-                       if (status & AR5K_INT_TX)
+                       if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC
+                                       | AR5K_INT_TXERR | AR5K_INT_TXEOL))
                                tasklet_schedule(&sc->txtq);
                        if (status & AR5K_INT_BMISS) {
                        }
@@ -2522,8 +2532,7 @@ ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
        led->led_dev.brightness_set = ath5k_led_brightness_set;
 
        err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
-       if (err)
-       {
+       if (err) {
                ATH5K_WARN(sc, "could not register LED %s\n", name);
                led->sc = NULL;
        }
@@ -2741,8 +2750,10 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
        sc->vif = conf->vif;
 
        switch (conf->type) {
+       case NL80211_IFTYPE_AP:
        case NL80211_IFTYPE_STATION:
        case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_MESH_POINT:
        case NL80211_IFTYPE_MONITOR:
                sc->opmode = conf->type;
                break;
@@ -2780,10 +2791,10 @@ end:
  * TODO: Phy disable/diversity etc
  */
 static int
-ath5k_config(struct ieee80211_hw *hw,
-                       struct ieee80211_conf *conf)
+ath5k_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct ath5k_softc *sc = hw->priv;
+       struct ieee80211_conf *conf = &hw->conf;
 
        sc->bintval = conf->beacon_int;
        sc->power_level = conf->power_level;
@@ -2804,7 +2815,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                ret = -EIO;
                goto unlock;
        }
-       if (conf->bssid) {
+       if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
                /* Cache for later use during resets */
                memcpy(ah->ah_bssid, conf->bssid, ETH_ALEN);
                /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
@@ -2812,18 +2823,17 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
                mmiowb();
        }
-
        if (conf->changed & IEEE80211_IFCC_BEACON &&
-           vif->type == NL80211_IFTYPE_ADHOC) {
+                       (vif->type == NL80211_IFTYPE_ADHOC ||
+                        vif->type == NL80211_IFTYPE_MESH_POINT ||
+                        vif->type == NL80211_IFTYPE_AP)) {
                struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
                if (!beacon) {
                        ret = -ENOMEM;
                        goto unlock;
                }
-               /* call old handler for now */
-               ath5k_beacon_update(hw, beacon);
+               ath5k_beacon_update(sc, beacon);
        }
-
        mutex_unlock(&sc->lock);
 
        return ath5k_reset_wake(sc);
@@ -2883,9 +2893,9 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
                if (*new_flags & FIF_PROMISC_IN_BSS) {
                        rfilt |= AR5K_RX_FILTER_PROM;
                        __set_bit(ATH_STAT_PROMISC, sc->status);
-               }
-               else
+               } else {
                        __clear_bit(ATH_STAT_PROMISC, sc->status);
+               }
        }
 
        /* Note, AR5K_RX_FILTER_MCAST is already enabled */
@@ -2946,9 +2956,12 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
                sc->opmode == NL80211_IFTYPE_ADHOC) {
                rfilt |= AR5K_RX_FILTER_BEACON;
        }
+       if (sc->opmode == NL80211_IFTYPE_MESH_POINT)
+               rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
+                       AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
 
        /* Set filters */
-       ath5k_hw_set_rx_filter(ah,rfilt);
+       ath5k_hw_set_rx_filter(ah, rfilt);
 
        /* Set multicast bits */
        ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]);
@@ -2965,12 +2978,13 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        struct ath5k_softc *sc = hw->priv;
        int ret = 0;
 
-       switch(key->alg) {
+       if (modparam_nohwcrypt)
+               return -EOPNOTSUPP;
+
+       switch (key->alg) {
        case ALG_WEP:
-       /* XXX: fix hardware encryption, its not working. For now
-        * allow software encryption */
-               /* break; */
        case ALG_TKIP:
+               break;
        case ALG_CCMP:
                return -EOPNOTSUPP;
        default:
@@ -2989,6 +3003,8 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                }
                __set_bit(key->keyidx, sc->keymap);
                key->hw_key_idx = key->keyidx;
+               key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV |
+                              IEEE80211_KEY_FLAG_GENERATE_MMIC);
                break;
        case DISABLE_KEY:
                ath5k_hw_reset_key(sc->ah, key->keyidx);
@@ -3055,19 +3071,13 @@ ath5k_reset_tsf(struct ieee80211_hw *hw)
 }
 
 static int
-ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
+ath5k_beacon_update(struct ath5k_softc *sc, struct sk_buff *skb)
 {
-       struct ath5k_softc *sc = hw->priv;
        unsigned long flags;
        int ret;
 
        ath5k_debug_dump_skb(sc, skb, "BC  ", 1);
 
-       if (sc->opmode != NL80211_IFTYPE_ADHOC) {
-               ret = -EIO;
-               goto end;
-       }
-
        spin_lock_irqsave(&sc->block, flags);
        ath5k_txbuf_free(sc, sc->bbuf);
        sc->bbuf->skb = skb;
@@ -3080,7 +3090,6 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
                mmiowb();
        }
 
-end:
        return ret;
 }
 
index 7adceb2c7fab50c33d4769b04364ec6655b4ad3e..7e2b1a67e5da3c505cddea78fde4406ab80254fd 100644 (file)
@@ -472,9 +472,6 @@ bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
  *
  * NOTE: We use read-and-clear register, so after this function is called ISR
  * is zeroed.
- *
- * XXX: Why filter interrupts in sw with interrupt_mask ? No benefit at all
- * plus it can be misleading (one might thing that we save interrupts this way)
  */
 int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
 {
@@ -494,11 +491,16 @@ int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
                }
        } else {
                /*
-                * Read interrupt status from the Read-And-Clear
-                * shadow register.
+                * Read interrupt status from Interrupt
+                * Status Register shadow copy (Read And Clear)
+                *
                 * Note: PISR/SISR Not available on 5210
                 */
                data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR);
+               if (unlikely(data == AR5K_INT_NOCARD)) {
+                       *interrupt_mask = data;
+                       return -ENODEV;
+               }
        }
 
        /*
@@ -506,17 +508,9 @@ int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
         */
        *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr;
 
-       if (unlikely(data == AR5K_INT_NOCARD))
-               return -ENODEV;
-
-       if (data & (AR5K_ISR_RXOK | AR5K_ISR_RXERR))
-               *interrupt_mask |= AR5K_INT_RX;
-
-       if (data & (AR5K_ISR_TXOK | AR5K_ISR_TXERR
-               | AR5K_ISR_TXDESC | AR5K_ISR_TXEOL))
-               *interrupt_mask |= AR5K_INT_TX;
-
        if (ah->ah_version != AR5K_AR5210) {
+               u32 sisr2 = ath5k_hw_reg_read(ah, AR5K_RAC_SISR2);
+
                /*HIU = Host Interface Unit (PCI etc)*/
                if (unlikely(data & (AR5K_ISR_HIUERR)))
                        *interrupt_mask |= AR5K_INT_FATAL;
@@ -524,24 +518,93 @@ int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
                /*Beacon Not Ready*/
                if (unlikely(data & (AR5K_ISR_BNR)))
                        *interrupt_mask |= AR5K_INT_BNR;
-       }
 
-       /*
-        * XXX: BMISS interrupts may occur after association.
-        * I found this on 5210 code but it needs testing. If this is
-        * true we should disable them before assoc and re-enable them
-        * after a successfull assoc + some jiffies.
-        */
-#if 0
-       interrupt_mask &= ~AR5K_INT_BMISS;
-#endif
+               if (unlikely(sisr2 & (AR5K_SISR2_SSERR |
+                                       AR5K_SISR2_DPERR |
+                                       AR5K_SISR2_MCABT)))
+                       *interrupt_mask |= AR5K_INT_FATAL;
+
+               if (data & AR5K_ISR_TIM)
+                       *interrupt_mask |= AR5K_INT_TIM;
+
+               if (data & AR5K_ISR_BCNMISC) {
+                       if (sisr2 & AR5K_SISR2_TIM)
+                               *interrupt_mask |= AR5K_INT_TIM;
+                       if (sisr2 & AR5K_SISR2_DTIM)
+                               *interrupt_mask |= AR5K_INT_DTIM;
+                       if (sisr2 & AR5K_SISR2_DTIM_SYNC)
+                               *interrupt_mask |= AR5K_INT_DTIM_SYNC;
+                       if (sisr2 & AR5K_SISR2_BCN_TIMEOUT)
+                               *interrupt_mask |= AR5K_INT_BCN_TIMEOUT;
+                       if (sisr2 & AR5K_SISR2_CAB_TIMEOUT)
+                               *interrupt_mask |= AR5K_INT_CAB_TIMEOUT;
+               }
+
+               if (data & AR5K_ISR_RXDOPPLER)
+                       *interrupt_mask |= AR5K_INT_RX_DOPPLER;
+               if (data & AR5K_ISR_QCBRORN) {
+                       *interrupt_mask |= AR5K_INT_QCBRORN;
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR3),
+                                       AR5K_SISR3_QCBRORN);
+               }
+               if (data & AR5K_ISR_QCBRURN) {
+                       *interrupt_mask |= AR5K_INT_QCBRURN;
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR3),
+                                       AR5K_SISR3_QCBRURN);
+               }
+               if (data & AR5K_ISR_QTRIG) {
+                       *interrupt_mask |= AR5K_INT_QTRIG;
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR4),
+                                       AR5K_SISR4_QTRIG);
+               }
+
+               if (data & AR5K_ISR_TXOK)
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR0),
+                                       AR5K_SISR0_QCU_TXOK);
+
+               if (data & AR5K_ISR_TXDESC)
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR0),
+                                       AR5K_SISR0_QCU_TXDESC);
+
+               if (data & AR5K_ISR_TXERR)
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR1),
+                                       AR5K_SISR1_QCU_TXERR);
+
+               if (data & AR5K_ISR_TXEOL)
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR1),
+                                       AR5K_SISR1_QCU_TXEOL);
+
+               if (data & AR5K_ISR_TXURN)
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR2),
+                                       AR5K_SISR2_QCU_TXURN);
+       } else {
+               if (unlikely(data & (AR5K_ISR_SSERR | AR5K_ISR_MCABT
+                               | AR5K_ISR_HIUERR | AR5K_ISR_DPERR)))
+                       *interrupt_mask |= AR5K_INT_FATAL;
+
+               /*
+                * XXX: BMISS interrupts may occur after association.
+                * I found this on 5210 code but it needs testing. If this is
+                * true we should disable them before assoc and re-enable them
+                * after a successfull assoc + some jiffies.
+                       interrupt_mask &= ~AR5K_INT_BMISS;
+                */
+       }
 
        /*
         * In case we didn't handle anything,
         * print the register value.
         */
        if (unlikely(*interrupt_mask == 0 && net_ratelimit()))
-               ATH5K_PRINTF("0x%08x\n", data);
+               ATH5K_PRINTF("ISR: 0x%08x IMR: 0x%08x\n", data, ah->ah_imr);
 
        return 0;
 }
@@ -560,14 +623,17 @@ enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
 {
        enum ath5k_int old_mask, int_mask;
 
+       old_mask = ah->ah_imr;
+
        /*
         * Disable card interrupts to prevent any race conditions
-        * (they will be re-enabled afterwards).
+        * (they will be re-enabled afterwards if AR5K_INT GLOBAL
+        * is set again on the new mask).
         */
-       ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
-       ath5k_hw_reg_read(ah, AR5K_IER);
-
-       old_mask = ah->ah_imr;
+       if (old_mask & AR5K_INT_GLOBAL) {
+               ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
+               ath5k_hw_reg_read(ah, AR5K_IER);
+       }
 
        /*
         * Add additional, chipset-dependent interrupt mask flags
@@ -575,30 +641,64 @@ enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
         */
        int_mask = new_mask & AR5K_INT_COMMON;
 
-       if (new_mask & AR5K_INT_RX)
-               int_mask |= AR5K_IMR_RXOK | AR5K_IMR_RXERR | AR5K_IMR_RXORN |
-                       AR5K_IMR_RXDESC;
-
-       if (new_mask & AR5K_INT_TX)
-               int_mask |= AR5K_IMR_TXOK | AR5K_IMR_TXERR | AR5K_IMR_TXDESC |
-                       AR5K_IMR_TXURN;
-
        if (ah->ah_version != AR5K_AR5210) {
+               /* Preserve per queue TXURN interrupt mask */
+               u32 simr2 = ath5k_hw_reg_read(ah, AR5K_SIMR2)
+                               & AR5K_SIMR2_QCU_TXURN;
+
                if (new_mask & AR5K_INT_FATAL) {
                        int_mask |= AR5K_IMR_HIUERR;
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_MCABT |
-                                       AR5K_SIMR2_SSERR | AR5K_SIMR2_DPERR);
+                       simr2 |= (AR5K_SIMR2_MCABT | AR5K_SIMR2_SSERR
+                               | AR5K_SIMR2_DPERR);
                }
+
+               /*Beacon Not Ready*/
+               if (new_mask & AR5K_INT_BNR)
+                       int_mask |= AR5K_INT_BNR;
+
+               if (new_mask & AR5K_INT_TIM)
+                       int_mask |= AR5K_IMR_TIM;
+
+               if (new_mask & AR5K_INT_TIM)
+                       simr2 |= AR5K_SISR2_TIM;
+               if (new_mask & AR5K_INT_DTIM)
+                       simr2 |= AR5K_SISR2_DTIM;
+               if (new_mask & AR5K_INT_DTIM_SYNC)
+                       simr2 |= AR5K_SISR2_DTIM_SYNC;
+               if (new_mask & AR5K_INT_BCN_TIMEOUT)
+                       simr2 |= AR5K_SISR2_BCN_TIMEOUT;
+               if (new_mask & AR5K_INT_CAB_TIMEOUT)
+                       simr2 |= AR5K_SISR2_CAB_TIMEOUT;
+
+               if (new_mask & AR5K_INT_RX_DOPPLER)
+                       int_mask |= AR5K_IMR_RXDOPPLER;
+
+               /* Note: Per queue interrupt masks
+                * are set via reset_tx_queue (qcu.c) */
+               ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
+               ath5k_hw_reg_write(ah, simr2, AR5K_SIMR2);
+
+       } else {
+               if (new_mask & AR5K_INT_FATAL)
+                       int_mask |= (AR5K_IMR_SSERR | AR5K_IMR_MCABT
+                               | AR5K_IMR_HIUERR | AR5K_IMR_DPERR);
+
+               ath5k_hw_reg_write(ah, int_mask, AR5K_IMR);
        }
 
-       ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
+       /* If RXNOFRM interrupt is masked disable it
+        * by setting AR5K_RXNOFRM to zero */
+       if (!(new_mask & AR5K_INT_RXNOFRM))
+               ath5k_hw_reg_write(ah, 0, AR5K_RXNOFRM);
 
        /* Store new interrupt mask */
        ah->ah_imr = new_mask;
 
-       /* ..re-enable interrupts */
-       ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER);
-       ath5k_hw_reg_read(ah, AR5K_IER);
+       /* ..re-enable interrupts if AR5K_INT_GLOBAL is set */
+       if (new_mask & AR5K_INT_GLOBAL) {
+               ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER);
+               ath5k_hw_reg_read(ah, AR5K_IER);
+       }
 
        return old_mask;
 }
index ceaa6c475c0615bb786cf52bb7c0f1838ee557c9..450bd6e945ff152d76d411b7380b38fb84f4baa7 100644 (file)
@@ -1681,7 +1681,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
         */
 
        /* For AR5212 and combatible */
-       if (ah->ah_version == AR5K_AR5212){
+       if (ah->ah_version == AR5K_AR5212) {
 
                /* First set of mode-specific settings */
                ath5k_hw_ini_mode_registers(ah,
@@ -1695,7 +1695,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
                                        ar5212_ini, change_channel);
 
                /* Second set of mode-specific settings */
-               if (ah->ah_radio == AR5K_RF5111){
+               if (ah->ah_radio == AR5K_RF5111) {
 
                        ath5k_hw_ini_mode_registers(ah,
                                        ARRAY_SIZE(ar5212_rf5111_ini_mode_end),
@@ -1706,7 +1706,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
                                        ARRAY_SIZE(rf5111_ini_bbgain),
                                        rf5111_ini_bbgain, change_channel);
 
-               } else if (ah->ah_radio == AR5K_RF5112){
+               } else if (ah->ah_radio == AR5K_RF5112) {
 
                        ath5k_hw_ini_mode_registers(ah,
                                        ARRAY_SIZE(ar5212_rf5112_ini_mode_end),
@@ -1716,7 +1716,7 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
                                        ARRAY_SIZE(rf5112_ini_bbgain),
                                        rf5112_ini_bbgain, change_channel);
 
-               } else if (ah->ah_radio == AR5K_RF5413){
+               } else if (ah->ah_radio == AR5K_RF5413) {
 
                        ath5k_hw_ini_mode_registers(ah,
                                        ARRAY_SIZE(rf5413_ini_mode_end),
index a47df9a24aa126783497eeb296edad22aa150d0e..d7f0c1017bda55a86a18acbb1384ebee34377eb5 100644 (file)
@@ -46,34 +46,45 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah)
 {
        u32 pcu_reg, beacon_reg, low_id, high_id;
 
-       pcu_reg = 0;
+
+       /* Preserve rest settings */
+       pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
+       pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
+                       | AR5K_STA_ID1_KEYSRCH_MODE
+                       | (ah->ah_version == AR5K_AR5210 ?
+                       (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
+
        beacon_reg = 0;
 
        ATH5K_TRACE(ah->ah_sc);
 
        switch (ah->ah_op_mode) {
        case NL80211_IFTYPE_ADHOC:
-               pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_DESC_ANTENNA |
-                       (ah->ah_version == AR5K_AR5210 ?
-                               AR5K_STA_ID1_NO_PSPOLL : 0);
+               pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
                beacon_reg |= AR5K_BCR_ADHOC;
+               if (ah->ah_version == AR5K_AR5210)
+                       pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
+               else
+                       AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_ADHOC);
                break;
 
        case NL80211_IFTYPE_AP:
        case NL80211_IFTYPE_MESH_POINT:
-               pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_RTS_DEF_ANTENNA |
-                       (ah->ah_version == AR5K_AR5210 ?
-                               AR5K_STA_ID1_NO_PSPOLL : 0);
+               pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
                beacon_reg |= AR5K_BCR_AP;
+               if (ah->ah_version == AR5K_AR5210)
+                       pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
+               else
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_ADHOC);
                break;
 
        case NL80211_IFTYPE_STATION:
-               pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
-                       (ah->ah_version == AR5K_AR5210 ?
+               pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
+                       (ah->ah_version == AR5K_AR5210 ?
                                AR5K_STA_ID1_PWR_SV : 0);
        case NL80211_IFTYPE_MONITOR:
-               pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
-                       (ah->ah_version == AR5K_AR5210 ?
+               pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
+                       (ah->ah_version == AR5K_AR5210 ?
                                AR5K_STA_ID1_NO_PSPOLL : 0);
                break;
 
@@ -130,6 +141,8 @@ void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
                ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
                ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
        }
+
+       /* TODO: Handle ANI stats */
 }
 
 /**
@@ -254,6 +267,10 @@ void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
  * @mac: The card's mac address
  *
  * Set station id on hw using the provided mac address
+ *
+ * NOTE: This is only called during attach, don't call it
+ * on reset because it overwrites all AR5K_STA_ID1 settings.
+ * We have set_opmode (above) for reset.
  */
 int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
 {
@@ -290,8 +307,10 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
         * Set simple BSSID mask on 5212
         */
        if (ah->ah_version == AR5K_AR5212) {
-               ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM0);
-               ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM1);
+               ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_bssid_mask),
+                                                       AR5K_BSS_IDM0);
+               ath5k_hw_reg_write(ah, AR5K_HIGH_ID(ah->ah_bssid_mask),
+                                                       AR5K_BSS_IDM1);
        }
 
        /*
@@ -415,6 +434,9 @@ int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
        u32 low_id, high_id;
        ATH5K_TRACE(ah->ah_sc);
 
+       /* Cache bssid mask so that we can restore it
+        * on reset */
+       memcpy(ah->ah_bssid_mask, mask, ETH_ALEN);
        if (ah->ah_version == AR5K_AR5212) {
                low_id = AR5K_LOW_ID(mask);
                high_id = AR5K_HIGH_ID(mask);
@@ -576,7 +598,7 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
                filter |= AR5K_RX_FILTER_PROM;
        }
 
-       /*Zero length DMA*/
+       /*Zero length DMA (phy error reporting) */
        if (data)
                AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
        else
@@ -661,7 +683,12 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
         * Set the additional timers by mode
         */
        switch (ah->ah_op_mode) {
+       case NL80211_IFTYPE_MONITOR:
        case NL80211_IFTYPE_STATION:
+               /* In STA mode timer1 is used as next wakeup
+                * timer and timer2 as next CFP duration start
+                * timer. Both in 1/8TUs. */
+               /* TODO: PCF handling */
                if (ah->ah_version == AR5K_AR5210) {
                        timer1 = 0xffffffff;
                        timer2 = 0xffffffff;
@@ -669,27 +696,60 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
                        timer1 = 0x0000ffff;
                        timer2 = 0x0007ffff;
                }
+               /* Mark associated AP as PCF incapable for now */
+               AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PCF);
                break;
-
+       case NL80211_IFTYPE_ADHOC:
+               AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_ADHOC_BCN_ATIM);
        default:
+               /* On non-STA modes timer1 is used as next DMA
+                * beacon alert (DBA) timer and timer2 as next
+                * software beacon alert. Both in 1/8TUs. */
                timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
                timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
+               break;
        }
 
+       /* Timer3 marks the end of our ATIM window
+        * a zero length window is not allowed because
+        * we 'll get no beacons */
        timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1);
 
        /*
         * Set the beacon register and enable all timers.
-        * (next beacon, DMA beacon, software beacon, ATIM window time)
         */
-       ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
+       /* When in AP mode zero timer0 to start TSF */
+       if (ah->ah_op_mode == NL80211_IFTYPE_AP)
+               ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
+       else
+               ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
        ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
        ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
        ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
 
+       /* Force a TSF reset if requested and enable beacons */
+       if (interval & AR5K_BEACON_RESET_TSF)
+               ath5k_hw_reset_tsf(ah);
+
        ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
-                       AR5K_BEACON_RESET_TSF | AR5K_BEACON_ENABLE),
-               AR5K_BEACON);
+                                       AR5K_BEACON_ENABLE),
+                                               AR5K_BEACON);
+
+       /* Flush any pending BMISS interrupts on ISR by
+        * performing a clear-on-write operation on PISR
+        * register for the BMISS bit (writing a bit on
+        * ISR togles a reset for that bit and leaves
+        * the rest bits intact) */
+       if (ah->ah_version == AR5K_AR5210)
+               ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_ISR);
+       else
+               ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_PISR);
+
+       /* TODO: Set enchanced sleep registers on AR5212
+        * based on vif->bss_conf params, until then
+        * disable power save reporting.*/
+       AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PWR_SV);
+
 }
 
 #if 0
@@ -899,14 +959,26 @@ int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
  */
 int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
 {
-       unsigned int i;
+       unsigned int i, type;
+       u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
 
        ATH5K_TRACE(ah->ah_sc);
        AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
 
+       type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry));
+
        for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
                ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
 
+       /* Reset associated MIC entry if TKIP
+        * is enabled located at offset (entry + 64) */
+       if (type == AR5K_KEYTABLE_TYPE_TKIP) {
+               AR5K_ASSERT_ENTRY(micentry, AR5K_KEYTABLE_SIZE);
+               for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++)
+                       ath5k_hw_reg_write(ah, 0,
+                               AR5K_KEYTABLE_OFF(micentry, i));
+       }
+
        /*
         * Set NULL encryption on AR5212+
         *
@@ -916,10 +988,16 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
         * Note2: Windows driver (ndiswrapper) sets this to
         *        0x00000714 instead of 0x00000007
         */
-       if (ah->ah_version > AR5K_AR5211)
+       if (ah->ah_version > AR5K_AR5211) {
                ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
                                AR5K_KEYTABLE_TYPE(entry));
 
+               if (type == AR5K_KEYTABLE_TYPE_TKIP) {
+                       ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
+                               AR5K_KEYTABLE_TYPE(micentry));
+               }
+       }
+
        return 0;
 }
 
@@ -943,17 +1021,29 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
                const struct ieee80211_key_conf *key, const u8 *mac)
 {
        unsigned int i;
+       int keylen;
        __le32 key_v[5] = {};
+       __le32 key0 = 0, key1 = 0;
+       __le32 *rxmic, *txmic;
        u32 keytype;
+       u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
+       bool is_tkip;
 
        ATH5K_TRACE(ah->ah_sc);
 
-       /* key->keylen comes in from mac80211 in bytes */
+       is_tkip = (key->alg == ALG_TKIP);
+
+       /*
+        * key->keylen comes in from mac80211 in bytes.
+        * TKIP is 128 bit + 128 bit mic
+        */
+       keylen = (is_tkip) ? (128 / 8) : key->keylen;
 
-       if (key->keylen > AR5K_KEYTABLE_SIZE / 8)
+       if (entry > AR5K_KEYTABLE_SIZE ||
+               (is_tkip && micentry > AR5K_KEYTABLE_SIZE))
                return -EOPNOTSUPP;
 
-       switch (key->keylen) {
+       switch (keylen) {
        /* WEP 40-bit   = 40-bit  entered key + 24 bit IV = 64-bit */
        case 40 / 8:
                memcpy(&key_v[0], key->key, 5);
@@ -967,24 +1057,66 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
                memcpy(&key_v[4], &key->key[12], 1);
                keytype = AR5K_KEYTABLE_TYPE_104;
                break;
-       /* WEP 128-bit  = 128-bit entered key + 24 bit IV = 152-bit */
+       /* WEP/TKIP 128-bit  = 128-bit entered key + 24 bit IV = 152-bit */
        case 128 / 8:
                memcpy(&key_v[0], &key->key[0], 6);
                memcpy(&key_v[2], &key->key[6], 6);
                memcpy(&key_v[4], &key->key[12], 4);
-               keytype = AR5K_KEYTABLE_TYPE_128;
+               keytype = is_tkip ?
+                       AR5K_KEYTABLE_TYPE_TKIP :
+                       AR5K_KEYTABLE_TYPE_128;
                break;
 
        default:
                return -EINVAL; /* shouldn't happen */
        }
 
+       /* intentionally corrupt key until mic is installed */
+       if (is_tkip) {
+               key0 = key_v[0] = ~key_v[0];
+               key1 = key_v[1] = ~key_v[1];
+       }
+
        for (i = 0; i < ARRAY_SIZE(key_v); i++)
                ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
                                AR5K_KEYTABLE_OFF(entry, i));
 
        ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry));
 
+       if (is_tkip) {
+               /* Install rx/tx MIC */
+               rxmic = (__le32 *) &key->key[16];
+               txmic = (__le32 *) &key->key[24];
+#if 0
+               /* MISC_MODE register & 0x04 - for mac srev >= griffin */
+               key_v[0] = rxmic[0];
+               key_v[1] = (txmic[0] >> 16) & 0xffff;
+               key_v[2] = rxmic[1];
+               key_v[3] = txmic[0] & 0xffff;
+               key_v[4] = txmic[1];
+#else
+               key_v[0] = rxmic[0];
+               key_v[1] = 0;
+               key_v[2] = rxmic[1];
+               key_v[3] = 0;
+               key_v[4] = 0;
+#endif
+               for (i = 0; i < ARRAY_SIZE(key_v); i++)
+                       ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
+                               AR5K_KEYTABLE_OFF(micentry, i));
+
+               ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
+                       AR5K_KEYTABLE_TYPE(micentry));
+               ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC0(micentry));
+               ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC1(micentry));
+
+               /* restore first 2 words of key */
+               ath5k_hw_reg_write(ah, le32_to_cpu(~key0),
+                       AR5K_KEYTABLE_OFF(entry, 0));
+               ath5k_hw_reg_write(ah, le32_to_cpu(~key1),
+                       AR5K_KEYTABLE_OFF(entry, 1));
+       }
+
        return ath5k_hw_set_key_lladdr(ah, entry, mac);
 }
 
index e43f6563e61a08ab6cbfcaaff1d455c6eb56e8f7..69625bf4d11c7f1807687f845b5692d42a64338f 100644 (file)
@@ -1412,7 +1412,8 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah,
                rf_ini = rfregs_2112a;
                rf_size = ARRAY_SIZE(rfregs_5112a);
                if (mode < 2) {
-                       ATH5K_ERR(ah->ah_sc,"invalid channel mode: %i\n",mode);
+                       ATH5K_ERR(ah->ah_sc, "invalid channel mode: %i\n",
+                                 mode);
                        return -EINVAL;
                }
                mode = mode - 2; /*no a/turboa modes for 2112*/
@@ -1708,7 +1709,7 @@ enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah)
                if (ah->ah_radio >= AR5K_RF5112) {
                        ath5k_hw_rfregs_gainf_corr(ah);
                        ah->ah_gain.g_current =
-                               ah->ah_gain.g_current>=ah->ah_gain.g_f_corr ?
+                               ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
                                (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
                                0;
                }
index 01bf09176d23b79a993ed5daf4b33b30a22a9cc6..1b7bc50ea8eb212b68fdd51f96283de34998e693 100644 (file)
@@ -432,13 +432,30 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
                if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
                        AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
 
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
 
                /* Update secondary interrupt mask registers */
+
+               /* Filter out inactive queues */
                ah->ah_txq_imr_txok &= ah->ah_txq_status;
                ah->ah_txq_imr_txerr &= ah->ah_txq_status;
                ah->ah_txq_imr_txurn &= ah->ah_txq_status;
                ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
                ah->ah_txq_imr_txeol &= ah->ah_txq_status;
+               ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
+               ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
+               ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
+               ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
 
                ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
                        AR5K_SIMR0_QCU_TXOK) |
@@ -448,8 +465,24 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
                        AR5K_SIMR1_QCU_TXERR) |
                        AR5K_REG_SM(ah->ah_txq_imr_txeol,
                        AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
-               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txurn,
-                       AR5K_SIMR2_QCU_TXURN), AR5K_SIMR2);
+               /* Update simr2 but don't overwrite rest simr2 settings */
+               AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
+               AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
+                       AR5K_REG_SM(ah->ah_txq_imr_txurn,
+                       AR5K_SIMR2_QCU_TXURN));
+               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
+                       AR5K_SIMR3_QCBRORN) |
+                       AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
+                       AR5K_SIMR3_QCBRURN), AR5K_SIMR3);
+               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
+                       AR5K_SIMR4_QTRIG), AR5K_SIMR4);
+               /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
+               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
+                       AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
+               /* No queue has TXNOFRM enabled, disable the interrupt
+                * by setting AR5K_TXNOFRM to zero */
+               if (ah->ah_txq_imr_nofrm == 0)
+                       ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
        }
 
        return 0;
index e557fe178bbf9401af6c7846118d0a7f46a16c84..69755fc2f9bee78ab78489bec6cd1ceb782ef914 100644 (file)
 #define AR5K_TXNOFRM           0x004c
 #define        AR5K_TXNOFRM_M          0x000003ff
 #define        AR5K_TXNOFRM_QCU        0x000ffc00
+#define        AR5K_TXNOFRM_QCU_S      10
 
 /*
  * Receive frame gap timeout register
 
 #define AR5K_SISR3             0x0090                  /* Register Address [5211+] */
 #define AR5K_SISR3_QCBRORN     0x000003ff      /* Mask for QCBRORN */
-#define AR5K_SISR3_QCBORN_S    0
+#define AR5K_SISR3_QCBRORN_S   0
 #define AR5K_SISR3_QCBRURN     0x03ff0000      /* Mask for QCBRURN */
 #define AR5K_SISR3_QCBRURN_S   16
 
 #define AR5K_PCU_MAX   0x8fff
 
 /*
- * First station id register (MAC address in lower 32 bits)
+ * First station id register (Lower 32 bits of MAC address)
  */
-#define AR5K_STA_ID0   0x8000
+#define AR5K_STA_ID0           0x8000
+#define        AR5K_STA_ID0_ARRD_L32   0xffffffff
 
 /*
- * Second station id register (MAC address in upper 16 bits)
+ * Second station id register (Upper 16 bits of MAC address + PCU settings)
  */
 #define AR5K_STA_ID1                   0x8004                  /* Register Address */
+#define        AR5K_STA_ID1_ADDR_U16           0x0000ffff      /* Upper 16 bits of MAC addres */
 #define AR5K_STA_ID1_AP                        0x00010000      /* Set AP mode */
 #define AR5K_STA_ID1_ADHOC             0x00020000      /* Set Ad-Hoc mode */
 #define AR5K_STA_ID1_PWR_SV            0x00040000      /* Power save reporting */
 #define AR5K_KEYTABLE_MAC1(_n)         AR5K_KEYTABLE_OFF(_n, 7)
 #define AR5K_KEYTABLE_VALID            0x00008000
 
+/* If key type is TKIP and MIC is enabled
+ * MIC key goes in offset entry + 64 */
+#define        AR5K_KEYTABLE_MIC_OFFSET        64
+
 /* WEP 40-bit  = 40-bit  entered key + 24 bit IV = 64-bit
  * WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit
  * WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit
index 1b6d45b6772db39c269752e1b5bbef4e328d6389..b51bc030da02584fbedadfefd35d9e725133a393 100644 (file)
@@ -864,8 +864,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
 
        /* Pre-enable interrupts on 5211/5212*/
        if (ah->ah_version != AR5K_AR5210)
-               ath5k_hw_set_imr(ah, AR5K_INT_RX | AR5K_INT_TX |
-                               AR5K_INT_FATAL);
+               ath5k_hw_set_imr(ah, ah->ah_imr);
 
        /*
         * Set RF kill flags if supported by the device (read from the EEPROM)
index a6411517e5f849f79c9e49180783ca11264ba4e5..c58cfdeb49c9ac65d74ac7f8306b480b25628e89 100644 (file)
@@ -1,4 +1,8 @@
 ath9k-y +=     hw.o \
+               eeprom.o \
+               mac.o \
+               calib.o \
+               ani.o \
                phy.o \
                regd.o \
                beacon.o \
diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath9k/ani.c
new file mode 100644 (file)
index 0000000..ada12e9
--- /dev/null
@@ -0,0 +1,854 @@
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "core.h"
+#include "hw.h"
+#include "reg.h"
+#include "phy.h"
+
+static int ath9k_hw_get_ani_channel_idx(struct ath_hal *ah,
+                                       struct ath9k_channel *chan)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
+               if (ahp->ah_ani[i].c.channel == chan->channel)
+                       return i;
+               if (ahp->ah_ani[i].c.channel == 0) {
+                       ahp->ah_ani[i].c.channel = chan->channel;
+                       ahp->ah_ani[i].c.channelFlags = chan->channelFlags;
+                       return i;
+               }
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "No more channel states left. Using channel 0\n");
+
+       return 0;
+}
+
+static bool ath9k_hw_ani_control(struct ath_hal *ah,
+                                enum ath9k_ani_cmd cmd, int param)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416AniState *aniState = ahp->ah_curani;
+
+       switch (cmd & ahp->ah_ani_function) {
+       case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                               "%s: level out of range (%u > %u)\n",
+                               __func__, level,
+                               (unsigned)ARRAY_SIZE(ahp->ah_totalSizeDesired));
+                       return false;
+               }
+
+               REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+                             AR_PHY_DESIRED_SZ_TOT_DES,
+                             ahp->ah_totalSizeDesired[level]);
+               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
+                             AR_PHY_AGC_CTL1_COARSE_LOW,
+                             ahp->ah_coarseLow[level]);
+               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
+                             AR_PHY_AGC_CTL1_COARSE_HIGH,
+                             ahp->ah_coarseHigh[level]);
+               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+                             AR_PHY_FIND_SIG_FIRPWR,
+                             ahp->ah_firpwr[level]);
+
+               if (level > aniState->noiseImmunityLevel)
+                       ahp->ah_stats.ast_ani_niup++;
+               else if (level < aniState->noiseImmunityLevel)
+                       ahp->ah_stats.ast_ani_nidown++;
+               aniState->noiseImmunityLevel = level;
+               break;
+       }
+       case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
+               const int m1ThreshLow[] = { 127, 50 };
+               const int m2ThreshLow[] = { 127, 40 };
+               const int m1Thresh[] = { 127, 0x4d };
+               const int m2Thresh[] = { 127, 0x40 };
+               const int m2CountThr[] = { 31, 16 };
+               const int m2CountThrLow[] = { 63, 48 };
+               u32 on = param ? 1 : 0;
+
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
+                             m1ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
+                             m2ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M1_THRESH,
+                             m1Thresh[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M2_THRESH,
+                             m2Thresh[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M2COUNT_THR,
+                             m2CountThr[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
+                             m2CountThrLow[on]);
+
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
+                             m1ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
+                             m2ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M1_THRESH,
+                             m1Thresh[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M2_THRESH,
+                             m2Thresh[on]);
+
+               if (on)
+                       REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
+                                   AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+               else
+                       REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
+                                   AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+
+               if (!on != aniState->ofdmWeakSigDetectOff) {
+                       if (on)
+                               ahp->ah_stats.ast_ani_ofdmon++;
+                       else
+                               ahp->ah_stats.ast_ani_ofdmoff++;
+                       aniState->ofdmWeakSigDetectOff = !on;
+               }
+               break;
+       }
+       case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
+               const int weakSigThrCck[] = { 8, 6 };
+               u32 high = param ? 1 : 0;
+
+               REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
+                             AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
+                             weakSigThrCck[high]);
+               if (high != aniState->cckWeakSigThreshold) {
+                       if (high)
+                               ahp->ah_stats.ast_ani_cckhigh++;
+                       else
+                               ahp->ah_stats.ast_ani_ccklow++;
+                       aniState->cckWeakSigThreshold = high;
+               }
+               break;
+       }
+       case ATH9K_ANI_FIRSTEP_LEVEL:{
+               const int firstep[] = { 0, 4, 8 };
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(firstep)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                               "%s: level out of range (%u > %u)\n",
+                               __func__, level,
+                               (unsigned) ARRAY_SIZE(firstep));
+                       return false;
+               }
+               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+                             AR_PHY_FIND_SIG_FIRSTEP,
+                             firstep[level]);
+               if (level > aniState->firstepLevel)
+                       ahp->ah_stats.ast_ani_stepup++;
+               else if (level < aniState->firstepLevel)
+                       ahp->ah_stats.ast_ani_stepdown++;
+               aniState->firstepLevel = level;
+               break;
+       }
+       case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
+               const int cycpwrThr1[] =
+                       { 2, 4, 6, 8, 10, 12, 14, 16 };
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(cycpwrThr1)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                               "%s: level out of range (%u > %u)\n",
+                               __func__, level,
+                               (unsigned)
+                               ARRAY_SIZE(cycpwrThr1));
+                       return false;
+               }
+               REG_RMW_FIELD(ah, AR_PHY_TIMING5,
+                             AR_PHY_TIMING5_CYCPWR_THR1,
+                             cycpwrThr1[level]);
+               if (level > aniState->spurImmunityLevel)
+                       ahp->ah_stats.ast_ani_spurup++;
+               else if (level < aniState->spurImmunityLevel)
+                       ahp->ah_stats.ast_ani_spurdown++;
+               aniState->spurImmunityLevel = level;
+               break;
+       }
+       case ATH9K_ANI_PRESENT:
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "%s: invalid cmd %u\n", __func__, cmd);
+               return false;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "%s: ANI parameters:\n", __func__);
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
+               "ofdmWeakSigDetectOff=%d\n",
+               aniState->noiseImmunityLevel, aniState->spurImmunityLevel,
+               !aniState->ofdmWeakSigDetectOff);
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "cckWeakSigThreshold=%d, "
+               "firstepLevel=%d, listenTime=%d\n",
+               aniState->cckWeakSigThreshold, aniState->firstepLevel,
+               aniState->listenTime);
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
+               aniState->cycleCount, aniState->ofdmPhyErrCount,
+               aniState->cckPhyErrCount);
+
+       return true;
+}
+
+static void ath9k_hw_update_mibstats(struct ath_hal *ah,
+                                    struct ath9k_mib_stats *stats)
+{
+       stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
+       stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
+       stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
+       stats->rts_good += REG_READ(ah, AR_RTS_OK);
+       stats->beacons += REG_READ(ah, AR_BEACON_CNT);
+}
+
+static void ath9k_ani_restart(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416AniState *aniState;
+
+       if (!DO_ANI(ah))
+               return;
+
+       aniState = ahp->ah_curani;
+
+       aniState->listenTime = 0;
+       if (ahp->ah_hasHwPhyCounters) {
+               if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
+                       aniState->ofdmPhyErrBase = 0;
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                               "OFDM Trigger is too high for hw counters\n");
+               } else {
+                       aniState->ofdmPhyErrBase =
+                               AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
+               }
+               if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
+                       aniState->cckPhyErrBase = 0;
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                               "CCK Trigger is too high for hw counters\n");
+               } else {
+                       aniState->cckPhyErrBase =
+                               AR_PHY_COUNTMAX - aniState->cckTrigHigh;
+               }
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "%s: Writing ofdmbase=%u   cckbase=%u\n",
+                       __func__, aniState->ofdmPhyErrBase,
+                       aniState->cckPhyErrBase);
+               REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
+               REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
+               REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
+               REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
+
+               ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+       }
+       aniState->ofdmPhyErrCount = 0;
+       aniState->cckPhyErrCount = 0;
+}
+
+static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ath9k_channel *chan = ah->ah_curchan;
+       struct ar5416AniState *aniState;
+       enum wireless_mode mode;
+       int32_t rssi;
+
+       if (!DO_ANI(ah))
+               return;
+
+       aniState = ahp->ah_curani;
+
+       if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
+               if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+                                        aniState->noiseImmunityLevel + 1)) {
+                       return;
+               }
+       }
+
+       if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
+               if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
+                                        aniState->spurImmunityLevel + 1)) {
+                       return;
+               }
+       }
+
+       if (ah->ah_opmode == ATH9K_M_HOSTAP) {
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+               }
+               return;
+       }
+       rssi = BEACON_RSSI(ahp);
+       if (rssi > aniState->rssiThrHigh) {
+               if (!aniState->ofdmWeakSigDetectOff) {
+                       if (ath9k_hw_ani_control(ah,
+                                        ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                        false)) {
+                               ath9k_hw_ani_control(ah,
+                                       ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
+                               return;
+                       }
+               }
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+                       return;
+               }
+       } else if (rssi > aniState->rssiThrLow) {
+               if (aniState->ofdmWeakSigDetectOff)
+                       ath9k_hw_ani_control(ah,
+                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                    true);
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+               return;
+       } else {
+               mode = ath9k_hw_chan2wmode(ah, chan);
+               if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
+                       if (!aniState->ofdmWeakSigDetectOff)
+                               ath9k_hw_ani_control(ah,
+                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                    false);
+                       if (aniState->firstepLevel > 0)
+                               ath9k_hw_ani_control(ah,
+                                            ATH9K_ANI_FIRSTEP_LEVEL, 0);
+                       return;
+               }
+       }
+}
+
+static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ath9k_channel *chan = ah->ah_curchan;
+       struct ar5416AniState *aniState;
+       enum wireless_mode mode;
+       int32_t rssi;
+
+       if (!DO_ANI(ah))
+               return;
+
+       aniState = ahp->ah_curani;
+       if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
+               if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+                                        aniState->noiseImmunityLevel + 1)) {
+                       return;
+               }
+       }
+       if (ah->ah_opmode == ATH9K_M_HOSTAP) {
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+               }
+               return;
+       }
+       rssi = BEACON_RSSI(ahp);
+       if (rssi > aniState->rssiThrLow) {
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+       } else {
+               mode = ath9k_hw_chan2wmode(ah, chan);
+               if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
+                       if (aniState->firstepLevel > 0)
+                               ath9k_hw_ani_control(ah,
+                                            ATH9K_ANI_FIRSTEP_LEVEL, 0);
+               }
+       }
+}
+
+static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416AniState *aniState;
+       int32_t rssi;
+
+       aniState = ahp->ah_curani;
+
+       if (ah->ah_opmode == ATH9K_M_HOSTAP) {
+               if (aniState->firstepLevel > 0) {
+                       if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                                aniState->firstepLevel - 1))
+                               return;
+               }
+       } else {
+               rssi = BEACON_RSSI(ahp);
+               if (rssi > aniState->rssiThrHigh) {
+                       /* XXX: Handle me */
+               } else if (rssi > aniState->rssiThrLow) {
+                       if (aniState->ofdmWeakSigDetectOff) {
+                               if (ath9k_hw_ani_control(ah,
+                                        ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                        true) == true)
+                                       return;
+                       }
+                       if (aniState->firstepLevel > 0) {
+                               if (ath9k_hw_ani_control(ah,
+                                        ATH9K_ANI_FIRSTEP_LEVEL,
+                                        aniState->firstepLevel - 1) == true)
+                                       return;
+                       }
+               } else {
+                       if (aniState->firstepLevel > 0) {
+                               if (ath9k_hw_ani_control(ah,
+                                        ATH9K_ANI_FIRSTEP_LEVEL,
+                                        aniState->firstepLevel - 1) == true)
+                                       return;
+                       }
+               }
+       }
+
+       if (aniState->spurImmunityLevel > 0) {
+               if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
+                                        aniState->spurImmunityLevel - 1))
+                       return;
+       }
+
+       if (aniState->noiseImmunityLevel > 0) {
+               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+                                    aniState->noiseImmunityLevel - 1);
+               return;
+       }
+}
+
+static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416AniState *aniState;
+       u32 txFrameCount, rxFrameCount, cycleCount;
+       int32_t listenTime;
+
+       txFrameCount = REG_READ(ah, AR_TFCNT);
+       rxFrameCount = REG_READ(ah, AR_RFCNT);
+       cycleCount = REG_READ(ah, AR_CCCNT);
+
+       aniState = ahp->ah_curani;
+       if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
+
+               listenTime = 0;
+               ahp->ah_stats.ast_ani_lzero++;
+       } else {
+               int32_t ccdelta = cycleCount - aniState->cycleCount;
+               int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
+               int32_t tfdelta = txFrameCount - aniState->txFrameCount;
+               listenTime = (ccdelta - rfdelta - tfdelta) / 44000;
+       }
+       aniState->cycleCount = cycleCount;
+       aniState->txFrameCount = txFrameCount;
+       aniState->rxFrameCount = rxFrameCount;
+
+       return listenTime;
+}
+
+void ath9k_ani_reset(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416AniState *aniState;
+       struct ath9k_channel *chan = ah->ah_curchan;
+       int index;
+
+       if (!DO_ANI(ah))
+               return;
+
+       index = ath9k_hw_get_ani_channel_idx(ah, chan);
+       aniState = &ahp->ah_ani[index];
+       ahp->ah_curani = aniState;
+
+       if (DO_ANI(ah) && ah->ah_opmode != ATH9K_M_STA
+           && ah->ah_opmode != ATH9K_M_IBSS) {
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "%s: Reset ANI state opmode %u\n", __func__,
+                       ah->ah_opmode);
+               ahp->ah_stats.ast_ani_reset++;
+
+               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
+               ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
+               ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
+               ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                    !ATH9K_ANI_USE_OFDM_WEAK_SIG);
+               ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
+                                    ATH9K_ANI_CCK_WEAK_SIG_THR);
+
+               ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
+                                    ATH9K_RX_FILTER_PHYERR);
+
+               if (ah->ah_opmode == ATH9K_M_HOSTAP) {
+                       ahp->ah_curani->ofdmTrigHigh =
+                               ah->ah_config.ofdm_trig_high;
+                       ahp->ah_curani->ofdmTrigLow =
+                               ah->ah_config.ofdm_trig_low;
+                       ahp->ah_curani->cckTrigHigh =
+                               ah->ah_config.cck_trig_high;
+                       ahp->ah_curani->cckTrigLow =
+                               ah->ah_config.cck_trig_low;
+               }
+               ath9k_ani_restart(ah);
+               return;
+       }
+
+       if (aniState->noiseImmunityLevel != 0)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+                                    aniState->noiseImmunityLevel);
+       if (aniState->spurImmunityLevel != 0)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
+                                    aniState->spurImmunityLevel);
+       if (aniState->ofdmWeakSigDetectOff)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                    !aniState->ofdmWeakSigDetectOff);
+       if (aniState->cckWeakSigThreshold)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
+                                    aniState->cckWeakSigThreshold);
+       if (aniState->firstepLevel != 0)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                    aniState->firstepLevel);
+       if (ahp->ah_hasHwPhyCounters) {
+               ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
+                                    ~ATH9K_RX_FILTER_PHYERR);
+               ath9k_ani_restart(ah);
+               REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
+               REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
+
+       } else {
+               ath9k_ani_restart(ah);
+               ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
+                                    ATH9K_RX_FILTER_PHYERR);
+       }
+}
+
+void ath9k_hw_ani_monitor(struct ath_hal *ah,
+                         const struct ath9k_node_stats *stats,
+                         struct ath9k_channel *chan)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416AniState *aniState;
+       int32_t listenTime;
+
+       aniState = ahp->ah_curani;
+       ahp->ah_stats.ast_nodestats = *stats;
+
+       listenTime = ath9k_hw_ani_get_listen_time(ah);
+       if (listenTime < 0) {
+               ahp->ah_stats.ast_ani_lneg++;
+               ath9k_ani_restart(ah);
+               return;
+       }
+
+       aniState->listenTime += listenTime;
+
+       if (ahp->ah_hasHwPhyCounters) {
+               u32 phyCnt1, phyCnt2;
+               u32 ofdmPhyErrCnt, cckPhyErrCnt;
+
+               ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+
+               phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
+               phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
+
+               if (phyCnt1 < aniState->ofdmPhyErrBase ||
+                   phyCnt2 < aniState->cckPhyErrBase) {
+                       if (phyCnt1 < aniState->ofdmPhyErrBase) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                                       "%s: phyCnt1 0x%x, resetting "
+                                       "counter value to 0x%x\n",
+                                       __func__, phyCnt1,
+                                       aniState->ofdmPhyErrBase);
+                               REG_WRITE(ah, AR_PHY_ERR_1,
+                                         aniState->ofdmPhyErrBase);
+                               REG_WRITE(ah, AR_PHY_ERR_MASK_1,
+                                         AR_PHY_ERR_OFDM_TIMING);
+                       }
+                       if (phyCnt2 < aniState->cckPhyErrBase) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                                       "%s: phyCnt2 0x%x, resetting "
+                                       "counter value to 0x%x\n",
+                                       __func__, phyCnt2,
+                                       aniState->cckPhyErrBase);
+                               REG_WRITE(ah, AR_PHY_ERR_2,
+                                         aniState->cckPhyErrBase);
+                               REG_WRITE(ah, AR_PHY_ERR_MASK_2,
+                                         AR_PHY_ERR_CCK_TIMING);
+                       }
+                       return;
+               }
+
+               ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
+               ahp->ah_stats.ast_ani_ofdmerrs +=
+                       ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
+               aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
+
+               cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
+               ahp->ah_stats.ast_ani_cckerrs +=
+                       cckPhyErrCnt - aniState->cckPhyErrCount;
+               aniState->cckPhyErrCount = cckPhyErrCnt;
+       }
+
+       if (!DO_ANI(ah))
+               return;
+
+       if (aniState->listenTime > 5 * ahp->ah_aniPeriod) {
+               if (aniState->ofdmPhyErrCount <= aniState->listenTime *
+                   aniState->ofdmTrigLow / 1000 &&
+                   aniState->cckPhyErrCount <= aniState->listenTime *
+                   aniState->cckTrigLow / 1000)
+                       ath9k_hw_ani_lower_immunity(ah);
+               ath9k_ani_restart(ah);
+       } else if (aniState->listenTime > ahp->ah_aniPeriod) {
+               if (aniState->ofdmPhyErrCount > aniState->listenTime *
+                   aniState->ofdmTrigHigh / 1000) {
+                       ath9k_hw_ani_ofdm_err_trigger(ah);
+                       ath9k_ani_restart(ah);
+               } else if (aniState->cckPhyErrCount >
+                          aniState->listenTime * aniState->cckTrigHigh /
+                          1000) {
+                       ath9k_hw_ani_cck_err_trigger(ah);
+                       ath9k_ani_restart(ah);
+               }
+       }
+}
+
+bool ath9k_hw_phycounters(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+
+       return ahp->ah_hasHwPhyCounters ? true : false;
+}
+
+void ath9k_enable_mib_counters(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n");
+
+       ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+
+       REG_WRITE(ah, AR_FILT_OFDM, 0);
+       REG_WRITE(ah, AR_FILT_CCK, 0);
+       REG_WRITE(ah, AR_MIBC,
+                 ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS)
+                 & 0x0f);
+       REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
+       REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
+}
+
+void ath9k_hw_disable_mib_counters(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disable MIB counters\n");
+
+       REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC);
+
+       ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+
+       REG_WRITE(ah, AR_FILT_OFDM, 0);
+       REG_WRITE(ah, AR_FILT_CCK, 0);
+}
+
+u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
+                                 u32 *rxc_pcnt,
+                                 u32 *rxf_pcnt,
+                                 u32 *txf_pcnt)
+{
+       static u32 cycles, rx_clear, rx_frame, tx_frame;
+       u32 good = 1;
+
+       u32 rc = REG_READ(ah, AR_RCCNT);
+       u32 rf = REG_READ(ah, AR_RFCNT);
+       u32 tf = REG_READ(ah, AR_TFCNT);
+       u32 cc = REG_READ(ah, AR_CCCNT);
+
+       if (cycles == 0 || cycles > cc) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
+                       "%s: cycle counter wrap. ExtBusy = 0\n",
+                       __func__);
+               good = 0;
+       } else {
+               u32 cc_d = cc - cycles;
+               u32 rc_d = rc - rx_clear;
+               u32 rf_d = rf - rx_frame;
+               u32 tf_d = tf - tx_frame;
+
+               if (cc_d != 0) {
+                       *rxc_pcnt = rc_d * 100 / cc_d;
+                       *rxf_pcnt = rf_d * 100 / cc_d;
+                       *txf_pcnt = tf_d * 100 / cc_d;
+               } else {
+                       good = 0;
+               }
+       }
+
+       cycles = cc;
+       rx_frame = rf;
+       rx_clear = rc;
+       tx_frame = tf;
+
+       return good;
+}
+
+/*
+ * 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)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       u32 phyCnt1, phyCnt2;
+
+       /* 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) ||
+           ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
+               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;
+               aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
+
+               cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
+               ahp->ah_stats.ast_ani_cckerrs +=
+                       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);
+       }
+}
+
+void ath9k_hw_ani_setup(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       int i;
+
+       const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
+       const int coarseHigh[] = { -14, -14, -14, -14, -12 };
+       const int coarseLow[] = { -64, -64, -64, -64, -70 };
+       const int firpwr[] = { -78, -78, -78, -78, -80 };
+
+       for (i = 0; i < 5; i++) {
+               ahp->ah_totalSizeDesired[i] = totalSizeDesired[i];
+               ahp->ah_coarseHigh[i] = coarseHigh[i];
+               ahp->ah_coarseLow[i] = coarseLow[i];
+               ahp->ah_firpwr[i] = firpwr[i];
+       }
+}
+
+void ath9k_hw_ani_attach(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       int i;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Attach ANI\n");
+
+       ahp->ah_hasHwPhyCounters = 1;
+
+       memset(ahp->ah_ani, 0, sizeof(ahp->ah_ani));
+       for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
+               ahp->ah_ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
+               ahp->ah_ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
+               ahp->ah_ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
+               ahp->ah_ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
+               ahp->ah_ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
+               ahp->ah_ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
+               ahp->ah_ani[i].ofdmWeakSigDetectOff =
+                       !ATH9K_ANI_USE_OFDM_WEAK_SIG;
+               ahp->ah_ani[i].cckWeakSigThreshold =
+                       ATH9K_ANI_CCK_WEAK_SIG_THR;
+               ahp->ah_ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
+               ahp->ah_ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
+               if (ahp->ah_hasHwPhyCounters) {
+                       ahp->ah_ani[i].ofdmPhyErrBase =
+                               AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
+                       ahp->ah_ani[i].cckPhyErrBase =
+                               AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
+               }
+       }
+       if (ahp->ah_hasHwPhyCounters) {
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "Setting OfdmErrBase = 0x%08x\n",
+                       ahp->ah_ani[0].ofdmPhyErrBase);
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
+                       ahp->ah_ani[0].cckPhyErrBase);
+
+               REG_WRITE(ah, AR_PHY_ERR_1, ahp->ah_ani[0].ofdmPhyErrBase);
+               REG_WRITE(ah, AR_PHY_ERR_2, ahp->ah_ani[0].cckPhyErrBase);
+               ath9k_enable_mib_counters(ah);
+       }
+       ahp->ah_aniPeriod = ATH9K_ANI_PERIOD;
+       if (ah->ah_config.enable_ani)
+               ahp->ah_procPhyErr |= HAL_PROCESS_ANI;
+}
+
+void ath9k_hw_ani_detach(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detach ANI\n");
+
+       if (ahp->ah_hasHwPhyCounters) {
+               ath9k_hw_disable_mib_counters(ah);
+               REG_WRITE(ah, AR_PHY_ERR_1, 0);
+               REG_WRITE(ah, AR_PHY_ERR_2, 0);
+       }
+}
index accace5f7efb9d809e962c4a32d2120e57182d60..3a180ce1770bb6174463ecd7a24c96a57e3fb14a 100644 (file)
@@ -138,6 +138,19 @@ struct ath_desc {
 #define ATH9K_TXDESC_NOACK             0x0002
 #define ATH9K_TXDESC_RTSENA            0x0004
 #define ATH9K_TXDESC_CTSENA            0x0008
+/* ATH9K_TXDESC_INTREQ forces a tx interrupt to be generated for
+ * the descriptor its marked on.  We take a tx interrupt to reap
+ * descriptors when the h/w hits an EOL condition or
+ * when the descriptor is specifically marked to generate
+ * an interrupt with this flag. Descriptors should be
+ * marked periodically to insure timely replenishing of the
+ * supply needed for sending frames. Defering interrupts
+ * reduces system load and potentially allows more concurrent
+ * work to be done but if done to aggressively can cause
+ * senders to backup. When the hardware queue is left too
+ * large rate control information may also be too out of
+ * date. An Alternative for this is TX interrupt mitigation
+ * but this needs more testing. */
 #define ATH9K_TXDESC_INTREQ            0x0010
 #define ATH9K_TXDESC_VEOL              0x0020
 #define ATH9K_TXDESC_EXT_ONLY          0x0040
@@ -815,195 +828,251 @@ struct chan_centers {
        u16 ext_center;
 };
 
-int ath_hal_getcapability(struct ath_hal *ah,
-                         enum ath9k_capability_type type,
-                         u32 capability,
-                         u32 *result);
-const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
-                                                    u32 mode);
-void ath9k_hw_detach(struct ath_hal *ah);
-struct ath_hal *ath9k_hw_attach(u16 devid,
-                               struct ath_softc *sc,
-                               void __iomem *mem,
-                               int *error);
-bool ath9k_regd_init_channels(struct ath_hal *ah,
-                             u32 maxchans, u32 *nchans,
-                             u8 *regclassids,
-                             u32 maxregids, u32 *nregids,
-                             u16 cc,
-                             bool enableOutdoor,
-                             bool enableExtendedChannels);
+/* Helpers */
+
+enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
+                              const struct ath9k_channel *chan);
+bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val);
+u32 ath9k_hw_reverse_bits(u32 val, u32 n);
+bool ath9k_get_channel_edges(struct ath_hal *ah,
+                            u16 flags, u16 *low,
+                            u16 *high);
+u16 ath9k_hw_computetxtime(struct ath_hal *ah,
+                          const struct ath9k_rate_table *rates,
+                          u32 frameLen, u16 rateix,
+                          bool shortPreamble);
 u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags);
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah,
-                                    enum ath9k_int ints);
-bool ath9k_hw_reset(struct ath_hal *ah,
-                   struct ath9k_channel *chan,
+void ath9k_hw_get_channel_centers(struct ath_hal *ah,
+                                 struct ath9k_channel *chan,
+                                 struct chan_centers *centers);
+
+/* Attach, Detach */
+
+const char *ath9k_hw_probe(u16 vendorid, u16 devid);
+void ath9k_hw_detach(struct ath_hal *ah);
+struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
+                               void __iomem *mem, int *error);
+void ath9k_hw_rfdetach(struct ath_hal *ah);
+
+
+/* HW Reset */
+
+bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
                    enum ath9k_ht_macmode macmode,
                    u8 txchainmask, u8 rxchainmask,
                    enum ath9k_ht_extprotspacing extprotspacing,
-                   bool bChannelChange,
-                   int *status);
-bool ath9k_hw_phy_disable(struct ath_hal *ah);
-void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
-                            bool *isCalDone);
-void ath9k_hw_ani_monitor(struct ath_hal *ah,
-                         const struct ath9k_node_stats *stats,
-                         struct ath9k_channel *chan);
-bool ath9k_hw_calibrate(struct ath_hal *ah,
-                       struct ath9k_channel *chan,
-                       u8 rxchainmask,
-                       bool longcal,
-                       bool *isCalDone);
-s16 ath9k_hw_getchan_noise(struct ath_hal *ah,
-                              struct ath9k_channel *chan);
-void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
-                           u16 assocId);
-void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits);
-void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
-                           u16 assocId);
-bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q);
-void ath9k_hw_reset_tsf(struct ath_hal *ah);
-bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry);
-bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
-                       const u8 *mac);
-bool ath9k_hw_set_keycache_entry(struct ath_hal *ah,
-                                u16 entry,
-                                const struct ath9k_keyval *k,
-                                const u8 *mac,
-                                int xorKey);
-bool ath9k_hw_set_tsfadjust(struct ath_hal *ah,
-                           u32 setting);
-void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore);
-bool ath9k_hw_intrpend(struct ath_hal *ah);
-bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked);
-bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah,
-                               bool bIncTrigLevel);
-void ath9k_hw_procmibevent(struct ath_hal *ah,
-                          const struct ath9k_node_stats *stats);
-bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set);
-void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode);
-bool ath9k_hw_phycounters(struct ath_hal *ah);
+                   bool bChannelChange, int *status);
+
+/* Key Cache Management */
+
 bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry);
-bool ath9k_hw_getcapability(struct ath_hal *ah,
-                           enum ath9k_capability_type type,
-                           u32 capability,
-                           u32 *result);
-bool ath9k_hw_setcapability(struct ath_hal *ah,
-                           enum ath9k_capability_type type,
-                           u32 capability,
-                           u32 setting,
-                           int *status);
-u32 ath9k_hw_getdefantenna(struct ath_hal *ah);
-void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac);
-void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask);
-bool ath9k_hw_setbssidmask(struct ath_hal *ah,
-                          const u8 *mask);
+bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac);
+bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
+                                const struct ath9k_keyval *k,
+                                const u8 *mac, int xorKey);
+bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry);
+
+/* Power Management */
+
 bool ath9k_hw_setpower(struct ath_hal *ah,
                       enum ath9k_power_mode mode);
-enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah);
-u64 ath9k_hw_gettsf64(struct ath_hal *ah);
+void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore);
+
+/* Beacon timers */
+
+void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period);
+void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
+                                   const struct ath9k_beacon_state *bs);
+
+/* Rate table */
+
+const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
+                                                    u32 mode);
+
+/* HW Capabilities */
+
+bool ath9k_hw_fill_cap_info(struct ath_hal *ah);
+bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
+                           u32 capability, u32 *result);
+bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type,
+                           u32 capability, u32 setting, int *status);
+
+/* GPIO / RFKILL / Antennae */
+
+void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio);
+u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio);
+void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
+                        u32 ah_signal_type);
+void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val);
+#ifdef CONFIG_RFKILL
+void ath9k_enable_rfkill(struct ath_hal *ah);
+#endif
+int ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg);
 u32 ath9k_hw_getdefantenna(struct ath_hal *ah);
-bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us);
+void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna);
 bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
                               enum ath9k_ant_setting settings,
                               struct ath9k_channel *chan,
                               u8 *tx_chainmask,
                               u8 *rx_chainmask,
                               u8 *antenna_cfgd);
-void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna);
-int ath9k_hw_select_antconfig(struct ath_hal *ah,
-                             u32 cfg);
-bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
-                      u32 txdp);
+
+/* General Operation */
+
+u32 ath9k_hw_getrxfilter(struct ath_hal *ah);
+void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits);
+bool ath9k_hw_phy_disable(struct ath_hal *ah);
+bool ath9k_hw_disable(struct ath_hal *ah);
+bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit);
+void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac);
+bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac);
+void ath9k_hw_setopmode(struct ath_hal *ah);
+void ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0, u32 filter1);
+void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask);
+bool ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask);
+void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, u16 assocId);
+u64 ath9k_hw_gettsf64(struct ath_hal *ah);
+void ath9k_hw_reset_tsf(struct ath_hal *ah);
+bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting);
+bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us);
+void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode);
+
+/* Regulatory */
+
+bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah);
+struct ath9k_channel* ath9k_regd_check_channel(struct ath_hal *ah,
+                        const struct ath9k_channel *c);
+u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan);
+u32 ath9k_regd_get_antenna_allowed(struct ath_hal *ah,
+                                  struct ath9k_channel *chan);
+bool ath9k_regd_init_channels(struct ath_hal *ah,
+                             u32 maxchans, u32 *nchans, u8 *regclassids,
+                             u32 maxregids, u32 *nregids, u16 cc,
+                             bool enableOutdoor, bool enableExtendedChannels);
+
+/* ANI */
+
+void ath9k_ani_reset(struct ath_hal *ah);
+void ath9k_hw_ani_monitor(struct ath_hal *ah,
+                         const struct ath9k_node_stats *stats,
+                         struct ath9k_channel *chan);
+bool ath9k_hw_phycounters(struct ath_hal *ah);
+void ath9k_enable_mib_counters(struct ath_hal *ah);
+void ath9k_hw_disable_mib_counters(struct ath_hal *ah);
+u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
+                                 u32 *rxc_pcnt,
+                                 u32 *rxf_pcnt,
+                                 u32 *txf_pcnt);
+void ath9k_hw_procmibevent(struct ath_hal *ah,
+                          const struct ath9k_node_stats *stats);
+void ath9k_hw_ani_setup(struct ath_hal *ah);
+void ath9k_hw_ani_attach(struct ath_hal *ah);
+void ath9k_hw_ani_detach(struct ath_hal *ah);
+
+/* Calibration */
+
+void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
+                            bool *isCalDone);
+void ath9k_hw_start_nfcal(struct ath_hal *ah);
+void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan);
+int16_t ath9k_hw_getnf(struct ath_hal *ah,
+                      struct ath9k_channel *chan);
+void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah);
+s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan);
+bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
+                       u8 rxchainmask, bool longcal,
+                       bool *isCalDone);
+bool ath9k_hw_init_cal(struct ath_hal *ah,
+                      struct ath9k_channel *chan);
+
+
+/* EEPROM */
+
+int ath9k_hw_set_txpower(struct ath_hal *ah,
+                        struct ath9k_channel *chan,
+                        u16 cfgCtl,
+                        u8 twiceAntennaReduction,
+                        u8 twiceMaxRegulatoryPower,
+                        u8 powerLimit);
+void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan);
+bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
+                                      struct ath9k_channel *chan,
+                                      int16_t *ratesArray,
+                                      u16 cfgCtl,
+                                      u8 AntennaReduction,
+                                      u8 twiceMaxRegulatoryPower,
+                                      u8 powerLimit);
+bool ath9k_hw_set_power_cal_table(struct ath_hal *ah,
+                                 struct ath9k_channel *chan,
+                                 int16_t *pTxPowerIndexOffset);
+bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
+                                     struct ath9k_channel *chan);
+int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah,
+                                   struct ath9k_channel *chan,
+                                   u8 index, u16 *config);
+u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah,
+                              enum ieee80211_band freq_band);
+u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz);
+int ath9k_hw_eeprom_attach(struct ath_hal *ah);
+
+/* Interrupt Handling */
+
+bool ath9k_hw_intrpend(struct ath_hal *ah);
+bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked);
+enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah);
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints);
+
+/* MAC (PCU/QCU) */
+
+void ath9k_hw_dmaRegDump(struct ath_hal *ah);
+u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q);
+bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp);
 bool ath9k_hw_txstart(struct ath_hal *ah, u32 q);
-u16 ath9k_hw_computetxtime(struct ath_hal *ah,
-                                const struct ath9k_rate_table *rates,
-                                u32 frameLen, u16 rateix,
-                                bool shortPreamble);
+u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q);
+bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel);
+bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q);
+bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
+                        u32 segLen, bool firstSeg,
+                        bool lastSeg, const struct ath_desc *ds0);
+void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds);
+int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds);
+void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
+                           u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
+                           u32 keyIx, enum ath9k_key_type keyType, u32 flags);
 void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
                                  struct ath_desc *lastds,
                                  u32 durUpdateEn, u32 rtsctsRate,
                                  u32 rtsctsDuration,
                                  struct ath9k_11n_rate_series series[],
                                  u32 nseries, u32 flags);
-void ath9k_hw_set11n_burstduration(struct ath_hal *ah,
-                                  struct ath_desc *ds,
+void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
+                               u32 aggrLen);
+void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
+                                u32 numDelims);
+void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds);
+void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds);
+void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
                                   u32 burstDuration);
-void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds);
-u32 ath9k_hw_reverse_bits(u32 val, u32 n);
-bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q);
-u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan);
-u32 ath9k_regd_get_antenna_allowed(struct ath_hal *ah,
-                                    struct ath9k_channel *chan);
-u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags);
-bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
-                           struct ath9k_tx_queue_info *qinfo);
+void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
+                                    u32 vmf);
+void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs);
 bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
                            const struct ath9k_tx_queue_info *qinfo);
-struct ath9k_channel *ath9k_regd_check_channel(struct ath_hal *ah,
-                                             const struct ath9k_channel *c);
-void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
-                           u32 pktLen, enum ath9k_pkt_type type,
-                           u32 txPower, u32 keyIx,
-                           enum ath9k_key_type keyType, u32 flags);
-bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
-                        u32 segLen, bool firstSeg,
-                        bool lastSeg,
-                        const struct ath_desc *ds0);
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
-                                       u32 *rxc_pcnt,
-                                       u32 *rxf_pcnt,
-                                       u32 *txf_pcnt);
-void ath9k_hw_dmaRegDump(struct ath_hal *ah);
-void ath9k_hw_beaconinit(struct ath_hal *ah,
-                        u32 next_beacon, u32 beacon_period);
-void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
-                                   const struct ath9k_beacon_state *bs);
+bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
+                           struct ath9k_tx_queue_info *qinfo);
+int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
+                         const struct ath9k_tx_queue_info *qinfo);
+bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q);
+bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q);
+int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
+                       u32 pa, struct ath_desc *nds, u64 tsf);
 bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
                          u32 size, u32 flags);
+bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set);
 void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp);
 void ath9k_hw_rxena(struct ath_hal *ah);
-void ath9k_hw_setopmode(struct ath_hal *ah);
-bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac);
-void ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
-                            u32 filter1);
-u32 ath9k_hw_getrxfilter(struct ath_hal *ah);
 void ath9k_hw_startpcureceive(struct ath_hal *ah);
 void ath9k_hw_stoppcurecv(struct ath_hal *ah);
 bool ath9k_hw_stopdmarecv(struct ath_hal *ah);
-int ath9k_hw_rxprocdesc(struct ath_hal *ah,
-                       struct ath_desc *ds, u32 pa,
-                       struct ath_desc *nds, u64 tsf);
-u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q);
-int ath9k_hw_txprocdesc(struct ath_hal *ah,
-                       struct ath_desc *ds);
-void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
-                                u32 numDelims);
-void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
-                               u32 aggrLen);
-void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds);
-bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q);
-void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs);
-void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds);
-void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah,
-                                    struct ath_desc *ds, u32 vmf);
-bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit);
-bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah);
-int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
-                         const struct ath9k_tx_queue_info *qinfo);
-u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q);
-const char *ath9k_hw_probe(u16 vendorid, u16 devid);
-bool ath9k_hw_disable(struct ath_hal *ah);
-void ath9k_hw_rfdetach(struct ath_hal *ah);
-void ath9k_hw_get_channel_centers(struct ath_hal *ah,
-                                 struct ath9k_channel *chan,
-                                 struct chan_centers *centers);
-bool ath9k_get_channel_edges(struct ath_hal *ah,
-                            u16 flags, u16 *low,
-                            u16 *high);
-void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
-                       u32 ah_signal_type);
-void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 value);
-u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio);
-void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio);
+
 #endif
index 9e15c30bbc065bcb0326ffee6860efda07242f64..d186cd41c2352fa0946de62b829c57df0d3876a3 100644 (file)
@@ -114,7 +114,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
        ath9k_hw_set11n_txdesc(ah, ds,
                               skb->len + FCS_LEN,     /* frame length */
                               ATH9K_PKT_TYPE_BEACON,  /* Atheros packet type */
-                              avp->av_btxctl.txpower, /* txpower XXX */
+                              MAX_RATE_POWER,         /* FIXME */
                               ATH9K_TXKEYIX_INVALID,  /* no encryption */
                               ATH9K_KEY_TYPE_CLEAR,   /* no encryption */
                               flags                   /* no ack,
@@ -152,12 +152,14 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
        struct ath_vap *avp;
        struct sk_buff *skb;
        struct ath_txq *cabq;
+       struct ieee80211_vif *vif;
        struct ieee80211_tx_info *info;
        int cabq_depth;
 
-       avp = sc->sc_vaps[if_id];
-       ASSERT(avp);
+       vif = sc->sc_vaps[if_id];
+       ASSERT(vif);
 
+       avp = (void *)vif->drv_priv;
        cabq = sc->sc_cabq;
 
        if (avp->av_bcbuf == NULL) {
@@ -174,7 +176,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
                                 PCI_DMA_TODEVICE);
        }
 
-       skb = ieee80211_beacon_get(sc->hw, avp->av_if_data);
+       skb = ieee80211_beacon_get(sc->hw, vif);
        bf->bf_mpdu = skb;
        if (skb == NULL)
                return NULL;
@@ -196,7 +198,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
                               skb_end_pointer(skb) - skb->head,
                               PCI_DMA_TODEVICE);
 
-       skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data);
+       skb = ieee80211_get_buffered_bc(sc->hw, vif);
 
        /*
         * if the CABQ traffic from previous DTIM is pending and the current
@@ -232,7 +234,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
         */
        while (skb) {
                ath_tx_cabq(sc, skb);
-               skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data);
+               skb = ieee80211_get_buffered_bc(sc->hw, vif);
        }
 
        return bf;
@@ -244,13 +246,16 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
 */
 static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
 {
+       struct ieee80211_vif *vif;
        struct ath_hal *ah = sc->sc_ah;
        struct ath_buf *bf;
        struct ath_vap *avp;
        struct sk_buff *skb;
 
-       avp = sc->sc_vaps[if_id];
-       ASSERT(avp);
+       vif = sc->sc_vaps[if_id];
+       ASSERT(vif);
+
+       avp = (void *)vif->drv_priv;
 
        if (avp->av_bcbuf == NULL) {
                DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n",
@@ -300,14 +305,17 @@ int ath_beaconq_setup(struct ath_hal *ah)
 */
 int ath_beacon_alloc(struct ath_softc *sc, int if_id)
 {
+       struct ieee80211_vif *vif;
        struct ath_vap *avp;
        struct ieee80211_hdr *hdr;
        struct ath_buf *bf;
        struct sk_buff *skb;
        __le64 tstamp;
 
-       avp = sc->sc_vaps[if_id];
-       ASSERT(avp);
+       vif = sc->sc_vaps[if_id];
+       ASSERT(vif);
+
+       avp = (void *)vif->drv_priv;
 
        /* Allocate a beacon descriptor if we haven't done so. */
        if (!avp->av_bcbuf) {
@@ -363,7 +371,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
         * FIXME: Fill avp->av_btxctl.txpower and
         * avp->av_btxctl.shortPreamble
         */
-       skb = ieee80211_beacon_get(sc->hw, avp->av_if_data);
+       skb = ieee80211_beacon_get(sc->hw, vif);
        if (skb == NULL) {
                DPRINTF(sc, ATH_DBG_BEACON, "%s: cannot get skb\n",
                        __func__);
@@ -652,15 +660,21 @@ void ath_bstuck_process(struct ath_softc *sc)
  */
 void ath_beacon_config(struct ath_softc *sc, int if_id)
 {
+       struct ieee80211_vif *vif;
        struct ath_hal *ah = sc->sc_ah;
        struct ath_beacon_config conf;
+       struct ath_vap *avp;
        enum ath9k_opmode av_opmode;
        u32 nexttbtt, intval;
 
-       if (if_id != ATH_IF_ID_ANY)
-               av_opmode = sc->sc_vaps[if_id]->av_opmode;
-       else
+       if (if_id != ATH_IF_ID_ANY) {
+               vif = sc->sc_vaps[if_id];
+               ASSERT(vif);
+               avp = (void *)vif->drv_priv;
+               av_opmode = avp->av_opmode;
+       } else {
                av_opmode = sc->sc_ah->ah_opmode;
+       }
 
        memset(&conf, 0, sizeof(struct ath_beacon_config));
 
diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath9k/calib.c
new file mode 100644 (file)
index 0000000..1690759
--- /dev/null
@@ -0,0 +1,930 @@
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "core.h"
+#include "hw.h"
+#include "reg.h"
+#include "phy.h"
+
+static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
+
+/* We can tune this as we go by monitoring really low values */
+#define ATH9K_NF_TOO_LOW       -60
+
+/* AR5416 may return very high value (like -31 dBm), in those cases the nf
+ * is incorrect and we should use the static NF value. Later we can try to
+ * find out why they are reporting these values */
+
+static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf)
+{
+       if (nf > ATH9K_NF_TOO_LOW) {
+               DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
+                       "%s: noise floor value detected (%d) is "
+                       "lower than what we think is a "
+                       "reasonable value (%d)\n",
+                       __func__, nf, ATH9K_NF_TOO_LOW);
+               return false;
+       }
+       return true;
+}
+
+static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
+{
+       int16_t nfval;
+       int16_t sort[ATH9K_NF_CAL_HIST_MAX];
+       int i, j;
+
+       for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
+               sort[i] = nfCalBuffer[i];
+
+       for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
+               for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
+                       if (sort[j] > sort[j - 1]) {
+                               nfval = sort[j];
+                               sort[j] = sort[j - 1];
+                               sort[j - 1] = nfval;
+                       }
+               }
+       }
+       nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
+
+       return nfval;
+}
+
+static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
+                                             int16_t *nfarray)
+{
+       int i;
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
+
+               if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
+                       h[i].currIndex = 0;
+
+               if (h[i].invalidNFcount > 0) {
+                       if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE ||
+                           nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
+                               h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
+                       } else {
+                               h[i].invalidNFcount--;
+                               h[i].privNF = nfarray[i];
+                       }
+               } else {
+                       h[i].privNF =
+                               ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
+               }
+       }
+       return;
+}
+
+static void ath9k_hw_do_getnf(struct ath_hal *ah,
+                             int16_t nfarray[NUM_NF_READINGS])
+{
+       int16_t nf;
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
+       else
+               nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
+
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+               "NF calibrated [ctl] [chain 0] is %d\n", nf);
+       nfarray[0] = nf;
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
+                       AR9280_PHY_CH1_MINCCA_PWR);
+       else
+               nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
+                       AR_PHY_CH1_MINCCA_PWR);
+
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
+               "NF calibrated [ctl] [chain 1] is %d\n", nf);
+       nfarray[1] = nf;
+
+       if (!AR_SREV_9280(ah)) {
+               nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
+                       AR_PHY_CH2_MINCCA_PWR);
+               if (nf & 0x100)
+                       nf = 0 - ((nf ^ 0x1ff) + 1);
+               DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
+                       "NF calibrated [ctl] [chain 2] is %d\n", nf);
+               nfarray[2] = nf;
+       }
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
+                       AR9280_PHY_EXT_MINCCA_PWR);
+       else
+               nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
+                       AR_PHY_EXT_MINCCA_PWR);
+
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
+               "NF calibrated [ext] [chain 0] is %d\n", nf);
+       nfarray[3] = nf;
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
+                       AR9280_PHY_CH1_EXT_MINCCA_PWR);
+       else
+               nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
+                       AR_PHY_CH1_EXT_MINCCA_PWR);
+
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+               "NF calibrated [ext] [chain 1] is %d\n", nf);
+       nfarray[4] = nf;
+
+       if (!AR_SREV_9280(ah)) {
+               nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
+                       AR_PHY_CH2_EXT_MINCCA_PWR);
+               if (nf & 0x100)
+                       nf = 0 - ((nf ^ 0x1ff) + 1);
+               DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
+                       "NF calibrated [ext] [chain 2] is %d\n", nf);
+               nfarray[5] = nf;
+       }
+}
+
+static bool getNoiseFloorThresh(struct ath_hal *ah,
+                               const struct ath9k_channel *chan,
+                               int16_t *nft)
+{
+       switch (chan->chanmode) {
+       case CHANNEL_A:
+       case CHANNEL_A_HT20:
+       case CHANNEL_A_HT40PLUS:
+       case CHANNEL_A_HT40MINUS:
+               *nft = (int16_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_5);
+               break;
+       case CHANNEL_B:
+       case CHANNEL_G:
+       case CHANNEL_G_HT20:
+       case CHANNEL_G_HT40PLUS:
+       case CHANNEL_G_HT40MINUS:
+               *nft = (int16_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_2);
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
+                       "%s: invalid channel flags 0x%x\n", __func__,
+                       chan->channelFlags);
+               return false;
+       }
+
+       return true;
+}
+
+static void ath9k_hw_setup_calibration(struct ath_hal *ah,
+                                      struct hal_cal_list *currCal)
+{
+       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
+                     AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
+                     currCal->calData->calCountMax);
+
+       switch (currCal->calData->calType) {
+       case IQ_MISMATCH_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%s: starting IQ Mismatch Calibration\n",
+                       __func__);
+               break;
+       case ADC_GAIN_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%s: starting ADC Gain Calibration\n", __func__);
+               break;
+       case ADC_DC_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%s: starting ADC DC Calibration\n", __func__);
+               break;
+       case ADC_DC_INIT_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%s: starting Init ADC DC Calibration\n",
+                       __func__);
+               break;
+       }
+
+       REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
+                   AR_PHY_TIMING_CTRL4_DO_CAL);
+}
+
+static void ath9k_hw_reset_calibration(struct ath_hal *ah,
+                                      struct hal_cal_list *currCal)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       int i;
+
+       ath9k_hw_setup_calibration(ah, currCal);
+
+       currCal->calState = CAL_RUNNING;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ahp->ah_Meas0.sign[i] = 0;
+               ahp->ah_Meas1.sign[i] = 0;
+               ahp->ah_Meas2.sign[i] = 0;
+               ahp->ah_Meas3.sign[i] = 0;
+       }
+
+       ahp->ah_CalSamples = 0;
+}
+
+static void ath9k_hw_per_calibration(struct ath_hal *ah,
+                                    struct ath9k_channel *ichan,
+                                    u8 rxchainmask,
+                                    struct hal_cal_list *currCal,
+                                    bool *isCalDone)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+
+       *isCalDone = false;
+
+       if (currCal->calState == CAL_RUNNING) {
+               if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
+                     AR_PHY_TIMING_CTRL4_DO_CAL)) {
+
+                       currCal->calData->calCollect(ah);
+                       ahp->ah_CalSamples++;
+
+                       if (ahp->ah_CalSamples >= currCal->calData->calNumSamples) {
+                               int i, numChains = 0;
+                               for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+                                       if (rxchainmask & (1 << i))
+                                               numChains++;
+                               }
+
+                               currCal->calData->calPostProc(ah, numChains);
+                               ichan->CalValid |= currCal->calData->calType;
+                               currCal->calState = CAL_DONE;
+                               *isCalDone = true;
+                       } else {
+                               ath9k_hw_setup_calibration(ah, currCal);
+                       }
+               }
+       } else if (!(ichan->CalValid & currCal->calData->calType)) {
+               ath9k_hw_reset_calibration(ah, currCal);
+       }
+}
+
+static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
+                                    struct ath9k_channel *chan,
+                                    enum hal_cal_types calType)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       bool retval = false;
+
+       switch (calType & ahp->ah_suppCals) {
+       case IQ_MISMATCH_CAL:
+               if (!IS_CHAN_B(chan))
+                       retval = true;
+               break;
+       case ADC_GAIN_CAL:
+       case ADC_DC_CAL:
+               if (!IS_CHAN_B(chan)
+                   && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
+                       retval = true;
+               break;
+       }
+
+       return retval;
+}
+
+static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       int i;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ahp->ah_totalPowerMeasI[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+               ahp->ah_totalPowerMeasQ[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+               ahp->ah_totalIqCorrMeas[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+                       ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
+                       ahp->ah_totalPowerMeasQ[i],
+                       ahp->ah_totalIqCorrMeas[i]);
+       }
+}
+
+static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       int i;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ahp->ah_totalAdcIOddPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+               ahp->ah_totalAdcIEvenPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+               ahp->ah_totalAdcQOddPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+               ahp->ah_totalAdcQEvenPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
+                       "oddq=0x%08x; evenq=0x%08x;\n",
+                       ahp->ah_CalSamples, i,
+                       ahp->ah_totalAdcIOddPhase[i],
+                       ahp->ah_totalAdcIEvenPhase[i],
+                       ahp->ah_totalAdcQOddPhase[i],
+                       ahp->ah_totalAdcQEvenPhase[i]);
+       }
+}
+
+static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       int i;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+               ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+               ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+               ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
+                       "oddq=0x%08x; evenq=0x%08x;\n",
+                       ahp->ah_CalSamples, i,
+                       ahp->ah_totalAdcDcOffsetIOddPhase[i],
+                       ahp->ah_totalAdcDcOffsetIEvenPhase[i],
+                       ahp->ah_totalAdcDcOffsetQOddPhase[i],
+                       ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
+       }
+}
+
+static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       u32 powerMeasQ, powerMeasI, iqCorrMeas;
+       u32 qCoffDenom, iCoffDenom;
+       int32_t qCoff, iCoff;
+       int iqCorrNeg, i;
+
+       for (i = 0; i < numChains; i++) {
+               powerMeasI = ahp->ah_totalPowerMeasI[i];
+               powerMeasQ = ahp->ah_totalPowerMeasQ[i];
+               iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Starting IQ Cal and Correction for Chain %d\n",
+                       i);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Orignal: Chn %diq_corr_meas = 0x%08x\n",
+                       i, ahp->ah_totalIqCorrMeas[i]);
+
+               iqCorrNeg = 0;
+
+               if (iqCorrMeas > 0x80000000) {
+                       iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
+                       iqCorrNeg = 1;
+               }
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
+                       iqCorrNeg);
+
+               iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
+               qCoffDenom = powerMeasQ / 64;
+
+               if (powerMeasQ != 0) {
+                       iCoff = iqCorrMeas / iCoffDenom;
+                       qCoff = powerMeasI / qCoffDenom - 64;
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "Chn %d iCoff = 0x%08x\n", i, iCoff);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "Chn %d qCoff = 0x%08x\n", i, qCoff);
+
+                       iCoff = iCoff & 0x3f;
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
+                       if (iqCorrNeg == 0x0)
+                               iCoff = 0x40 - iCoff;
+
+                       if (qCoff > 15)
+                               qCoff = 15;
+                       else if (qCoff <= -16)
+                               qCoff = 16;
+
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
+                               i, iCoff, qCoff);
+
+                       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
+                                     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
+                                     iCoff);
+                       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
+                                     AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
+                                     qCoff);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "IQ Cal and Correction done for Chain %d\n",
+                               i);
+               }
+       }
+
+       REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
+                   AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
+}
+
+static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
+       u32 qGainMismatch, iGainMismatch, val, i;
+
+       for (i = 0; i < numChains; i++) {
+               iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
+               iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
+               qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
+               qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Starting ADC Gain Cal for Chain %d\n", i);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
+                       iOddMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_even_i = 0x%08x\n", i,
+                       iEvenMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
+                       qOddMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_even_q = 0x%08x\n", i,
+                       qEvenMeasOffset);
+
+               if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
+                       iGainMismatch =
+                               ((iEvenMeasOffset * 32) /
+                                iOddMeasOffset) & 0x3f;
+                       qGainMismatch =
+                               ((qOddMeasOffset * 32) /
+                                qEvenMeasOffset) & 0x3f;
+
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "Chn %d gain_mismatch_i = 0x%08x\n", i,
+                               iGainMismatch);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "Chn %d gain_mismatch_q = 0x%08x\n", i,
+                               qGainMismatch);
+
+                       val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
+                       val &= 0xfffff000;
+                       val |= (qGainMismatch) | (iGainMismatch << 6);
+                       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
+
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "ADC Gain Cal done for Chain %d\n", i);
+               }
+       }
+
+       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
+                 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
+                 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
+}
+
+static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       u32 iOddMeasOffset, iEvenMeasOffset, val, i;
+       int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
+       const struct hal_percal_data *calData =
+               ahp->ah_cal_list_curr->calData;
+       u32 numSamples =
+               (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
+
+       for (i = 0; i < numChains; i++) {
+               iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
+               iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
+               qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
+               qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Starting ADC DC Offset Cal for Chain %d\n", i);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_odd_i = %d\n", i,
+                       iOddMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_even_i = %d\n", i,
+                       iEvenMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_odd_q = %d\n", i,
+                       qOddMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_even_q = %d\n", i,
+                       qEvenMeasOffset);
+
+               iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
+                              numSamples) & 0x1ff;
+               qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
+                              numSamples) & 0x1ff;
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
+                       iDcMismatch);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
+                       qDcMismatch);
+
+               val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
+               val &= 0xc0000fff;
+               val |= (qDcMismatch << 12) | (iDcMismatch << 21);
+               REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "ADC DC Offset Cal done for Chain %d\n", i);
+       }
+
+       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
+                 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
+                 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
+}
+
+void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
+                            bool *isCalDone)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ath9k_channel *ichan =
+               ath9k_regd_check_channel(ah, chan);
+       struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
+
+       *isCalDone = true;
+
+       if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
+               return;
+
+       if (currCal == NULL)
+               return;
+
+       if (ichan == NULL) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%s: invalid channel %u/0x%x; no mapping\n",
+                       __func__, chan->channel, chan->channelFlags);
+               return;
+       }
+
+
+       if (currCal->calState != CAL_DONE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%s: Calibration state incorrect, %d\n",
+                       __func__, currCal->calState);
+               return;
+       }
+
+
+       if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
+               return;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+               "%s: Resetting Cal %d state for channel %u/0x%x\n",
+               __func__, currCal->calData->calType, chan->channel,
+               chan->channelFlags);
+
+       ichan->CalValid &= ~currCal->calData->calType;
+       currCal->calState = CAL_WAITING;
+
+       *isCalDone = false;
+}
+
+void ath9k_hw_start_nfcal(struct ath_hal *ah)
+{
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
+                   AR_PHY_AGC_CONTROL_ENABLE_NF);
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
+                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+}
+
+void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+       struct ath9k_nfcal_hist *h;
+       int i, j;
+       int32_t val;
+       const u32 ar5416_cca_regs[6] = {
+               AR_PHY_CCA,
+               AR_PHY_CH1_CCA,
+               AR_PHY_CH2_CCA,
+               AR_PHY_EXT_CCA,
+               AR_PHY_CH1_EXT_CCA,
+               AR_PHY_CH2_EXT_CCA
+       };
+       u8 chainmask;
+
+       if (AR_SREV_9280(ah))
+               chainmask = 0x1B;
+       else
+               chainmask = 0x3F;
+
+#ifdef ATH_NF_PER_CHAN
+       h = chan->nfCalHist;
+#else
+       h = ah->nfCalHist;
+#endif
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               if (chainmask & (1 << i)) {
+                       val = REG_READ(ah, ar5416_cca_regs[i]);
+                       val &= 0xFFFFFE00;
+                       val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
+                       REG_WRITE(ah, ar5416_cca_regs[i], val);
+               }
+       }
+
+       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+                   AR_PHY_AGC_CONTROL_ENABLE_NF);
+       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+
+       for (j = 0; j < 1000; j++) {
+               if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
+                    AR_PHY_AGC_CONTROL_NF) == 0)
+                       break;
+               udelay(10);
+       }
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               if (chainmask & (1 << i)) {
+                       val = REG_READ(ah, ar5416_cca_regs[i]);
+                       val &= 0xFFFFFE00;
+                       val |= (((u32) (-50) << 1) & 0x1ff);
+                       REG_WRITE(ah, ar5416_cca_regs[i], val);
+               }
+       }
+}
+
+int16_t ath9k_hw_getnf(struct ath_hal *ah,
+                      struct ath9k_channel *chan)
+{
+       int16_t nf, nfThresh;
+       int16_t nfarray[NUM_NF_READINGS] = { 0 };
+       struct ath9k_nfcal_hist *h;
+       u8 chainmask;
+
+       if (AR_SREV_9280(ah))
+               chainmask = 0x1B;
+       else
+               chainmask = 0x3F;
+
+       chan->channelFlags &= (~CHANNEL_CW_INT);
+       if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%s: NF did not complete in calibration window\n",
+                       __func__);
+               nf = 0;
+               chan->rawNoiseFloor = nf;
+               return chan->rawNoiseFloor;
+       } else {
+               ath9k_hw_do_getnf(ah, nfarray);
+               nf = nfarray[0];
+               if (getNoiseFloorThresh(ah, chan, &nfThresh)
+                   && nf > nfThresh) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "%s: noise floor failed detected; "
+                               "detected %d, threshold %d\n", __func__,
+                               nf, nfThresh);
+                       chan->channelFlags |= CHANNEL_CW_INT;
+               }
+       }
+
+#ifdef ATH_NF_PER_CHAN
+       h = chan->nfCalHist;
+#else
+       h = ah->nfCalHist;
+#endif
+
+       ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
+       chan->rawNoiseFloor = h[0].privNF;
+
+       return chan->rawNoiseFloor;
+}
+
+void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
+{
+       int i, j;
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               ah->nfCalHist[i].currIndex = 0;
+               ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE;
+               ah->nfCalHist[i].invalidNFcount =
+                       AR_PHY_CCA_FILTERWINDOW_LENGTH;
+               for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
+                       ah->nfCalHist[i].nfCalBuffer[j] =
+                               AR_PHY_CCA_MAX_GOOD_VALUE;
+               }
+       }
+       return;
+}
+
+s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+       struct ath9k_channel *ichan;
+       s16 nf;
+
+       ichan = ath9k_regd_check_channel(ah, chan);
+       if (ichan == NULL) {
+               DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
+                       "%s: invalid channel %u/0x%x; no mapping\n",
+                       __func__, chan->channel, chan->channelFlags);
+               return ATH_DEFAULT_NOISE_FLOOR;
+       }
+       if (ichan->rawNoiseFloor == 0) {
+               enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
+               nf = NOISE_FLOOR[mode];
+       } else
+               nf = ichan->rawNoiseFloor;
+
+       if (!ath9k_hw_nf_in_range(ah, nf))
+               nf = ATH_DEFAULT_NOISE_FLOOR;
+
+       return nf;
+}
+
+bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
+                       u8 rxchainmask, bool longcal,
+                       bool *isCalDone)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
+       struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
+
+       *isCalDone = true;
+
+       if (ichan == NULL) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
+                       "%s: invalid channel %u/0x%x; no mapping\n",
+                       __func__, chan->channel, chan->channelFlags);
+               return false;
+       }
+
+       if (currCal &&
+           (currCal->calState == CAL_RUNNING ||
+            currCal->calState == CAL_WAITING)) {
+               ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
+                                        isCalDone);
+               if (*isCalDone) {
+                       ahp->ah_cal_list_curr = currCal = currCal->calNext;
+
+                       if (currCal->calState == CAL_WAITING) {
+                               *isCalDone = false;
+                               ath9k_hw_reset_calibration(ah, currCal);
+                       }
+               }
+       }
+
+       if (longcal) {
+               ath9k_hw_getnf(ah, ichan);
+               ath9k_hw_loadnf(ah, ah->ah_curchan);
+               ath9k_hw_start_nfcal(ah);
+
+               if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
+                       chan->channelFlags |= CHANNEL_CW_INT;
+                       ichan->channelFlags &= ~CHANNEL_CW_INT;
+               }
+       }
+
+       return true;
+}
+
+bool ath9k_hw_init_cal(struct ath_hal *ah,
+                      struct ath9k_channel *chan)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
+
+       REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+                 REG_READ(ah, AR_PHY_AGC_CONTROL) |
+                 AR_PHY_AGC_CONTROL_CAL);
+
+       if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%s: offset calibration failed to complete in 1ms; "
+                       "noisy environment?\n", __func__);
+               return false;
+       }
+
+       REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+                 REG_READ(ah, AR_PHY_AGC_CONTROL) |
+                 AR_PHY_AGC_CONTROL_NF);
+
+       ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
+
+       if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
+               if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
+                       INIT_CAL(&ahp->ah_adcGainCalData);
+                       INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "%s: enabling ADC Gain Calibration.\n",
+                               __func__);
+               }
+               if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
+                       INIT_CAL(&ahp->ah_adcDcCalData);
+                       INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "%s: enabling ADC DC Calibration.\n",
+                               __func__);
+               }
+               if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
+                       INIT_CAL(&ahp->ah_iqCalData);
+                       INSERT_CAL(ahp, &ahp->ah_iqCalData);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "%s: enabling IQ Calibration.\n",
+                               __func__);
+               }
+
+               ahp->ah_cal_list_curr = ahp->ah_cal_list;
+
+               if (ahp->ah_cal_list_curr)
+                       ath9k_hw_reset_calibration(ah, ahp->ah_cal_list_curr);
+       }
+
+       ichan->CalValid = 0;
+
+       return true;
+}
+
+const struct hal_percal_data iq_cal_multi_sample = {
+       IQ_MISMATCH_CAL,
+       MAX_CAL_SAMPLES,
+       PER_MIN_LOG_COUNT,
+       ath9k_hw_iqcal_collect,
+       ath9k_hw_iqcalibrate
+};
+const struct hal_percal_data iq_cal_single_sample = {
+       IQ_MISMATCH_CAL,
+       MIN_CAL_SAMPLES,
+       PER_MAX_LOG_COUNT,
+       ath9k_hw_iqcal_collect,
+       ath9k_hw_iqcalibrate
+};
+const struct hal_percal_data adc_gain_cal_multi_sample = {
+       ADC_GAIN_CAL,
+       MAX_CAL_SAMPLES,
+       PER_MIN_LOG_COUNT,
+       ath9k_hw_adc_gaincal_collect,
+       ath9k_hw_adc_gaincal_calibrate
+};
+const struct hal_percal_data adc_gain_cal_single_sample = {
+       ADC_GAIN_CAL,
+       MIN_CAL_SAMPLES,
+       PER_MAX_LOG_COUNT,
+       ath9k_hw_adc_gaincal_collect,
+       ath9k_hw_adc_gaincal_calibrate
+};
+const struct hal_percal_data adc_dc_cal_multi_sample = {
+       ADC_DC_CAL,
+       MAX_CAL_SAMPLES,
+       PER_MIN_LOG_COUNT,
+       ath9k_hw_adc_dccal_collect,
+       ath9k_hw_adc_dccal_calibrate
+};
+const struct hal_percal_data adc_dc_cal_single_sample = {
+       ADC_DC_CAL,
+       MIN_CAL_SAMPLES,
+       PER_MAX_LOG_COUNT,
+       ath9k_hw_adc_dccal_collect,
+       ath9k_hw_adc_dccal_calibrate
+};
+const struct hal_percal_data adc_init_dc_cal = {
+       ADC_DC_INIT_CAL,
+       MIN_CAL_SAMPLES,
+       INIT_LOG_COUNT,
+       ath9k_hw_adc_dccal_collect,
+       ath9k_hw_adc_dccal_calibrate
+};
index c5033f6f42acd3c6ddf4cf7d00835adf9c9b665e..5f5184acb2746de6a73b418f27a489e0c11397cf 100644 (file)
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
- /* Implementation of the main "ATH" layer. */
-
 #include "core.h"
 #include "regd.h"
 
-static int ath_outdoor;                /* enable outdoor use */
-
 static u32 ath_chainmask_sel_up_rssi_thres =
        ATH_CHAINMASK_SEL_UP_RSSI_THRES;
 static u32 ath_chainmask_sel_down_rssi_thres =
@@ -47,6 +43,41 @@ static void bus_read_cachesize(struct ath_softc *sc, int *csz)
                *csz = DEFAULT_CACHELINE >> 2;   /* Use the default size */
 }
 
+static u8 parse_mpdudensity(u8 mpdudensity)
+{
+       /*
+        * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
+        *   0 for no restriction
+        *   1 for 1/4 us
+        *   2 for 1/2 us
+        *   3 for 1 us
+        *   4 for 2 us
+        *   5 for 4 us
+        *   6 for 8 us
+        *   7 for 16 us
+        */
+       switch (mpdudensity) {
+       case 0:
+               return 0;
+       case 1:
+       case 2:
+       case 3:
+               /* Our lower layer calculations limit our precision to
+                  1 microsecond */
+               return 1;
+       case 4:
+               return 2;
+       case 5:
+               return 4;
+       case 6:
+               return 8;
+       case 7:
+               return 16;
+       default:
+               return 0;
+       }
+}
+
 /*
  *  Set current operating mode
  *
@@ -155,17 +186,10 @@ static int ath_setup_channels(struct ath_softc *sc)
        struct ath9k_channel *c;
 
        /* Fill in ah->ah_channels */
-       if (!ath9k_regd_init_channels(ah,
-                                     ATH_CHAN_MAX,
-                                     (u32 *)&nchan,
-                                     regclassids,
-                                     ATH_REGCLASSIDS_MAX,
-                                     &nregclass,
-                                     CTRY_DEFAULT,
-                                     false,
-                                     1)) {
+       if (!ath9k_regd_init_channels(ah, ATH_CHAN_MAX, (u32 *)&nchan,
+                                     regclassids, ATH_REGCLASSIDS_MAX,
+                                     &nregclass, CTRY_DEFAULT, false, 1)) {
                u32 rd = ah->ah_currentRD;
-
                DPRINTF(sc, ATH_DBG_FATAL,
                        "%s: unable to collect channel list; "
                        "regdomain likely %u country code %u\n",
@@ -186,40 +210,32 @@ static int ath_setup_channels(struct ath_softc *sc)
                        chan_2ghz[a].max_power = c->maxTxPower;
 
                        if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
-                               chan_2ghz[a].flags |=
-                                       IEEE80211_CHAN_NO_IBSS;
+                               chan_2ghz[a].flags |= IEEE80211_CHAN_NO_IBSS;
                        if (c->channelFlags & CHANNEL_PASSIVE)
-                               chan_2ghz[a].flags |=
-                                       IEEE80211_CHAN_PASSIVE_SCAN;
+                               chan_2ghz[a].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
 
                        band_2ghz->n_channels = ++a;
 
                        DPRINTF(sc, ATH_DBG_CONFIG,
                                "%s: 2MHz channel: %d, "
                                "channelFlags: 0x%x\n",
-                               __func__,
-                               c->channel,
-                               c->channelFlags);
+                               __func__, c->channel, c->channelFlags);
                } else if (IS_CHAN_5GHZ(c)) {
                        chan_5ghz[b].band = IEEE80211_BAND_5GHZ;
                        chan_5ghz[b].center_freq = c->channel;
                        chan_5ghz[b].max_power = c->maxTxPower;
 
                        if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
-                               chan_5ghz[b].flags |=
-                                       IEEE80211_CHAN_NO_IBSS;
+                               chan_5ghz[b].flags |= IEEE80211_CHAN_NO_IBSS;
                        if (c->channelFlags & CHANNEL_PASSIVE)
-                               chan_5ghz[b].flags |=
-                                       IEEE80211_CHAN_PASSIVE_SCAN;
+                               chan_5ghz[b].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
 
                        band_5ghz->n_channels = ++b;
 
                        DPRINTF(sc, ATH_DBG_CONFIG,
                                "%s: 5MHz channel: %d, "
                                "channelFlags: 0x%x\n",
-                               __func__,
-                               c->channel,
-                               c->channelFlags);
+                               __func__, c->channel, c->channelFlags);
                }
        }
 
@@ -260,44 +276,6 @@ static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan)
        return ATH9K_MODE_11B;
 }
 
-/*
- * Stop the device, grabbing the top-level lock to protect
- * against concurrent entry through ath_init (which can happen
- * if another thread does a system call and the thread doing the
- * stop is preempted).
- */
-
-static int ath_stop(struct ath_softc *sc)
-{
-       struct ath_hal *ah = sc->sc_ah;
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "%s: invalid %ld\n",
-               __func__, sc->sc_flags & SC_OP_INVALID);
-
-       /*
-        * Shutdown the hardware and driver:
-        *    stop output from above
-        *    turn off timers
-        *    disable interrupts
-        *    clear transmit machinery
-        *    clear receive machinery
-        *    turn off the radio
-        *    reclaim beacon resources
-        *
-        * Note that some of this work is not possible if the
-        * hardware is gone (invalid).
-        */
-
-       ath_draintxq(sc, false);
-       if (!(sc->sc_flags & SC_OP_INVALID)) {
-               ath_stoprecv(sc);
-               ath9k_hw_phy_disable(ah);
-       } else
-               sc->sc_rxlink = NULL;
-
-       return 0;
-}
-
 /*
  * Set the current channel
  *
@@ -606,114 +584,6 @@ static void ath_ani_calibrate(unsigned long data)
        mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(cal_interval));
 }
 
-/******************/
-/* VAP management */
-/******************/
-
-int ath_vap_attach(struct ath_softc *sc,
-                  int if_id,
-                  struct ieee80211_vif *if_data,
-                  enum ath9k_opmode opmode)
-{
-       struct ath_vap *avp;
-
-       if (if_id >= ATH_BCBUF || sc->sc_vaps[if_id] != NULL) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "%s: Invalid interface id = %u\n", __func__, if_id);
-               return -EINVAL;
-       }
-
-       switch (opmode) {
-       case ATH9K_M_STA:
-       case ATH9K_M_IBSS:
-       case ATH9K_M_MONITOR:
-               break;
-       case ATH9K_M_HOSTAP:
-               /* XXX not right, beacon buffer is allocated on RUN trans */
-               if (list_empty(&sc->sc_bbuf))
-                       return -ENOMEM;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* create ath_vap */
-       avp = kmalloc(sizeof(struct ath_vap), GFP_KERNEL);
-       if (avp == NULL)
-               return -ENOMEM;
-
-       memset(avp, 0, sizeof(struct ath_vap));
-       avp->av_if_data = if_data;
-       /* Set the VAP opmode */
-       avp->av_opmode = opmode;
-       avp->av_bslot = -1;
-
-       if (opmode == ATH9K_M_HOSTAP)
-               ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
-
-       sc->sc_vaps[if_id] = avp;
-       sc->sc_nvaps++;
-       /* Set the device opmode */
-       sc->sc_ah->ah_opmode = opmode;
-
-       /* default VAP configuration */
-       avp->av_config.av_fixed_rateset = IEEE80211_FIXED_RATE_NONE;
-       avp->av_config.av_fixed_retryset = 0x03030303;
-
-       return 0;
-}
-
-int ath_vap_detach(struct ath_softc *sc, int if_id)
-{
-       struct ath_hal *ah = sc->sc_ah;
-       struct ath_vap *avp;
-
-       avp = sc->sc_vaps[if_id];
-       if (avp == NULL) {
-               DPRINTF(sc, ATH_DBG_FATAL, "%s: invalid interface id %u\n",
-                       __func__, if_id);
-               return -EINVAL;
-       }
-
-       /*
-        * Quiesce the hardware while we remove the vap.  In
-        * particular we need to reclaim all references to the
-        * vap state by any frames pending on the tx queues.
-        *
-        * XXX can we do this w/o affecting other vap's?
-        */
-       ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */
-       ath_draintxq(sc, false);        /* stop xmit side */
-       ath_stoprecv(sc);       /* stop recv side */
-       ath_flushrecv(sc);      /* flush recv queue */
-
-       kfree(avp);
-       sc->sc_vaps[if_id] = NULL;
-       sc->sc_nvaps--;
-
-       return 0;
-}
-
-int ath_vap_config(struct ath_softc *sc,
-       int if_id, struct ath_vap_config *if_config)
-{
-       struct ath_vap *avp;
-
-       if (if_id >= ATH_BCBUF) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "%s: Invalid interface id = %u\n", __func__, if_id);
-               return -EINVAL;
-       }
-
-       avp = sc->sc_vaps[if_id];
-       ASSERT(avp != NULL);
-
-       if (avp)
-               memcpy(&avp->av_config, if_config, sizeof(avp->av_config));
-
-       return 0;
-}
-
 /********/
 /* Core */
 /********/
@@ -727,16 +597,6 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
        DPRINTF(sc, ATH_DBG_CONFIG, "%s: mode %d\n",
                __func__, sc->sc_ah->ah_opmode);
 
-       /*
-        * Stop anything previously setup.  This is safe
-        * whether this is the first time through or not.
-        */
-       ath_stop(sc);
-
-       /* Initialize chanmask selection */
-       sc->sc_tx_chainmask = ah->ah_caps.tx_chainmask;
-       sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask;
-
        /* Reset SERDES registers */
        ath9k_hw_configpcipowersave(ah, 0);
 
@@ -762,6 +622,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
                goto done;
        }
        spin_unlock_bh(&sc->sc_resetlock);
+
        /*
         * This is needed only to setup initial state
         * but it's best done after a reset.
@@ -781,6 +642,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
                error = -EIO;
                goto done;
        }
+
        /* Setup our intr mask. */
        sc->sc_imask = ATH9K_INT_RX | ATH9K_INT_TX
                | ATH9K_INT_RXEOL | ATH9K_INT_RXORN
@@ -810,30 +672,60 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
            (sc->sc_ah->ah_opmode == ATH9K_M_STA) &&
            !sc->sc_config.swBeaconProcess)
                sc->sc_imask |= ATH9K_INT_TIM;
-       /*
-        *  Don't enable interrupts here as we've not yet built our
-        *  vap and node data structures, which will be needed as soon
-        *  as we start receiving.
-        */
+
        ath_setcurmode(sc, ath_chan2mode(initial_chan));
 
-       /* XXX: we must make sure h/w is ready and clear invalid flag
-        * before turning on interrupt. */
        sc->sc_flags &= ~SC_OP_INVALID;
+
+       /* Disable BMISS interrupt when we're not associated */
+       sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
+       ath9k_hw_set_interrupts(sc->sc_ah,sc->sc_imask);
+
+       ieee80211_wake_queues(sc->hw);
 done:
        return error;
 }
 
+void ath_stop(struct ath_softc *sc)
+{
+       struct ath_hal *ah = sc->sc_ah;
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "%s: Cleaning up\n", __func__);
+
+       ieee80211_stop_queues(sc->hw);
+
+       /* make sure h/w will not generate any interrupt
+        * before setting the invalid flag. */
+       ath9k_hw_set_interrupts(ah, 0);
+
+       if (!(sc->sc_flags & SC_OP_INVALID)) {
+               ath_draintxq(sc, false);
+               ath_stoprecv(sc);
+               ath9k_hw_phy_disable(ah);
+       } else
+               sc->sc_rxlink = NULL;
+
+#ifdef CONFIG_RFKILL
+       if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+               cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
+#endif
+       /* disable HAL and put h/w to sleep */
+       ath9k_hw_disable(sc->sc_ah);
+       ath9k_hw_configpcipowersave(sc->sc_ah, 1);
+
+       sc->sc_flags |= SC_OP_INVALID;
+}
+
 int ath_reset(struct ath_softc *sc, bool retry_tx)
 {
        struct ath_hal *ah = sc->sc_ah;
        int status;
        int error = 0;
 
-       ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */
-       ath_draintxq(sc, retry_tx);     /* stop xmit */
-       ath_stoprecv(sc);               /* stop recv */
-       ath_flushrecv(sc);              /* flush recv queue */
+       ath9k_hw_set_interrupts(ah, 0);
+       ath_draintxq(sc, retry_tx);
+       ath_stoprecv(sc);
+       ath_flushrecv(sc);
 
        /* Reset chip */
        spin_lock_bh(&sc->sc_resetlock);
@@ -848,7 +740,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
        }
        spin_unlock_bh(&sc->sc_resetlock);
 
-       if (ath_startrecv(sc) != 0)     /* restart recv */
+       if (ath_startrecv(sc) != 0)
                DPRINTF(sc, ATH_DBG_FATAL,
                        "%s: unable to start recv logic\n", __func__);
 
@@ -881,29 +773,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
        return error;
 }
 
-int ath_suspend(struct ath_softc *sc)
-{
-       struct ath_hal *ah = sc->sc_ah;
-
-       /* No I/O if device has been surprise removed */
-       if (sc->sc_flags & SC_OP_INVALID)
-               return -EIO;
-
-       /* Shut off the interrupt before setting sc->sc_invalid to '1' */
-       ath9k_hw_set_interrupts(ah, 0);
-
-       /* XXX: we must make sure h/w will not generate any interrupt
-        * before setting the invalid flag. */
-       sc->sc_flags |= SC_OP_INVALID;
-
-       /* disable HAL and put h/w to sleep */
-       ath9k_hw_disable(sc->sc_ah);
-
-       ath9k_hw_configpcipowersave(sc->sc_ah, 1);
-
-       return 0;
-}
-
 /* Interrupt handler.  Most of the actual processing is deferred.
  * It's the caller's responsibility to ensure the chip is awake. */
 
@@ -1071,11 +940,9 @@ int ath_init(u16 devid, struct ath_softc *sc)
 
        /* XXX: hardware will not be ready until ath_open() being called */
        sc->sc_flags |= SC_OP_INVALID;
-
        sc->sc_debug = DBG_DEFAULT;
-       DPRINTF(sc, ATH_DBG_CONFIG, "%s: devid 0x%x\n", __func__, devid);
 
-       /* Initialize tasklet */
+       spin_lock_init(&sc->sc_resetlock);
        tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
        tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
                     (unsigned long)sc);
@@ -1088,8 +955,6 @@ int ath_init(u16 devid, struct ath_softc *sc)
        /* XXX assert csz is non-zero */
        sc->sc_cachelsz = csz << 2;     /* convert to bytes */
 
-       spin_lock_init(&sc->sc_resetlock);
-
        ah = ath9k_hw_attach(devid, sc, sc->mem, &status);
        if (ah == NULL) {
                DPRINTF(sc, ATH_DBG_FATAL,
@@ -1100,10 +965,6 @@ int ath_init(u16 devid, struct ath_softc *sc)
        }
        sc->sc_ah = ah;
 
-       /* Initializes the noise floor to a reasonable default value.
-        * Later on this will be updated during ANI processing. */
-       sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR;
-
        /* Get the hardware key cache size. */
        sc->sc_keymax = ah->ah_caps.keycache_size;
        if (sc->sc_keymax > ATH_KEYMAX) {
@@ -1131,17 +992,14 @@ int ath_init(u16 devid, struct ath_softc *sc)
                set_bit(i + 64, sc->sc_keymap);
                set_bit(i + 32 + 64, sc->sc_keymap);
        }
-       /*
-        * Collect the channel list using the default country
-        * code and including outdoor channels.  The 802.11 layer
-        * is resposible for filtering this list based on settings
-        * like the phy mode.
-        */
+
+       /* Collect the channel list using the default country code */
+
        error = ath_setup_channels(sc);
        if (error)
                goto bad;
 
-       /* default to STA mode */
+       /* default to MONITOR mode */
        sc->sc_ah->ah_opmode = ATH9K_M_MONITOR;
 
        /* Setup rate tables */
@@ -1211,6 +1069,10 @@ int ath_init(u16 devid, struct ath_softc *sc)
                goto bad2;
        }
 
+       /* Initializes the noise floor to a reasonable default value.
+        * Later on this will be updated during ANI processing. */
+
+       sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR;
        setup_timer(&sc->sc_ani.timer, ath_ani_calibrate, (unsigned long)sc);
 
        sc->sc_rc = ath_rate_attach(ah);
@@ -1271,6 +1133,7 @@ int ath_init(u16 devid, struct ath_softc *sc)
                ATH_SET_VAP_BSSID_MASK(sc->sc_bssidmask);
                ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
        }
+
        sc->sc_slottime = ATH9K_SLOT_TIME_9;    /* default to short slot time */
 
        /* initialize beacon slots */
@@ -1285,6 +1148,22 @@ int ath_init(u16 devid, struct ath_softc *sc)
        ath_slow_ant_div_init(&sc->sc_antdiv, sc, 0x127);
 #endif
 
+       /* setup channels and rates */
+
+       sc->sbands[IEEE80211_BAND_2GHZ].channels =
+               sc->channels[IEEE80211_BAND_2GHZ];
+       sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
+               sc->rates[IEEE80211_BAND_2GHZ];
+       sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
+
+       if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) {
+               sc->sbands[IEEE80211_BAND_5GHZ].channels =
+                       sc->channels[IEEE80211_BAND_5GHZ];
+               sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
+                       sc->rates[IEEE80211_BAND_5GHZ];
+               sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
+       }
+
        return 0;
 bad2:
        /* cleanup tx queues */
@@ -1294,128 +1173,39 @@ bad2:
 bad:
        if (ah)
                ath9k_hw_detach(ah);
-       return error;
-}
-
-void ath_deinit(struct ath_softc *sc)
-{
-       struct ath_hal *ah = sc->sc_ah;
-       int i;
-
-       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);
-       ath_rate_detach(sc->sc_rc);
-       /* cleanup tx queues */
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
-               if (ATH_TXQ_SETUP(sc, i))
-                       ath_tx_cleanupq(sc, &sc->sc_txq[i]);
-       ath9k_hw_detach(ah);
+       return error;
 }
 
 /*******************/
 /* Node Management */
 /*******************/
 
-struct ath_node *ath_node_attach(struct ath_softc *sc, u8 *addr, int if_id)
+void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
 {
-       struct ath_vap *avp;
        struct ath_node *an;
-       DECLARE_MAC_BUF(mac);
-
-       avp = sc->sc_vaps[if_id];
-       ASSERT(avp != NULL);
 
-       /* mac80211 sta_notify callback is from an IRQ context, so no sleep */
-       an = kmalloc(sizeof(struct ath_node), GFP_ATOMIC);
-       if (an == NULL)
-               return NULL;
-       memset(an, 0, sizeof(*an));
+       an = (struct ath_node *)sta->drv_priv;
 
-       an->an_sc = sc;
-       memcpy(an->an_addr, addr, ETH_ALEN);
-       atomic_set(&an->an_refcnt, 1);
+       if (sc->sc_flags & SC_OP_TXAGGR)
+               ath_tx_node_init(sc, an);
 
-       /* set up per-node tx/rx state */
-       ath_tx_node_init(sc, an);
-       ath_rx_node_init(sc, an);
+       an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
+                            sta->ht_cap.ampdu_factor);
+       an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
 
        ath_chainmask_sel_init(sc, an);
        ath_chainmask_sel_timerstart(&an->an_chainmask_sel);
-       list_add(&an->list, &sc->node_list);
-
-       return an;
 }
 
-void ath_node_detach(struct ath_softc *sc, struct ath_node *an, bool bh_flag)
+void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
 {
-       unsigned long flags;
-
-       DECLARE_MAC_BUF(mac);
+       struct ath_node *an = (struct ath_node *)sta->drv_priv;
 
        ath_chainmask_sel_timerstop(&an->an_chainmask_sel);
-       an->an_flags |= ATH_NODE_CLEAN;
-       ath_tx_node_cleanup(sc, an, bh_flag);
-       ath_rx_node_cleanup(sc, an);
-
-       ath_tx_node_free(sc, an);
-       ath_rx_node_free(sc, an);
-
-       spin_lock_irqsave(&sc->node_lock, flags);
-
-       list_del(&an->list);
-
-       spin_unlock_irqrestore(&sc->node_lock, flags);
 
-       kfree(an);
-}
-
-/* Finds a node and increases the refcnt if found */
-
-struct ath_node *ath_node_get(struct ath_softc *sc, u8 *addr)
-{
-       struct ath_node *an = NULL, *an_found = NULL;
-
-       if (list_empty(&sc->node_list)) /* FIXME */
-               goto out;
-       list_for_each_entry(an, &sc->node_list, list) {
-               if (!compare_ether_addr(an->an_addr, addr)) {
-                       atomic_inc(&an->an_refcnt);
-                       an_found = an;
-                       break;
-               }
-       }
-out:
-       return an_found;
-}
-
-/* Decrements the refcnt and if it drops to zero, detach the node */
-
-void ath_node_put(struct ath_softc *sc, struct ath_node *an, bool bh_flag)
-{
-       if (atomic_dec_and_test(&an->an_refcnt))
-               ath_node_detach(sc, an, bh_flag);
-}
-
-/* Finds a node, doesn't increment refcnt. Caller must hold sc->node_lock */
-struct ath_node *ath_node_find(struct ath_softc *sc, u8 *addr)
-{
-       struct ath_node *an = NULL, *an_found = NULL;
-
-       if (list_empty(&sc->node_list))
-               return NULL;
-
-       list_for_each_entry(an, &sc->node_list, list)
-               if (!compare_ether_addr(an->an_addr, addr)) {
-                       an_found = an;
-                       break;
-               }
-
-       return an_found;
+       if (sc->sc_flags & SC_OP_TXAGGR)
+               ath_tx_node_cleanup(sc, an);
 }
 
 /*
@@ -1436,11 +1226,8 @@ void ath_newassoc(struct ath_softc *sc,
                for (tidno = 0; tidno < WME_NUM_TID; tidno++) {
                        if (sc->sc_flags & SC_OP_TXAGGR)
                                ath_tx_aggr_teardown(sc, an, tidno);
-                       if (sc->sc_flags & SC_OP_RXAGGR)
-                               ath_rx_aggr_teardown(sc, an, tidno);
                }
        }
-       an->an_flags = 0;
 }
 
 /**************/
@@ -1491,27 +1278,6 @@ void ath_update_txpow(struct ath_softc *sc)
        }
 }
 
-/* Return the current country and domain information */
-void ath_get_currentCountry(struct ath_softc *sc,
-       struct ath9k_country_entry *ctry)
-{
-       ath9k_regd_get_current_country(sc->sc_ah, ctry);
-
-       /* If HAL not specific yet, since it is band dependent,
-        * use the one we passed in. */
-       if (ctry->countryCode == CTRY_DEFAULT) {
-               ctry->iso[0] = 0;
-               ctry->iso[1] = 0;
-       } else if (ctry->iso[0] && ctry->iso[1]) {
-               if (!ctry->iso[2]) {
-                       if (ath_outdoor)
-                               ctry->iso[2] = 'O';
-                       else
-                               ctry->iso[2] = 'I';
-               }
-       }
-}
-
 /**************************/
 /* Slow Antenna Diversity */
 /**************************/
index cb3e61e57c4d9a82218c6c7220fdef0f26fa3e77..69e8d3e4113113929963a75a2b04f95a8776f381 100644 (file)
@@ -84,9 +84,6 @@ struct ath_node;
 #define TSF_TO_TU(_h,_l) \
        ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
 
-#define ATH9K_BH_STATUS_INTACT         0
-#define ATH9K_BH_STATUS_CHANGE         1
-
 #define        ATH_TXQ_SETUP(sc, i)        ((sc)->sc_txqsetup & (1<<i))
 
 static inline unsigned long get_timestamp(void)
@@ -209,6 +206,7 @@ struct ath_buf_state {
        struct ath_rc_series bfs_rcs[4];        /* rate series */
        u32 bf_type;                            /* BUF_* (enum buffer_type) */
        /* key type use to encrypt this frame */
+       u32 bfs_keyix;
        enum ath9k_key_type bfs_keytype;
 };
 
@@ -219,6 +217,7 @@ struct ath_buf_state {
 #define bf_seqno               bf_state.bfs_seqno
 #define bf_tidno               bf_state.bfs_tidno
 #define bf_rcs                 bf_state.bfs_rcs
+#define bf_keyix                bf_state.bfs_keyix
 #define bf_keytype             bf_state.bfs_keytype
 #define bf_isdata(bf)          (bf->bf_state.bf_type & BUF_DATA)
 #define bf_isaggr(bf)          (bf->bf_state.bf_type & BUF_AGGR)
@@ -244,7 +243,6 @@ struct ath_buf {
        struct ath_buf *bf_next;        /* next subframe in the aggregate */
        struct ath_buf *bf_rifslast;    /* last buf for RIFS burst */
        void *bf_mpdu;                  /* enclosing frame structure */
-       void *bf_node;                  /* pointer to the node */
        struct ath_desc *bf_desc;       /* virtual addr of desc */
        dma_addr_t bf_daddr;            /* physical addr of desc */
        dma_addr_t bf_buf_addr;         /* physical addr of data buffer */
@@ -306,15 +304,7 @@ void ath_descdma_cleanup(struct ath_softc *sc,
 
 #define ATH_MAX_ANTENNA          3
 #define ATH_RXBUF                512
-#define ATH_RX_TIMEOUT           40      /* 40 milliseconds */
 #define WME_NUM_TID              16
-#define IEEE80211_BAR_CTL_TID_M  0xF000  /* tid mask */
-#define IEEE80211_BAR_CTL_TID_S  12      /* tid shift */
-
-enum ATH_RX_TYPE {
-       ATH_RX_NON_CONSUMED = 0,
-       ATH_RX_CONSUMED
-};
 
 /* per frame rx status block */
 struct ath_recv_status {
@@ -348,49 +338,18 @@ struct ath_rxbuf {
        struct ath_recv_status rx_status;       /* cached rx status */
 };
 
-/* Per-TID aggregate receiver state for a node */
-struct ath_arx_tid {
-       struct ath_node *an;
-       struct ath_rxbuf *rxbuf;        /* re-ordering buffer */
-       struct timer_list timer;
-       spinlock_t tidlock;
-       int baw_head;                   /* seq_next at head */
-       int baw_tail;                   /* tail of block-ack window */
-       int seq_reset;                  /* need to reset start sequence */
-       int addba_exchangecomplete;
-       u16 seq_next;                   /* next expected sequence */
-       u16 baw_size;                   /* block-ack window size */
-};
-
-/* Per-node receiver aggregate state */
-struct ath_arx {
-       struct ath_arx_tid tid[WME_NUM_TID];
-};
-
 int ath_startrecv(struct ath_softc *sc);
 bool ath_stoprecv(struct ath_softc *sc);
 void ath_flushrecv(struct ath_softc *sc);
 u32 ath_calcrxfilter(struct ath_softc *sc);
-void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an);
-void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an);
-void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
 void ath_handle_rx_intr(struct ath_softc *sc);
 int ath_rx_init(struct ath_softc *sc, int nbufs);
 void ath_rx_cleanup(struct ath_softc *sc);
 int ath_rx_tasklet(struct ath_softc *sc, int flush);
-int ath_rx_input(struct ath_softc *sc,
-                struct ath_node *node,
-                int is_ampdu,
-                struct sk_buff *skb,
-                struct ath_recv_status *rx_status,
-                enum ATH_RX_TYPE *status);
 int _ath_rx_indicate(struct ath_softc *sc,
                     struct sk_buff *skb,
                     struct ath_recv_status *status,
                     u16 keyix);
-int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb,
-                   struct ath_recv_status *status);
-
 /******/
 /* TX */
 /******/
@@ -419,12 +378,6 @@ int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb,
 #define WME_AC_VO               3 /* voice */
 #define WME_NUM_AC              4
 
-enum ATH_SM_PWRSAV{
-       ATH_SM_ENABLE,
-       ATH_SM_PWRSAV_STATIC,
-       ATH_SM_PWRSAV_DYNAMIC,
-};
-
 /*
  * Data transmit queue state.  One of these exists for each
  * hardware transmit queue.  Packets sent to us from above
@@ -444,9 +397,6 @@ struct ath_txq {
        u8 axq_aggr_depth;              /* aggregates queued */
        u32 axq_totalqueued;            /* total ever queued */
 
-       /* count to determine if descriptor should generate int on this txq. */
-       u32 axq_intrcnt;
-
        bool stopped;                   /* Is mac80211 queue stopped ? */
        struct ath_buf *axq_linkbuf;    /* virtual addr of last buffer*/
 
@@ -460,6 +410,10 @@ struct ath_txq {
        struct list_head axq_acq;
 };
 
+#define AGGR_CLEANUP         BIT(1)
+#define AGGR_ADDBA_COMPLETE  BIT(2)
+#define AGGR_ADDBA_PROGRESS  BIT(3)
+
 /* per TID aggregate tx state for a destination */
 struct ath_atx_tid {
        struct list_head list;          /* round-robin tid entry */
@@ -475,9 +429,7 @@ struct ath_atx_tid {
        int baw_tail;                   /* next unused tx buffer slot */
        int sched;
        int paused;
-       int cleanup_inprogress;
-       u32 addba_exchangecomplete:1;
-       int32_t addba_exchangeinprogress;
+       u8 state;
        int addba_exchangeattempts;
 };
 
@@ -498,24 +450,8 @@ struct ath_atx {
 
 /* per-frame tx control block */
 struct ath_tx_control {
-       struct ath_node *an;
+       struct ath_txq *txq;
        int if_id;
-       int qnum;
-       u32 ht:1;
-       u32 ps:1;
-       u32 use_minrate:1;
-       enum ath9k_pkt_type atype;
-       enum ath9k_key_type keytype;
-       u32 flags;
-       u16 seqno;
-       u16 tidno;
-       u16 txpower;
-       u16 frmlen;
-       u32 keyix;
-       int min_rate;
-       int mcast_rate;
-       struct ath_softc *dev;
-       dma_addr_t dmacontext;
 };
 
 /* per frame tx status block */
@@ -550,33 +486,29 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx);
 void ath_tx_draintxq(struct ath_softc *sc,
                     struct ath_txq *txq, bool retry_tx);
 void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
-void ath_tx_node_cleanup(struct ath_softc *sc,
-                        struct ath_node *an, bool bh_flag);
+void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
 void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an);
 void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
 int ath_tx_init(struct ath_softc *sc, int nbufs);
 int ath_tx_cleanup(struct ath_softc *sc);
 int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
+struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
 int ath_txq_update(struct ath_softc *sc, int qnum,
                   struct ath9k_tx_queue_info *q);
-int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb);
+int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
+                struct ath_tx_control *txctl);
 void ath_tx_tasklet(struct ath_softc *sc);
 u32 ath_txq_depth(struct ath_softc *sc, int qnum);
 u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum);
 void ath_notify_txq_status(struct ath_softc *sc, u16 queue_depth);
 void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
-                    struct ath_xmit_status *tx_status, struct ath_node *an);
+                    struct ath_xmit_status *tx_status);
 void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb);
 
 /**********************/
 /* Node / Aggregation */
 /**********************/
 
-/* indicates the node is clened up */
-#define ATH_NODE_CLEAN          0x1
-/* indicates the node is 80211 power save */
-#define ATH_NODE_PWRSAVE        0x2
-
 #define ADDBA_EXCHANGE_ATTEMPTS    10
 #define ATH_AGGR_DELIM_SZ          4   /* delimiter size   */
 #define ATH_AGGR_MINPLEN           256 /* in bytes, minimum packet length */
@@ -588,6 +520,7 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb);
 #define IEEE80211_SEQ_SEQ_SHIFT    4
 #define IEEE80211_SEQ_MAX          4096
 #define IEEE80211_MIN_AMPDU_BUF    0x8
+#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
 
 /* return whether a bit at index _n in bitmap _bm is set
  * _sz is the size of the bitmap  */
@@ -618,14 +551,6 @@ enum ATH_AGGR_STATUS {
        ATH_AGGR_8K_LIMITED,
 };
 
-enum ATH_AGGR_CHECK {
-       AGGR_NOT_REQUIRED,
-       AGGR_REQUIRED,
-       AGGR_CLEANUP_PROGRESS,
-       AGGR_EXCHANGE_PROGRESS,
-       AGGR_EXCHANGE_DONE
-};
-
 struct aggr_rifs_param {
        int param_max_frames;
        int param_max_len;
@@ -637,51 +562,30 @@ struct aggr_rifs_param {
 /* Per-node aggregation state */
 struct ath_node_aggr {
        struct ath_atx tx;      /* node transmit state */
-       struct ath_arx rx;      /* node receive state */
 };
 
 /* driver-specific node state */
 struct ath_node {
-       struct list_head list;
        struct ath_softc *an_sc;
-       atomic_t an_refcnt;
        struct ath_chainmask_sel an_chainmask_sel;
        struct ath_node_aggr an_aggr;
-       u8 an_smmode; /* SM Power save mode */
-       u8 an_flags;
-       u8 an_addr[ETH_ALEN];
+       u16 maxampdu;
+       u8 mpdudensity;
 };
 
 void ath_tx_resume_tid(struct ath_softc *sc,
        struct ath_atx_tid *tid);
-enum ATH_AGGR_CHECK ath_tx_aggr_check(struct ath_softc *sc,
-       struct ath_node *an, u8 tidno);
+bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
 void ath_tx_aggr_teardown(struct ath_softc *sc,
        struct ath_node *an, u8 tidno);
-void ath_rx_aggr_teardown(struct ath_softc *sc,
-       struct ath_node *an, u8 tidno);
-int ath_rx_aggr_start(struct ath_softc *sc,
-                     const u8 *addr,
-                     u16 tid,
-                     u16 *ssn);
-int ath_rx_aggr_stop(struct ath_softc *sc,
-                    const u8 *addr,
-                    u16 tid);
-int ath_tx_aggr_start(struct ath_softc *sc,
-                     const u8 *addr,
-                     u16 tid,
-                     u16 *ssn);
-int ath_tx_aggr_stop(struct ath_softc *sc,
-                    const u8 *addr,
-                    u16 tid);
+int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+                     u16 tid, u16 *ssn);
+int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
+void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
 void ath_newassoc(struct ath_softc *sc,
        struct ath_node *node, int isnew, int isuapsd);
-struct ath_node *ath_node_attach(struct ath_softc *sc,
-       u8 addr[ETH_ALEN], int if_id);
-void ath_node_detach(struct ath_softc *sc, struct ath_node *an, bool bh_flag);
-struct ath_node *ath_node_get(struct ath_softc *sc, u8 addr[ETH_ALEN]);
-void ath_node_put(struct ath_softc *sc, struct ath_node *an, bool bh_flag);
-struct ath_node *ath_node_find(struct ath_softc *sc, u8 *addr);
+void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta);
+void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta);
 
 /*******************/
 /* Beacon Handling */
@@ -745,23 +649,14 @@ struct ath_vap_config {
 
 /* driver-specific vap state */
 struct ath_vap {
-       struct ieee80211_vif *av_if_data;
+       int av_bslot;                   /* beacon slot index */
        enum ath9k_opmode av_opmode;    /* VAP operational mode */
        struct ath_buf *av_bcbuf;       /* beacon buffer */
        struct ath_tx_control av_btxctl;  /* txctl information for beacon */
-       int av_bslot;                   /* beacon slot index */
        struct ath_vap_config av_config;/* vap configuration parameters*/
        struct ath_rate_node *rc_node;
 };
 
-int ath_vap_attach(struct ath_softc *sc,
-                  int if_id,
-                  struct ieee80211_vif *if_data,
-                  enum ath9k_opmode opmode);
-int ath_vap_detach(struct ath_softc *sc, int if_id);
-int ath_vap_config(struct ath_softc *sc,
-                  int if_id, struct ath_vap_config *if_config);
-
 /*********************/
 /* Antenna diversity */
 /*********************/
@@ -919,8 +814,6 @@ enum RATE_TYPE {
 
 struct ath_ht_info {
        enum ath9k_ht_macmode tx_chan_width;
-       u16 maxampdu;
-       u8 mpdudensity;
        u8 ext_chan_offset;
 };
 
@@ -971,14 +864,13 @@ struct ath_softc {
 
        u8 sc_nbcnvaps;                 /* # of vaps sending beacons */
        u16 sc_nvaps;                   /* # of active virtual ap's */
-       struct ath_vap *sc_vaps[ATH_BCBUF];
+       struct ieee80211_vif *sc_vaps[ATH_BCBUF];
 
        u8 sc_mcastantenna;
        u8 sc_defant;                   /* current default antenna */
        u8 sc_rxotherant;               /* rx's on non-default antenna */
 
        struct ath9k_node_stats sc_halstats; /* station-mode rssi stats */
-       struct list_head node_list;
        struct ath_ht_info sc_ht_info;
        enum ath9k_ht_extprotspacing sc_ht_extprotspacing;
 
@@ -1007,7 +899,6 @@ struct ath_softc {
        struct ath_txq sc_txq[ATH9K_NUM_TX_QUEUES];
        struct ath_descdma sc_txdma;
        u32 sc_txqsetup;
-       u32 sc_txintrperiod;    /* tx interrupt batching */
        int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */
        u16 seq_no; /* TX sequence number */
 
@@ -1040,7 +931,6 @@ struct ath_softc {
        spinlock_t sc_rxbuflock;
        spinlock_t sc_txbuflock;
        spinlock_t sc_resetlock;
-       spinlock_t node_lock;
 
        /* LEDs */
        struct ath_led radio_led;
@@ -1056,9 +946,8 @@ struct ath_softc {
 };
 
 int ath_init(u16 devid, struct ath_softc *sc);
-void ath_deinit(struct ath_softc *sc);
 int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan);
-int ath_suspend(struct ath_softc *sc);
+void ath_stop(struct ath_softc *sc);
 irqreturn_t ath_isr(int irq, void *dev);
 int ath_reset(struct ath_softc *sc, bool retry_tx);
 int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan);
@@ -1077,8 +966,6 @@ int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
 void ath_setslottime(struct ath_softc *sc);
 void ath_update_txpow(struct ath_softc *sc);
 int ath_cabq_update(struct ath_softc *);
-void ath_get_currentCountry(struct ath_softc *sc,
-       struct ath9k_country_entry *ctry);
 u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp);
 
 #endif /* CORE_H */
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c
new file mode 100644 (file)
index 0000000..f5fd03c
--- /dev/null
@@ -0,0 +1,1605 @@
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "core.h"
+#include "hw.h"
+#include "reg.h"
+#include "phy.h"
+
+static void ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
+                                     u32 reg, u32 mask,
+                                     u32 shift, u32 val)
+{
+       u32 regVal;
+
+       regVal = REG_READ(ah, reg) & ~mask;
+       regVal |= (val << shift) & mask;
+
+       REG_WRITE(ah, reg, regVal);
+
+       if (ah->ah_config.analog_shiftreg)
+               udelay(100);
+
+       return;
+}
+
+static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
+{
+
+       if (fbin == AR5416_BCHAN_UNUSED)
+               return fbin;
+
+       return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
+}
+
+static inline int16_t ath9k_hw_interpolate(u16 target,
+                                          u16 srcLeft, u16 srcRight,
+                                          int16_t targetLeft,
+                                          int16_t targetRight)
+{
+       int16_t rv;
+
+       if (srcRight == srcLeft) {
+               rv = targetLeft;
+       } else {
+               rv = (int16_t) (((target - srcLeft) * targetRight +
+                                (srcRight - target) * targetLeft) /
+                               (srcRight - srcLeft));
+       }
+       return rv;
+}
+
+static inline bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList,
+                                                 u16 listSize, u16 *indexL,
+                                                 u16 *indexR)
+{
+       u16 i;
+
+       if (target <= pList[0]) {
+               *indexL = *indexR = 0;
+               return true;
+       }
+       if (target >= pList[listSize - 1]) {
+               *indexL = *indexR = (u16) (listSize - 1);
+               return true;
+       }
+
+       for (i = 0; i < listSize - 1; i++) {
+               if (pList[i] == target) {
+                       *indexL = *indexR = i;
+                       return true;
+               }
+               if (target < pList[i + 1]) {
+                       *indexL = i;
+                       *indexR = (u16) (i + 1);
+                       return false;
+               }
+       }
+       return false;
+}
+
+static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
+{
+       (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
+
+       if (!ath9k_hw_wait(ah,
+                          AR_EEPROM_STATUS_DATA,
+                          AR_EEPROM_STATUS_DATA_BUSY |
+                          AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
+               return false;
+       }
+
+       *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
+                  AR_EEPROM_STATUS_DATA_VAL);
+
+       return true;
+}
+
+static int ath9k_hw_flash_map(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+
+       ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX);
+
+       if (!ahp->ah_cal_mem) {
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "%s: cannot remap eeprom region \n", __func__);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off, u16 *data)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+
+       *data = ioread16(ahp->ah_cal_mem + off);
+
+       return true;
+}
+
+static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, u32 off, u16 *data)
+{
+       if (ath9k_hw_use_flash(ah))
+               return ath9k_hw_flash_read(ah, off, data);
+       else
+               return ath9k_hw_eeprom_read(ah, off, data);
+}
+
+static bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416_eeprom *eep = &ahp->ah_eeprom;
+       u16 *eep_data;
+       int addr, ar5416_eep_start_loc = 0;
+
+       if (!ath9k_hw_use_flash(ah)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "%s: Reading from EEPROM, not flash\n", __func__);
+               ar5416_eep_start_loc = 256;
+       }
+
+       if (AR_SREV_9100(ah))
+               ar5416_eep_start_loc = 256;
+
+       eep_data = (u16 *)eep;
+
+       for (addr = 0; addr < sizeof(struct ar5416_eeprom) / sizeof(u16); addr++) {
+               if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
+                                        eep_data)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                               "%s: Unable to read eeprom region \n",
+                               __func__);
+                       return false;
+               }
+               eep_data++;
+       }
+       return true;
+}
+
+static int ath9k_hw_check_eeprom(struct ath_hal *ah)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416_eeprom *eep =
+               (struct ar5416_eeprom *) &ahp->ah_eeprom;
+       u16 *eepdata, temp, magic, magic2;
+       u32 sum = 0, el;
+       bool need_swap = false;
+       int i, addr, size;
+
+       if (!ath9k_hw_use_flash(ah)) {
+               if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
+                                        &magic)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                               "%s: Reading Magic # failed\n", __func__);
+                       return false;
+               }
+
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "%s: Read Magic = 0x%04X\n",
+                        __func__, magic);
+
+               if (magic != AR5416_EEPROM_MAGIC) {
+                       magic2 = swab16(magic);
+
+                       if (magic2 == AR5416_EEPROM_MAGIC) {
+                               size = sizeof(struct ar5416_eeprom);
+                               need_swap = true;
+                               eepdata = (u16 *) (&ahp->ah_eeprom);
+
+                               for (addr = 0; addr < size / sizeof(u16); addr++) {
+                                       temp = swab16(*eepdata);
+                                       *eepdata = temp;
+                                       eepdata++;
+
+                                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                               "0x%04X  ", *eepdata);
+
+                                       if (((addr + 1) % 6) == 0)
+                                               DPRINTF(ah->ah_sc,
+                                                       ATH_DBG_EEPROM, "\n");
+                               }
+                       } else {
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "Invalid EEPROM Magic. "
+                                       "endianness mismatch.\n");
+                               return -EINVAL;
+                       }
+               }
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
+               need_swap ? "True" : "False");
+
+       if (need_swap)
+               el = swab16(ahp->ah_eeprom.baseEepHeader.length);
+       else
+               el = ahp->ah_eeprom.baseEepHeader.length;
+
+       if (el > sizeof(struct ar5416_eeprom))
+               el = sizeof(struct ar5416_eeprom) / sizeof(u16);
+       else
+               el = el / sizeof(u16);
+
+       eepdata = (u16 *)(&ahp->ah_eeprom);
+
+       for (i = 0; i < el; i++)
+               sum ^= *eepdata++;
+
+       if (need_swap) {
+               u32 integer, j;
+               u16 word;
+
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "EEPROM Endianness is not native.. Changing \n");
+
+               word = swab16(eep->baseEepHeader.length);
+               eep->baseEepHeader.length = word;
+
+               word = swab16(eep->baseEepHeader.checksum);
+               eep->baseEepHeader.checksum = word;
+
+               word = swab16(eep->baseEepHeader.version);
+               eep->baseEepHeader.version = word;
+
+               word = swab16(eep->baseEepHeader.regDmn[0]);
+               eep->baseEepHeader.regDmn[0] = word;
+
+               word = swab16(eep->baseEepHeader.regDmn[1]);
+               eep->baseEepHeader.regDmn[1] = word;
+
+               word = swab16(eep->baseEepHeader.rfSilent);
+               eep->baseEepHeader.rfSilent = word;
+
+               word = swab16(eep->baseEepHeader.blueToothOptions);
+               eep->baseEepHeader.blueToothOptions = word;
+
+               word = swab16(eep->baseEepHeader.deviceCap);
+               eep->baseEepHeader.deviceCap = word;
+
+               for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
+                       struct modal_eep_header *pModal =
+                               &eep->modalHeader[j];
+                       integer = swab32(pModal->antCtrlCommon);
+                       pModal->antCtrlCommon = integer;
+
+                       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+                               integer = swab32(pModal->antCtrlChain[i]);
+                               pModal->antCtrlChain[i] = integer;
+                       }
+
+                       for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+                               word = swab16(pModal->spurChans[i].spurChan);
+                               pModal->spurChans[i].spurChan = word;
+                       }
+               }
+       }
+
+       if (sum != 0xffff || ar5416_get_eep_ver(ahp) != AR5416_EEP_VER ||
+           ar5416_get_eep_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+                       sum, ar5416_get_eep_ver(ahp));
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
+                                          u8 *pVpdList, u16 numIntercepts,
+                                          u8 *pRetVpdList)
+{
+       u16 i, k;
+       u8 currPwr = pwrMin;
+       u16 idxL = 0, idxR = 0;
+
+       for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
+               ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
+                                              numIntercepts, &(idxL),
+                                              &(idxR));
+               if (idxR < 1)
+                       idxR = 1;
+               if (idxL == numIntercepts - 1)
+                       idxL = (u16) (numIntercepts - 2);
+               if (pPwrList[idxL] == pPwrList[idxR])
+                       k = pVpdList[idxL];
+               else
+                       k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
+                                  (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
+                                 (pPwrList[idxR] - pPwrList[idxL]));
+               pRetVpdList[i] = (u8) k;
+               currPwr += 2;
+       }
+
+       return true;
+}
+
+static void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
+                               struct ath9k_channel *chan,
+                               struct cal_data_per_freq *pRawDataSet,
+                               u8 *bChans, u16 availPiers,
+                               u16 tPdGainOverlap, int16_t *pMinCalPower,
+                               u16 *pPdGainBoundaries, u8 *pPDADCValues,
+                               u16 numXpdGains)
+{
+       int i, j, k;
+       int16_t ss;
+       u16 idxL = 0, idxR = 0, numPiers;
+       static u8 vpdTableL[AR5416_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+       static u8 vpdTableR[AR5416_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+       static u8 vpdTableI[AR5416_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+
+       u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+       u8 minPwrT4[AR5416_NUM_PD_GAINS];
+       u8 maxPwrT4[AR5416_NUM_PD_GAINS];
+       int16_t vpdStep;
+       int16_t tmpVal;
+       u16 sizeCurrVpdTable, maxIndex, tgtIndex;
+       bool match;
+       int16_t minDelta = 0;
+       struct chan_centers centers;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+       for (numPiers = 0; numPiers < availPiers; numPiers++) {
+               if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
+                       break;
+       }
+
+       match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
+                                                            IS_CHAN_2GHZ(chan)),
+                                              bChans, numPiers, &idxL, &idxR);
+
+       if (match) {
+               for (i = 0; i < numXpdGains; i++) {
+                       minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
+                       maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
+                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                       pRawDataSet[idxL].pwrPdg[i],
+                                       pRawDataSet[idxL].vpdPdg[i],
+                                       AR5416_PD_GAIN_ICEPTS,
+                                       vpdTableI[i]);
+               }
+       } else {
+               for (i = 0; i < numXpdGains; i++) {
+                       pVpdL = pRawDataSet[idxL].vpdPdg[i];
+                       pPwrL = pRawDataSet[idxL].pwrPdg[i];
+                       pVpdR = pRawDataSet[idxR].vpdPdg[i];
+                       pPwrR = pRawDataSet[idxR].pwrPdg[i];
+
+                       minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
+
+                       maxPwrT4[i] =
+                               min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
+                                   pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
+
+
+                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               pPwrL, pVpdL,
+                                               AR5416_PD_GAIN_ICEPTS,
+                                               vpdTableL[i]);
+                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               pPwrR, pVpdR,
+                                               AR5416_PD_GAIN_ICEPTS,
+                                               vpdTableR[i]);
+
+                       for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
+                               vpdTableI[i][j] =
+                                       (u8)(ath9k_hw_interpolate((u16)
+                                            FREQ2FBIN(centers.
+                                                      synth_center,
+                                                      IS_CHAN_2GHZ
+                                                      (chan)),
+                                            bChans[idxL], bChans[idxR],
+                                            vpdTableL[i][j], vpdTableR[i][j]));
+                       }
+               }
+       }
+
+       *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
+
+       k = 0;
+
+       for (i = 0; i < numXpdGains; i++) {
+               if (i == (numXpdGains - 1))
+                       pPdGainBoundaries[i] =
+                               (u16)(maxPwrT4[i] / 2);
+               else
+                       pPdGainBoundaries[i] =
+                               (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
+
+               pPdGainBoundaries[i] =
+                       min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
+
+               if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
+                       minDelta = pPdGainBoundaries[0] - 23;
+                       pPdGainBoundaries[0] = 23;
+               } else {
+                       minDelta = 0;
+               }
+
+               if (i == 0) {
+                       if (AR_SREV_9280_10_OR_LATER(ah))
+                               ss = (int16_t)(0 - (minPwrT4[i] / 2));
+                       else
+                               ss = 0;
+               } else {
+                       ss = (int16_t)((pPdGainBoundaries[i - 1] -
+                                       (minPwrT4[i] / 2)) -
+                                      tPdGainOverlap + 1 + minDelta);
+               }
+               vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
+               vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+               while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+                       tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
+                       pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
+                       ss++;
+               }
+
+               sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+               tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
+                               (minPwrT4[i] / 2));
+               maxIndex = (tgtIndex < sizeCurrVpdTable) ?
+                       tgtIndex : sizeCurrVpdTable;
+
+               while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+                       pPDADCValues[k++] = vpdTableI[i][ss++];
+               }
+
+               vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
+                                   vpdTableI[i][sizeCurrVpdTable - 2]);
+               vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+               if (tgtIndex > maxIndex) {
+                       while ((ss <= tgtIndex) &&
+                              (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+                               tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
+                                                   (ss - maxIndex + 1) * vpdStep));
+                               pPDADCValues[k++] = (u8)((tmpVal > 255) ?
+                                                        255 : tmpVal);
+                               ss++;
+                       }
+               }
+       }
+
+       while (i < AR5416_PD_GAINS_IN_MASK) {
+               pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
+               i++;
+       }
+
+       while (k < AR5416_NUM_PDADC_VALUES) {
+               pPDADCValues[k] = pPDADCValues[k - 1];
+               k++;
+       }
+
+       return;
+}
+
+static void ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
+                                     struct ath9k_channel *chan,
+                                     struct cal_target_power_leg *powInfo,
+                                     u16 numChannels,
+                                     struct cal_target_power_leg *pNewPower,
+                                     u16 numRates, bool isExtTarget)
+{
+       struct chan_centers centers;
+       u16 clo, chi;
+       int i;
+       int matchIndex = -1, lowIndex = -1;
+       u16 freq;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
+
+       if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
+                                      IS_CHAN_2GHZ(chan))) {
+               matchIndex = 0;
+       } else {
+               for (i = 0; (i < numChannels) &&
+                            (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+                       if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
+                                                      IS_CHAN_2GHZ(chan))) {
+                               matchIndex = i;
+                               break;
+                       } else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
+                                                     IS_CHAN_2GHZ(chan))) &&
+                                  (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
+                                                     IS_CHAN_2GHZ(chan)))) {
+                               lowIndex = i - 1;
+                               break;
+                       }
+               }
+               if ((matchIndex == -1) && (lowIndex == -1))
+                       matchIndex = i - 1;
+       }
+
+       if (matchIndex != -1) {
+               *pNewPower = powInfo[matchIndex];
+       } else {
+               clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
+                                        IS_CHAN_2GHZ(chan));
+               chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
+                                        IS_CHAN_2GHZ(chan));
+
+               for (i = 0; i < numRates; i++) {
+                       pNewPower->tPow2x[i] =
+                               (u8)ath9k_hw_interpolate(freq, clo, chi,
+                                               powInfo[lowIndex].tPow2x[i],
+                                               powInfo[lowIndex + 1].tPow2x[i]);
+               }
+       }
+}
+
+static void ath9k_hw_get_target_powers(struct ath_hal *ah,
+                                      struct ath9k_channel *chan,
+                                      struct cal_target_power_ht *powInfo,
+                                      u16 numChannels,
+                                      struct cal_target_power_ht *pNewPower,
+                                      u16 numRates, bool isHt40Target)
+{
+       struct chan_centers centers;
+       u16 clo, chi;
+       int i;
+       int matchIndex = -1, lowIndex = -1;
+       u16 freq;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = isHt40Target ? centers.synth_center : centers.ctl_center;
+
+       if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
+               matchIndex = 0;
+       } else {
+               for (i = 0; (i < numChannels) &&
+                            (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+                       if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
+                                                      IS_CHAN_2GHZ(chan))) {
+                               matchIndex = i;
+                               break;
+                       } else
+                               if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
+                                                      IS_CHAN_2GHZ(chan))) &&
+                                   (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
+                                                      IS_CHAN_2GHZ(chan)))) {
+                                       lowIndex = i - 1;
+                                       break;
+                               }
+               }
+               if ((matchIndex == -1) && (lowIndex == -1))
+                       matchIndex = i - 1;
+       }
+
+       if (matchIndex != -1) {
+               *pNewPower = powInfo[matchIndex];
+       } else {
+               clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
+                                        IS_CHAN_2GHZ(chan));
+               chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
+                                        IS_CHAN_2GHZ(chan));
+
+               for (i = 0; i < numRates; i++) {
+                       pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
+                                               clo, chi,
+                                               powInfo[lowIndex].tPow2x[i],
+                                               powInfo[lowIndex + 1].tPow2x[i]);
+               }
+       }
+}
+
+static u16 ath9k_hw_get_max_edge_power(u16 freq,
+                                      struct cal_ctl_edges *pRdEdgesPower,
+                                      bool is2GHz)
+{
+       u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+       int i;
+
+       for (i = 0; (i < AR5416_NUM_BAND_EDGES) &&
+                    (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+               if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
+                       twiceMaxEdgePower = pRdEdgesPower[i].tPower;
+                       break;
+               } else if ((i > 0) &&
+                          (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
+                                                     is2GHz))) {
+                       if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
+                                              is2GHz) < freq &&
+                           pRdEdgesPower[i - 1].flag) {
+                               twiceMaxEdgePower =
+                                       pRdEdgesPower[i - 1].tPower;
+                       }
+                       break;
+               }
+       }
+
+       return twiceMaxEdgePower;
+}
+
+int ath9k_hw_set_txpower(struct ath_hal *ah,
+                        struct ath9k_channel *chan,
+                        u16 cfgCtl,
+                        u8 twiceAntennaReduction,
+                        u8 twiceMaxRegulatoryPower,
+                        u8 powerLimit)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416_eeprom *pEepData = &ahp->ah_eeprom;
+       struct modal_eep_header *pModal =
+               &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
+       int16_t ratesArray[Ar5416RateSize];
+       int16_t txPowerIndexOffset = 0;
+       u8 ht40PowerIncForPdadc = 2;
+       int i;
+
+       memset(ratesArray, 0, sizeof(ratesArray));
+
+       if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+           AR5416_EEP_MINOR_VER_2) {
+               ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+       }
+
+       if (!ath9k_hw_set_power_per_rate_table(ah, chan,
+                                              &ratesArray[0], cfgCtl,
+                                              twiceAntennaReduction,
+                                              twiceMaxRegulatoryPower,
+                                              powerLimit)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "ath9k_hw_set_txpower: unable to set "
+                       "tx power per rate table\n");
+               return -EIO;
+       }
+
+       if (!ath9k_hw_set_power_cal_table(ah, chan, &txPowerIndexOffset)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                        "ath9k_hw_set_txpower: unable to set power table\n");
+               return -EIO;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+               ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
+               if (ratesArray[i] > AR5416_MAX_RATE_POWER)
+                       ratesArray[i] = AR5416_MAX_RATE_POWER;
+       }
+
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               for (i = 0; i < Ar5416RateSize; i++)
+                       ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+       }
+
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
+                 ATH9K_POW_SM(ratesArray[rate18mb], 24)
+                 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
+                 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
+                 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+                 ATH9K_POW_SM(ratesArray[rate54mb], 24)
+                 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
+                 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
+                 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
+       if (IS_CHAN_2GHZ(chan)) {
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+                         ATH9K_POW_SM(ratesArray[rate2s], 24)
+                         | ATH9K_POW_SM(ratesArray[rate2l], 16)
+                         | ATH9K_POW_SM(ratesArray[rateXr], 8)
+                         | ATH9K_POW_SM(ratesArray[rate1l], 0));
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+                         ATH9K_POW_SM(ratesArray[rate11s], 24)
+                         | ATH9K_POW_SM(ratesArray[rate11l], 16)
+                         | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
+                         | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+       }
+
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+                 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+                 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+
+       if (IS_CHAN_HT40(chan)) {
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+                         ATH9K_POW_SM(ratesArray[rateHt40_3] +
+                                      ht40PowerIncForPdadc, 24)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_2] +
+                                        ht40PowerIncForPdadc, 16)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_1] +
+                                        ht40PowerIncForPdadc, 8)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_0] +
+                                        ht40PowerIncForPdadc, 0));
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+                         ATH9K_POW_SM(ratesArray[rateHt40_7] +
+                                      ht40PowerIncForPdadc, 24)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_6] +
+                                        ht40PowerIncForPdadc, 16)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_5] +
+                                        ht40PowerIncForPdadc, 8)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_4] +
+                                        ht40PowerIncForPdadc, 0));
+
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+                         ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+                         | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
+                         | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+                         | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+       }
+
+       REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
+                 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
+                 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
+
+       i = rate6mb;
+
+       if (IS_CHAN_HT40(chan))
+               i = rateHt40_0;
+       else if (IS_CHAN_HT20(chan))
+               i = rateHt20_0;
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               ah->ah_maxPowerLevel =
+                       ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
+       else
+               ah->ah_maxPowerLevel = ratesArray[i];
+
+       return 0;
+}
+
+void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+       struct modal_eep_header *pModal;
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416_eeprom *eep = &ahp->ah_eeprom;
+       u8 biaslevel;
+
+       if (ah->ah_macVersion != AR_SREV_VERSION_9160)
+               return;
+
+       if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
+               return;
+
+       pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+
+       if (pModal->xpaBiasLvl != 0xff) {
+               biaslevel = pModal->xpaBiasLvl;
+       } else {
+               u16 resetFreqBin, freqBin, freqCount = 0;
+               struct chan_centers centers;
+
+               ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+               resetFreqBin = FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
+               freqBin = pModal->xpaBiasLvlFreq[0] & 0xff;
+               biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14);
+
+               freqCount++;
+
+               while (freqCount < 3) {
+                       if (pModal->xpaBiasLvlFreq[freqCount] == 0x0)
+                               break;
+
+                       freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff;
+                       if (resetFreqBin >= freqBin) {
+                               biaslevel = (u8)(pModal->xpaBiasLvlFreq[freqCount] >> 14);
+                       } else {
+                               break;
+                       }
+                       freqCount++;
+               }
+       }
+
+       if (IS_CHAN_2GHZ(chan)) {
+               INI_RA(&ahp->ah_iniAddac, 7, 1) =
+                       (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
+       } else {
+               INI_RA(&ahp->ah_iniAddac, 6, 1) =
+                       (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel << 6;
+       }
+}
+
+bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
+                                      struct ath9k_channel *chan,
+                                      int16_t *ratesArray,
+                                      u16 cfgCtl,
+                                      u8 AntennaReduction,
+                                      u8 twiceMaxRegulatoryPower,
+                                      u8 powerLimit)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416_eeprom *pEepData = &ahp->ah_eeprom;
+       u8 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+       static const u16 tpScaleReductionTable[5] =
+               { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+
+       int i;
+       int8_t twiceLargestAntenna;
+       struct cal_ctl_data *rep;
+       struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
+               0, { 0, 0, 0, 0}
+       };
+       struct cal_target_power_leg targetPowerOfdmExt = {
+               0, { 0, 0, 0, 0} }, targetPowerCckExt = {
+               0, { 0, 0, 0, 0 }
+       };
+       struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
+               0, {0, 0, 0, 0}
+       };
+       u8 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+       u16 ctlModesFor11a[] =
+               { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
+       u16 ctlModesFor11g[] =
+               { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
+                 CTL_2GHT40
+               };
+       u16 numCtlModes, *pCtlMode, ctlMode, freq;
+       struct chan_centers centers;
+       int tx_chainmask;
+       u8 twiceMinEdgePower;
+
+       tx_chainmask = ahp->ah_txchainmask;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+       twiceLargestAntenna = max(
+               pEepData->modalHeader
+                       [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
+               pEepData->modalHeader
+                       [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
+
+       twiceLargestAntenna = max((u8)twiceLargestAntenna,
+                                 pEepData->modalHeader
+                                 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
+
+       twiceLargestAntenna = (int8_t)min(AntennaReduction - twiceLargestAntenna, 0);
+
+       maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+
+       if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
+               maxRegAllowedPower -=
+                       (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
+       }
+
+       scaledPower = min(powerLimit, maxRegAllowedPower);
+
+       switch (ar5416_get_ntxchains(tx_chainmask)) {
+       case 1:
+               break;
+       case 2:
+               scaledPower -=
+                       pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pwrDecreaseFor2Chain;
+               break;
+       case 3:
+               scaledPower -=
+                       pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pwrDecreaseFor3Chain;
+               break;
+       }
+
+       scaledPower = max(0, (int32_t) scaledPower);
+
+       if (IS_CHAN_2GHZ(chan)) {
+               numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
+                       SUB_NUM_CTL_MODES_AT_2G_40;
+               pCtlMode = ctlModesFor11g;
+
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                       pEepData->calTargetPowerCck,
+                       AR5416_NUM_2G_CCK_TARGET_POWERS,
+                       &targetPowerCck, 4, false);
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                       pEepData->calTargetPower2G,
+                       AR5416_NUM_2G_20_TARGET_POWERS,
+                       &targetPowerOfdm, 4, false);
+               ath9k_hw_get_target_powers(ah, chan,
+                       pEepData->calTargetPower2GHT20,
+                       AR5416_NUM_2G_20_TARGET_POWERS,
+                       &targetPowerHt20, 8, false);
+
+               if (IS_CHAN_HT40(chan)) {
+                       numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+                       ath9k_hw_get_target_powers(ah, chan,
+                               pEepData->calTargetPower2GHT40,
+                               AR5416_NUM_2G_40_TARGET_POWERS,
+                               &targetPowerHt40, 8, true);
+                       ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPowerCck,
+                               AR5416_NUM_2G_CCK_TARGET_POWERS,
+                               &targetPowerCckExt, 4, true);
+                       ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPower2G,
+                               AR5416_NUM_2G_20_TARGET_POWERS,
+                               &targetPowerOfdmExt, 4, true);
+               }
+       } else {
+               numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
+                       SUB_NUM_CTL_MODES_AT_5G_40;
+               pCtlMode = ctlModesFor11a;
+
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                       pEepData->calTargetPower5G,
+                       AR5416_NUM_5G_20_TARGET_POWERS,
+                       &targetPowerOfdm, 4, false);
+               ath9k_hw_get_target_powers(ah, chan,
+                       pEepData->calTargetPower5GHT20,
+                       AR5416_NUM_5G_20_TARGET_POWERS,
+                       &targetPowerHt20, 8, false);
+
+               if (IS_CHAN_HT40(chan)) {
+                       numCtlModes = ARRAY_SIZE(ctlModesFor11a);
+                       ath9k_hw_get_target_powers(ah, chan,
+                               pEepData->calTargetPower5GHT40,
+                               AR5416_NUM_5G_40_TARGET_POWERS,
+                               &targetPowerHt40, 8, true);
+                       ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPower5G,
+                               AR5416_NUM_5G_20_TARGET_POWERS,
+                               &targetPowerOfdmExt, 4, true);
+               }
+       }
+
+       for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+               bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+                       (pCtlMode[ctlMode] == CTL_2GHT40);
+               if (isHt40CtlMode)
+                       freq = centers.synth_center;
+               else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+                       freq = centers.ext_center;
+               else
+                       freq = centers.ctl_center;
+
+               if (ar5416_get_eep_ver(ahp) == 14 && ar5416_get_eep_rev(ahp) <= 2)
+                       twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+
+               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+                       "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
+                       "EXT_ADDITIVE %d\n",
+                       ctlMode, numCtlModes, isHt40CtlMode,
+                       (pCtlMode[ctlMode] & EXT_ADDITIVE));
+
+               for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+                               "  LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
+                               "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
+                               "chan %d\n",
+                               i, cfgCtl, pCtlMode[ctlMode],
+                               pEepData->ctlIndex[i], chan->channel);
+
+                       if ((((cfgCtl & ~CTL_MODE_M) |
+                             (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+                            pEepData->ctlIndex[i]) ||
+                           (((cfgCtl & ~CTL_MODE_M) |
+                             (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+                            ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
+                               rep = &(pEepData->ctlData[i]);
+
+                               twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
+                               rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
+                               IS_CHAN_2GHZ(chan));
+
+                               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+                                       "    MATCH-EE_IDX %d: ch %d is2 %d "
+                                       "2xMinEdge %d chainmask %d chains %d\n",
+                                       i, freq, IS_CHAN_2GHZ(chan),
+                                       twiceMinEdgePower, tx_chainmask,
+                                       ar5416_get_ntxchains
+                                       (tx_chainmask));
+                               if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+                                       twiceMaxEdgePower = min(twiceMaxEdgePower,
+                                                               twiceMinEdgePower);
+                               } else {
+                                       twiceMaxEdgePower = twiceMinEdgePower;
+                                       break;
+                               }
+                       }
+               }
+
+               minCtlPower = min(twiceMaxEdgePower, scaledPower);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+                       "    SEL-Min ctlMode %d pCtlMode %d "
+                       "2xMaxEdge %d sP %d minCtlPwr %d\n",
+                       ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
+                       scaledPower, minCtlPower);
+
+               switch (pCtlMode[ctlMode]) {
+               case CTL_11B:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
+                               targetPowerCck.tPow2x[i] =
+                                       min(targetPowerCck.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_11A:
+               case CTL_11G:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
+                               targetPowerOfdm.tPow2x[i] =
+                                       min(targetPowerOfdm.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_5GHT20:
+               case CTL_2GHT20:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
+                               targetPowerHt20.tPow2x[i] =
+                                       min(targetPowerHt20.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_11B_EXT:
+                       targetPowerCckExt.tPow2x[0] =
+                               min(targetPowerCckExt.tPow2x[0], minCtlPower);
+                       break;
+               case CTL_11A_EXT:
+               case CTL_11G_EXT:
+                       targetPowerOfdmExt.tPow2x[0] =
+                               min(targetPowerOfdmExt.tPow2x[0], minCtlPower);
+                       break;
+               case CTL_5GHT40:
+               case CTL_2GHT40:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+                               targetPowerHt40.tPow2x[i] =
+                                       min(targetPowerHt40.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
+               ratesArray[rate18mb] = ratesArray[rate24mb] =
+               targetPowerOfdm.tPow2x[0];
+       ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
+       ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
+       ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
+       ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
+
+       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
+               ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
+
+       if (IS_CHAN_2GHZ(chan)) {
+               ratesArray[rate1l] = targetPowerCck.tPow2x[0];
+               ratesArray[rate2s] = ratesArray[rate2l] =
+                       targetPowerCck.tPow2x[1];
+               ratesArray[rate5_5s] = ratesArray[rate5_5l] =
+                       targetPowerCck.tPow2x[2];
+               ;
+               ratesArray[rate11s] = ratesArray[rate11l] =
+                       targetPowerCck.tPow2x[3];
+               ;
+       }
+       if (IS_CHAN_HT40(chan)) {
+               for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+                       ratesArray[rateHt40_0 + i] =
+                               targetPowerHt40.tPow2x[i];
+               }
+               ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
+               ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
+               ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
+               if (IS_CHAN_2GHZ(chan)) {
+                       ratesArray[rateExtCck] =
+                               targetPowerCckExt.tPow2x[0];
+               }
+       }
+       return true;
+}
+
+bool ath9k_hw_set_power_cal_table(struct ath_hal *ah,
+                                 struct ath9k_channel *chan,
+                                 int16_t *pTxPowerIndexOffset)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416_eeprom *pEepData = &ahp->ah_eeprom;
+       struct cal_data_per_freq *pRawDataset;
+       u8 *pCalBChans = NULL;
+       u16 pdGainOverlap_t2;
+       static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+       u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+       u16 numPiers, i, j;
+       int16_t tMinCalPower;
+       u16 numXpdGain, xpdMask;
+       u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
+       u32 reg32, regOffset, regChainOffset;
+       int16_t modalIdx;
+
+       modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
+       xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
+
+       if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+           AR5416_EEP_MINOR_VER_2) {
+               pdGainOverlap_t2 =
+                       pEepData->modalHeader[modalIdx].pdGainOverlap;
+       } else {
+               pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+                                           AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+       }
+
+       if (IS_CHAN_2GHZ(chan)) {
+               pCalBChans = pEepData->calFreqPier2G;
+               numPiers = AR5416_NUM_2G_CAL_PIERS;
+       } else {
+               pCalBChans = pEepData->calFreqPier5G;
+               numPiers = AR5416_NUM_5G_CAL_PIERS;
+       }
+
+       numXpdGain = 0;
+
+       for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+               if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+                       if (numXpdGain >= AR5416_NUM_PD_GAINS)
+                               break;
+                       xpdGainValues[numXpdGain] =
+                               (u16)(AR5416_PD_GAINS_IN_MASK - i);
+                       numXpdGain++;
+               }
+       }
+
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+                     (numXpdGain - 1) & 0x3);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+                     xpdGainValues[0]);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+                     xpdGainValues[1]);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
+                     xpdGainValues[2]);
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               if (AR_SREV_5416_V20_OR_LATER(ah) &&
+                   (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
+                   (i != 0)) {
+                       regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+               } else
+                       regChainOffset = i * 0x1000;
+
+               if (pEepData->baseEepHeader.txMask & (1 << i)) {
+                       if (IS_CHAN_2GHZ(chan))
+                               pRawDataset = pEepData->calPierData2G[i];
+                       else
+                               pRawDataset = pEepData->calPierData5G[i];
+
+                       ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
+                                           pRawDataset, pCalBChans,
+                                           numPiers, pdGainOverlap_t2,
+                                           &tMinCalPower, gainBoundaries,
+                                           pdadcValues, numXpdGain);
+
+                       if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
+                               REG_WRITE(ah,
+                                         AR_PHY_TPCRG5 + regChainOffset,
+                                         SM(pdGainOverlap_t2,
+                                            AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
+                                         | SM(gainBoundaries[0],
+                                              AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
+                                         | SM(gainBoundaries[1],
+                                              AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
+                                         | SM(gainBoundaries[2],
+                                              AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
+                                         | SM(gainBoundaries[3],
+                                      AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
+                       }
+
+                       regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
+                       for (j = 0; j < 32; j++) {
+                               reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
+                                       ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
+                                       ((pdadcValues[4 * j + 2] & 0xFF) << 16) |
+                                       ((pdadcValues[4 * j + 3] & 0xFF) << 24);
+                               REG_WRITE(ah, regOffset, reg32);
+
+                               DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
+                                       "PDADC (%d,%4x): %4.4x %8.8x\n",
+                                       i, regChainOffset, regOffset,
+                                       reg32);
+                               DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
+                                       "PDADC: Chain %d | PDADC %3d Value %3d | "
+                                       "PDADC %3d Value %3d | PDADC %3d Value %3d | "
+                                       "PDADC %3d Value %3d |\n",
+                                       i, 4 * j, pdadcValues[4 * j],
+                                       4 * j + 1, pdadcValues[4 * j + 1],
+                                       4 * j + 2, pdadcValues[4 * j + 2],
+                                       4 * j + 3,
+                                       pdadcValues[4 * j + 3]);
+
+                               regOffset += 4;
+                       }
+               }
+       }
+
+       *pTxPowerIndexOffset = 0;
+
+       return true;
+}
+
+/* XXX: Clean me up, make me more legible */
+bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
+                                     struct ath9k_channel *chan)
+{
+       struct modal_eep_header *pModal;
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416_eeprom *eep = &ahp->ah_eeprom;
+       int i, regChainOffset;
+       u8 txRxAttenLocal;
+       u16 ant_config;
+
+       pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+
+       txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
+
+       ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 1, &ant_config);
+       REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               if (AR_SREV_9280(ah)) {
+                       if (i >= 2)
+                               break;
+               }
+
+               if (AR_SREV_5416_V20_OR_LATER(ah) &&
+                   (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
+                   && (i != 0))
+                       regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+               else
+                       regChainOffset = i * 0x1000;
+
+               REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
+                         pModal->antCtrlChain[i]);
+
+               REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
+                         (REG_READ(ah,
+                                   AR_PHY_TIMING_CTRL4(0) +
+                                   regChainOffset) &
+                          ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+                            AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+                         SM(pModal->iqCalICh[i],
+                            AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+                         SM(pModal->iqCalQCh[i],
+                            AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+               if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
+                       if ((eep->baseEepHeader.version &
+                            AR5416_EEP_VER_MINOR_MASK) >=
+                           AR5416_EEP_MINOR_VER_3) {
+                               txRxAttenLocal = pModal->txRxAttenCh[i];
+                               if (AR_SREV_9280_10_OR_LATER(ah)) {
+                                       REG_RMW_FIELD(ah,
+                                               AR_PHY_GAIN_2GHZ +
+                                               regChainOffset,
+                                               AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+                                               pModal->
+                                               bswMargin[i]);
+                                       REG_RMW_FIELD(ah,
+                                               AR_PHY_GAIN_2GHZ +
+                                               regChainOffset,
+                                               AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+                                               pModal->
+                                               bswAtten[i]);
+                                       REG_RMW_FIELD(ah,
+                                               AR_PHY_GAIN_2GHZ +
+                                               regChainOffset,
+                                               AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+                                               pModal->
+                                               xatten2Margin[i]);
+                                       REG_RMW_FIELD(ah,
+                                               AR_PHY_GAIN_2GHZ +
+                                               regChainOffset,
+                                               AR_PHY_GAIN_2GHZ_XATTEN2_DB,
+                                               pModal->
+                                               xatten2Db[i]);
+                               } else {
+                                       REG_WRITE(ah,
+                                                 AR_PHY_GAIN_2GHZ +
+                                                 regChainOffset,
+                                                 (REG_READ(ah,
+                                                           AR_PHY_GAIN_2GHZ +
+                                                           regChainOffset) &
+                                                  ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
+                                                 | SM(pModal->
+                                                 bswMargin[i],
+                                                 AR_PHY_GAIN_2GHZ_BSW_MARGIN));
+                                       REG_WRITE(ah,
+                                                 AR_PHY_GAIN_2GHZ +
+                                                 regChainOffset,
+                                                 (REG_READ(ah,
+                                                           AR_PHY_GAIN_2GHZ +
+                                                           regChainOffset) &
+                                                  ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
+                                                 | SM(pModal->bswAtten[i],
+                                                 AR_PHY_GAIN_2GHZ_BSW_ATTEN));
+                               }
+                       }
+                       if (AR_SREV_9280_10_OR_LATER(ah)) {
+                               REG_RMW_FIELD(ah,
+                                             AR_PHY_RXGAIN +
+                                             regChainOffset,
+                                             AR9280_PHY_RXGAIN_TXRX_ATTEN,
+                                             txRxAttenLocal);
+                               REG_RMW_FIELD(ah,
+                                             AR_PHY_RXGAIN +
+                                             regChainOffset,
+                                             AR9280_PHY_RXGAIN_TXRX_MARGIN,
+                                             pModal->rxTxMarginCh[i]);
+                       } else {
+                               REG_WRITE(ah,
+                                         AR_PHY_RXGAIN + regChainOffset,
+                                         (REG_READ(ah,
+                                                   AR_PHY_RXGAIN +
+                                                   regChainOffset) &
+                                          ~AR_PHY_RXGAIN_TXRX_ATTEN) |
+                                         SM(txRxAttenLocal,
+                                            AR_PHY_RXGAIN_TXRX_ATTEN));
+                               REG_WRITE(ah,
+                                         AR_PHY_GAIN_2GHZ +
+                                         regChainOffset,
+                                         (REG_READ(ah,
+                                                   AR_PHY_GAIN_2GHZ +
+                                                   regChainOffset) &
+                                          ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
+                                         SM(pModal->rxTxMarginCh[i],
+                                            AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
+                       }
+               }
+       }
+
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               if (IS_CHAN_2GHZ(chan)) {
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
+                                                 AR_AN_RF2G1_CH0_OB,
+                                                 AR_AN_RF2G1_CH0_OB_S,
+                                                 pModal->ob);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
+                                                 AR_AN_RF2G1_CH0_DB,
+                                                 AR_AN_RF2G1_CH0_DB_S,
+                                                 pModal->db);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
+                                                 AR_AN_RF2G1_CH1_OB,
+                                                 AR_AN_RF2G1_CH1_OB_S,
+                                                 pModal->ob_ch1);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
+                                                 AR_AN_RF2G1_CH1_DB,
+                                                 AR_AN_RF2G1_CH1_DB_S,
+                                                 pModal->db_ch1);
+               } else {
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
+                                                 AR_AN_RF5G1_CH0_OB5,
+                                                 AR_AN_RF5G1_CH0_OB5_S,
+                                                 pModal->ob);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
+                                                 AR_AN_RF5G1_CH0_DB5,
+                                                 AR_AN_RF5G1_CH0_DB5_S,
+                                                 pModal->db);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
+                                                 AR_AN_RF5G1_CH1_OB5,
+                                                 AR_AN_RF5G1_CH1_OB5_S,
+                                                 pModal->ob_ch1);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
+                                                 AR_AN_RF5G1_CH1_DB5,
+                                                 AR_AN_RF5G1_CH1_DB5_S,
+                                                 pModal->db_ch1);
+               }
+               ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
+                                         AR_AN_TOP2_XPABIAS_LVL,
+                                         AR_AN_TOP2_XPABIAS_LVL_S,
+                                         pModal->xpaBiasLvl);
+               ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
+                                         AR_AN_TOP2_LOCALBIAS,
+                                         AR_AN_TOP2_LOCALBIAS_S,
+                                         pModal->local_bias);
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "ForceXPAon: %d\n",
+                       pModal->force_xpaon);
+               REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
+                             pModal->force_xpaon);
+       }
+
+       REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
+                     pModal->switchSettling);
+       REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
+                     pModal->adcDesiredSize);
+
+       if (!AR_SREV_9280_10_OR_LATER(ah))
+               REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+                             AR_PHY_DESIRED_SZ_PGA,
+                             pModal->pgaDesiredSize);
+
+       REG_WRITE(ah, AR_PHY_RF_CTL4,
+                 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
+                 | SM(pModal->txEndToXpaOff,
+                      AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
+                 | SM(pModal->txFrameToXpaOn,
+                      AR_PHY_RF_CTL4_FRAME_XPAA_ON)
+                 | SM(pModal->txFrameToXpaOn,
+                      AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+       REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
+                     pModal->txEndToRxOn);
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
+                             pModal->thresh62);
+               REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
+                             AR_PHY_EXT_CCA0_THRESH62,
+                             pModal->thresh62);
+       } else {
+               REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
+                             pModal->thresh62);
+               REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
+                             AR_PHY_EXT_CCA_THRESH62,
+                             pModal->thresh62);
+       }
+
+       if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+           AR5416_EEP_MINOR_VER_2) {
+               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
+                             AR_PHY_TX_END_DATA_START,
+                             pModal->txFrameToDataStart);
+               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
+                             pModal->txFrameToPaOn);
+       }
+
+       if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+           AR5416_EEP_MINOR_VER_3) {
+               if (IS_CHAN_HT40(chan))
+                       REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+                                     AR_PHY_SETTLING_SWITCH,
+                                     pModal->swSettleHt40);
+       }
+
+       return true;
+}
+
+int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah,
+                                   struct ath9k_channel *chan,
+                                   u8 index, u16 *config)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416_eeprom *eep = &ahp->ah_eeprom;
+       struct modal_eep_header *pModal =
+               &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+       struct base_eep_header *pBase = &eep->baseEepHeader;
+
+       switch (index) {
+       case 0:
+               *config = pModal->antCtrlCommon & 0xFFFF;
+               return 0;
+       case 1:
+               if (pBase->version >= 0x0E0D) {
+                       if (pModal->useAnt1) {
+                               *config =
+                               ((pModal->antCtrlCommon & 0xFFFF0000) >> 16);
+                               return 0;
+                       }
+               }
+               break;
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah,
+                              enum ieee80211_band freq_band)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416_eeprom *eep = &ahp->ah_eeprom;
+       struct modal_eep_header *pModal =
+               &(eep->modalHeader[IEEE80211_BAND_5GHZ == freq_band]);
+       struct base_eep_header *pBase = &eep->baseEepHeader;
+       u8 num_ant_config;
+
+       num_ant_config = 1;
+
+       if (pBase->version >= 0x0E0D)
+               if (pModal->useAnt1)
+                       num_ant_config += 1;
+
+       return num_ant_config;
+}
+
+u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416_eeprom *eep =
+               (struct ar5416_eeprom *) &ahp->ah_eeprom;
+       u16 spur_val = AR_NO_SPUR;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "Getting spur idx %d is2Ghz. %d val %x\n",
+               i, is2GHz, ah->ah_config.spurchans[i][is2GHz]);
+
+       switch (ah->ah_config.spurmode) {
+       case SPUR_DISABLE:
+               break;
+       case SPUR_ENABLE_IOCTL:
+               spur_val = ah->ah_config.spurchans[i][is2GHz];
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "Getting spur val from new loc. %d\n", spur_val);
+               break;
+       case SPUR_ENABLE_EEPROM:
+               spur_val = eep->modalHeader[is2GHz].spurChans[i].spurChan;
+               break;
+
+       }
+
+       return spur_val;
+}
+
+u32 ath9k_hw_get_eeprom(struct ath_hal *ah,
+                       enum eeprom_param param)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ar5416_eeprom *eep = &ahp->ah_eeprom;
+       struct modal_eep_header *pModal = eep->modalHeader;
+       struct base_eep_header *pBase = &eep->baseEepHeader;
+
+       switch (param) {
+       case EEP_NFTHRESH_5:
+               return -pModal[0].noiseFloorThreshCh[0];
+       case EEP_NFTHRESH_2:
+               return -pModal[1].noiseFloorThreshCh[0];
+       case AR_EEPROM_MAC(0):
+               return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+       case AR_EEPROM_MAC(1):
+               return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+       case AR_EEPROM_MAC(2):
+               return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+       case EEP_REG_0:
+               return pBase->regDmn[0];
+       case EEP_REG_1:
+               return pBase->regDmn[1];
+       case EEP_OP_CAP:
+               return pBase->deviceCap;
+       case EEP_OP_MODE:
+               return pBase->opCapFlags;
+       case EEP_RF_SILENT:
+               return pBase->rfSilent;
+       case EEP_OB_5:
+               return pModal[0].ob;
+       case EEP_DB_5:
+               return pModal[0].db;
+       case EEP_OB_2:
+               return pModal[1].ob;
+       case EEP_DB_2:
+               return pModal[1].db;
+       case EEP_MINOR_REV:
+               return pBase->version & AR5416_EEP_VER_MINOR_MASK;
+       case EEP_TX_MASK:
+               return pBase->txMask;
+       case EEP_RX_MASK:
+               return pBase->rxMask;
+       default:
+               return 0;
+       }
+}
+
+int ath9k_hw_eeprom_attach(struct ath_hal *ah)
+{
+       int status;
+
+       if (ath9k_hw_use_flash(ah))
+               ath9k_hw_flash_map(ah);
+
+       if (!ath9k_hw_fill_eeprom(ah))
+               return -EIO;
+
+       status = ath9k_hw_check_eeprom(ah);
+
+       return status;
+}
index 98bc25c9b3cf4f5f5ddf3e22b92d0cbd12c60a3d..e05c9ef55e471327fa1a213db3e74446ccfaf27e 100644 (file)
 #include "phy.h"
 #include "initvals.h"
 
-static void ath9k_hw_iqcal_collect(struct ath_hal *ah);
-static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains);
-static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah);
-static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah,
-                                          u8 numChains);
-static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah);
-static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah,
-                                        u8 numChains);
-
 static const u8 CLOCK_RATE[] = { 40, 80, 22, 44, 88, 40 };
-static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
-
-static const struct hal_percal_data iq_cal_multi_sample = {
-       IQ_MISMATCH_CAL,
-       MAX_CAL_SAMPLES,
-       PER_MIN_LOG_COUNT,
-       ath9k_hw_iqcal_collect,
-       ath9k_hw_iqcalibrate
-};
-static const struct hal_percal_data iq_cal_single_sample = {
-       IQ_MISMATCH_CAL,
-       MIN_CAL_SAMPLES,
-       PER_MAX_LOG_COUNT,
-       ath9k_hw_iqcal_collect,
-       ath9k_hw_iqcalibrate
-};
-static const struct hal_percal_data adc_gain_cal_multi_sample = {
-       ADC_GAIN_CAL,
-       MAX_CAL_SAMPLES,
-       PER_MIN_LOG_COUNT,
-       ath9k_hw_adc_gaincal_collect,
-       ath9k_hw_adc_gaincal_calibrate
-};
-static const struct hal_percal_data adc_gain_cal_single_sample = {
-       ADC_GAIN_CAL,
-       MIN_CAL_SAMPLES,
-       PER_MAX_LOG_COUNT,
-       ath9k_hw_adc_gaincal_collect,
-       ath9k_hw_adc_gaincal_calibrate
-};
-static const struct hal_percal_data adc_dc_cal_multi_sample = {
-       ADC_DC_CAL,
-       MAX_CAL_SAMPLES,
-       PER_MIN_LOG_COUNT,
-       ath9k_hw_adc_dccal_collect,
-       ath9k_hw_adc_dccal_calibrate
-};
-static const struct hal_percal_data adc_dc_cal_single_sample = {
-       ADC_DC_CAL,
-       MIN_CAL_SAMPLES,
-       PER_MAX_LOG_COUNT,
-       ath9k_hw_adc_dccal_collect,
-       ath9k_hw_adc_dccal_calibrate
-};
-static const struct hal_percal_data adc_init_dc_cal = {
-       ADC_DC_INIT_CAL,
-       MIN_CAL_SAMPLES,
-       INIT_LOG_COUNT,
-       ath9k_hw_adc_dccal_collect,
-       ath9k_hw_adc_dccal_calibrate
-};
 
-static struct ath9k_rate_table ar5416_11a_table = {
-       8,
-       {0},
-       {
-               {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
-               {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
-               {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
-               {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
-               {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
-               {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
-               {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
-               {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4}
-       },
-};
+extern struct hal_percal_data iq_cal_multi_sample;
+extern struct hal_percal_data iq_cal_single_sample;
+extern struct hal_percal_data adc_gain_cal_multi_sample;
+extern struct hal_percal_data adc_gain_cal_single_sample;
+extern struct hal_percal_data adc_dc_cal_multi_sample;
+extern struct hal_percal_data adc_dc_cal_single_sample;
+extern struct hal_percal_data adc_init_dc_cal;
 
-static struct ath9k_rate_table ar5416_11b_table = {
-       4,
-       {0},
-       {
-               {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
-               {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
-               {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 1},
-               {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 1}
-       },
-};
+static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type);
+static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
+                             enum ath9k_ht_macmode macmode);
+static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
+                             struct ar5416_eeprom *pEepData,
+                             u32 reg, u32 value);
+static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan);
+static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan);
 
-static struct ath9k_rate_table ar5416_11g_table = {
-       12,
-       {0},
-       {
-               {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
-               {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
-               {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
-               {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
+/********************/
+/* Helper Functions */
+/********************/
 
-               {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
-               {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
-               {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
-               {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
-               {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
-               {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
-               {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
-               {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8}
-       },
-};
+static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
+{
+       if (ah->ah_curchan != NULL)
+               return clks / CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
+       else
+               return clks / CLOCK_RATE[ATH9K_MODE_11B];
+}
 
-static struct ath9k_rate_table ar5416_11ng_table = {
-       28,
-       {0},
-       {
-               {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
-               {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
-               {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
-               {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
+static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
+{
+       struct ath9k_channel *chan = ah->ah_curchan;
 
-               {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
-               {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
-               {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
-               {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
-               {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
-               {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
-               {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
-               {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8},
-               {true, PHY_HT, 6500, 0x80, 0x00, 0, 4},
-               {true, PHY_HT, 13000, 0x81, 0x00, 1, 6},
-               {true, PHY_HT, 19500, 0x82, 0x00, 2, 6},
-               {true, PHY_HT, 26000, 0x83, 0x00, 3, 8},
-               {true, PHY_HT, 39000, 0x84, 0x00, 4, 8},
-               {true, PHY_HT, 52000, 0x85, 0x00, 5, 8},
-               {true, PHY_HT, 58500, 0x86, 0x00, 6, 8},
-               {true, PHY_HT, 65000, 0x87, 0x00, 7, 8},
-               {true, PHY_HT, 13000, 0x88, 0x00, 8, 4},
-               {true, PHY_HT, 26000, 0x89, 0x00, 9, 6},
-               {true, PHY_HT, 39000, 0x8a, 0x00, 10, 6},
-               {true, PHY_HT, 52000, 0x8b, 0x00, 11, 8},
-               {true, PHY_HT, 78000, 0x8c, 0x00, 12, 8},
-               {true, PHY_HT, 104000, 0x8d, 0x00, 13, 8},
-               {true, PHY_HT, 117000, 0x8e, 0x00, 14, 8},
-               {true, PHY_HT, 130000, 0x8f, 0x00, 15, 8},
-       },
-};
+       if (chan && IS_CHAN_HT40(chan))
+               return ath9k_hw_mac_usec(ah, clks) / 2;
+       else
+               return ath9k_hw_mac_usec(ah, clks);
+}
 
-static struct ath9k_rate_table ar5416_11na_table = {
-       24,
-       {0},
-       {
-               {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
-               {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
-               {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
-               {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
-               {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
-               {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
-               {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
-               {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4},
-               {true, PHY_HT, 6500, 0x80, 0x00, 0, 0},
-               {true, PHY_HT, 13000, 0x81, 0x00, 1, 2},
-               {true, PHY_HT, 19500, 0x82, 0x00, 2, 2},
-               {true, PHY_HT, 26000, 0x83, 0x00, 3, 4},
-               {true, PHY_HT, 39000, 0x84, 0x00, 4, 4},
-               {true, PHY_HT, 52000, 0x85, 0x00, 5, 4},
-               {true, PHY_HT, 58500, 0x86, 0x00, 6, 4},
-               {true, PHY_HT, 65000, 0x87, 0x00, 7, 4},
-               {true, PHY_HT, 13000, 0x88, 0x00, 8, 0},
-               {true, PHY_HT, 26000, 0x89, 0x00, 9, 2},
-               {true, PHY_HT, 39000, 0x8a, 0x00, 10, 2},
-               {true, PHY_HT, 52000, 0x8b, 0x00, 11, 4},
-               {true, PHY_HT, 78000, 0x8c, 0x00, 12, 4},
-               {true, PHY_HT, 104000, 0x8d, 0x00, 13, 4},
-               {true, PHY_HT, 117000, 0x8e, 0x00, 14, 4},
-               {true, PHY_HT, 130000, 0x8f, 0x00, 15, 4},
-       },
-};
+static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
+{
+       if (ah->ah_curchan != NULL)
+               return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
+                       ah->ah_curchan)];
+       else
+               return usecs * CLOCK_RATE[ATH9K_MODE_11B];
+}
+
+static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
+{
+       struct ath9k_channel *chan = ah->ah_curchan;
+
+       if (chan && IS_CHAN_HT40(chan))
+               return ath9k_hw_mac_clks(ah, usecs) * 2;
+       else
+               return ath9k_hw_mac_clks(ah, usecs);
+}
 
-static enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
-                                      const struct ath9k_channel *chan)
+enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
+                              const struct ath9k_channel *chan)
 {
        if (IS_CHAN_CCK(chan))
                return ATH9K_MODE_11A;
@@ -208,10 +93,7 @@ static enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
        return ATH9K_MODE_11A;
 }
 
-static bool ath9k_hw_wait(struct ath_hal *ah,
-                         u32 reg,
-                         u32 mask,
-                         u32 val)
+bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val)
 {
        int i;
 
@@ -222,78 +104,10 @@ static bool ath9k_hw_wait(struct ath_hal *ah,
                udelay(AH_TIME_QUANTUM);
        }
        DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
-                "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
-                __func__, reg, REG_READ(ah, reg), mask, val);
-       return false;
-}
-
-static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off,
-                                u16 *data)
-{
-       (void) REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
-
-       if (!ath9k_hw_wait(ah,
-                          AR_EEPROM_STATUS_DATA,
-                          AR_EEPROM_STATUS_DATA_BUSY |
-                          AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
-               return false;
-       }
-
-       *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
-                  AR_EEPROM_STATUS_DATA_VAL);
-
-       return true;
-}
-
-static int ath9k_hw_flash_map(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-
-       ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX);
-
-       if (!ahp->ah_cal_mem) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                        "%s: cannot remap eeprom region \n", __func__);
-               return -EIO;
-       }
-
-       return 0;
-}
-
-static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off,
-                               u16 *data)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-
-       *data = ioread16(ahp->ah_cal_mem + off);
-       return true;
-}
-
-static void ath9k_hw_read_revisions(struct ath_hal *ah)
-{
-       u32 val;
-
-       val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
-
-       if (val == 0xFF) {
-               val = REG_READ(ah, AR_SREV);
-
-               ah->ah_macVersion =
-                       (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
-
-               ah->ah_macRev = MS(val, AR_SREV_REVISION2);
-               ah->ah_isPciExpress =
-                       (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
-
-       } else {
-               if (!AR_SREV_9100(ah))
-                       ah->ah_macVersion = MS(val, AR_SREV_VERSION);
-
-               ah->ah_macRev = val & AR_SREV_REVISION;
+               "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
+               __func__, reg, REG_READ(ah, reg), mask, val);
 
-               if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE)
-                       ah->ah_isPciExpress = true;
-       }
+       return false;
 }
 
 u32 ath9k_hw_reverse_bits(u32 val, u32 n)
@@ -308,850 +122,318 @@ u32 ath9k_hw_reverse_bits(u32 val, u32 n)
        return retval;
 }
 
-static void ath9k_hw_set_defaults(struct ath_hal *ah)
+bool ath9k_get_channel_edges(struct ath_hal *ah,
+                            u16 flags, u16 *low,
+                            u16 *high)
 {
-       int i;
-
-       ah->ah_config.dma_beacon_response_time = 2;
-       ah->ah_config.sw_beacon_response_time = 10;
-       ah->ah_config.additional_swba_backoff = 0;
-       ah->ah_config.ack_6mb = 0x0;
-       ah->ah_config.cwm_ignore_extcca = 0;
-       ah->ah_config.pcie_powersave_enable = 0;
-       ah->ah_config.pcie_l1skp_enable = 0;
-       ah->ah_config.pcie_clock_req = 0;
-       ah->ah_config.pcie_power_reset = 0x100;
-       ah->ah_config.pcie_restore = 0;
-       ah->ah_config.pcie_waen = 0;
-       ah->ah_config.analog_shiftreg = 1;
-       ah->ah_config.ht_enable = 1;
-       ah->ah_config.ofdm_trig_low = 200;
-       ah->ah_config.ofdm_trig_high = 500;
-       ah->ah_config.cck_trig_high = 200;
-       ah->ah_config.cck_trig_low = 100;
-       ah->ah_config.enable_ani = 1;
-       ah->ah_config.noise_immunity_level = 4;
-       ah->ah_config.ofdm_weaksignal_det = 1;
-       ah->ah_config.cck_weaksignal_thr = 0;
-       ah->ah_config.spur_immunity_level = 2;
-       ah->ah_config.firstep_level = 0;
-       ah->ah_config.rssi_thr_high = 40;
-       ah->ah_config.rssi_thr_low = 7;
-       ah->ah_config.diversity_control = 0;
-       ah->ah_config.antenna_switch_swap = 0;
+       struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
 
-       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-               ah->ah_config.spurchans[i][0] = AR_NO_SPUR;
-               ah->ah_config.spurchans[i][1] = AR_NO_SPUR;
+       if (flags & CHANNEL_5GHZ) {
+               *low = pCap->low_5ghz_chan;
+               *high = pCap->high_5ghz_chan;
+               return true;
        }
-
-       ah->ah_config.intr_mitigation = 0;
+       if ((flags & CHANNEL_2GHZ)) {
+               *low = pCap->low_2ghz_chan;
+               *high = pCap->high_2ghz_chan;
+               return true;
+       }
+       return false;
 }
 
-static void ath9k_hw_override_ini(struct ath_hal *ah,
-                                        struct ath9k_channel *chan)
+u16 ath9k_hw_computetxtime(struct ath_hal *ah,
+                          const struct ath9k_rate_table *rates,
+                          u32 frameLen, u16 rateix,
+                          bool shortPreamble)
 {
-       if (!AR_SREV_5416_V20_OR_LATER(ah)
-           || AR_SREV_9280_10_OR_LATER(ah))
-               return;
+       u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
+       u32 kbps;
 
-       REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
-}
+       kbps = rates->info[rateix].rateKbps;
 
-static void ath9k_hw_init_bb(struct ath_hal *ah,
-                            struct ath9k_channel *chan)
-{
-       u32 synthDelay;
+       if (kbps == 0)
+               return 0;
 
-       synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
-       if (IS_CHAN_CCK(chan))
-               synthDelay = (4 * synthDelay) / 22;
-       else
-               synthDelay /= 10;
+       switch (rates->info[rateix].phy) {
+       case PHY_CCK:
+               phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
+               if (shortPreamble && rates->info[rateix].shortPreamble)
+                       phyTime >>= 1;
+               numBits = frameLen << 3;
+               txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps);
+               break;
+       case PHY_OFDM:
+               if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
+                       bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
+                       numBits = OFDM_PLCP_BITS + (frameLen << 3);
+                       numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
+                       txTime = OFDM_SIFS_TIME_QUARTER
+                               + OFDM_PREAMBLE_TIME_QUARTER
+                               + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
+               } else if (ah->ah_curchan &&
+                          IS_CHAN_HALF_RATE(ah->ah_curchan)) {
+                       bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
+                       numBits = OFDM_PLCP_BITS + (frameLen << 3);
+                       numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
+                       txTime = OFDM_SIFS_TIME_HALF +
+                               OFDM_PREAMBLE_TIME_HALF
+                               + (numSymbols * OFDM_SYMBOL_TIME_HALF);
+               } else {
+                       bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
+                       numBits = OFDM_PLCP_BITS + (frameLen << 3);
+                       numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
+                       txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
+                               + (numSymbols * OFDM_SYMBOL_TIME);
+               }
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
+                       "%s: unknown phy %u (rate ix %u)\n", __func__,
+                       rates->info[rateix].phy, rateix);
+               txTime = 0;
+               break;
+       }
 
-       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+       return txTime;
+}
 
-       udelay(synthDelay + BASE_ACTIVATE_DELAY);
+u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
+{
+       if (flags & CHANNEL_2GHZ) {
+               if (freq == 2484)
+                       return 14;
+               if (freq < 2484)
+                       return (freq - 2407) / 5;
+               else
+                       return 15 + ((freq - 2512) / 20);
+       } else if (flags & CHANNEL_5GHZ) {
+               if (ath9k_regd_is_public_safety_sku(ah) &&
+                   IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
+                       return ((freq * 10) +
+                               (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
+               } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
+                       return (freq - 4000) / 5;
+               } else {
+                       return (freq - 5000) / 5;
+               }
+       } else {
+               if (freq == 2484)
+                       return 14;
+               if (freq < 2484)
+                       return (freq - 2407) / 5;
+               if (freq < 5000) {
+                       if (ath9k_regd_is_public_safety_sku(ah)
+                           && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
+                               return ((freq * 10) +
+                                       (((freq % 5) ==
+                                         2) ? 5 : 0) - 49400) / 5;
+                       } else if (freq > 4900) {
+                               return (freq - 4000) / 5;
+                       } else {
+                               return 15 + ((freq - 2512) / 20);
+                       }
+               }
+               return (freq - 5000) / 5;
+       }
 }
 
-static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
-                                         enum ath9k_opmode opmode)
+void ath9k_hw_get_channel_centers(struct ath_hal *ah,
+                                 struct ath9k_channel *chan,
+                                 struct chan_centers *centers)
 {
+       int8_t extoff;
        struct ath_hal_5416 *ahp = AH5416(ah);
 
-       ahp->ah_maskReg = AR_IMR_TXERR |
-               AR_IMR_TXURN |
-               AR_IMR_RXERR |
-               AR_IMR_RXORN |
-               AR_IMR_BCNMISC;
-
-       if (ahp->ah_intrMitigation)
-               ahp->ah_maskReg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
-       else
-               ahp->ah_maskReg |= AR_IMR_RXOK;
-
-       ahp->ah_maskReg |= AR_IMR_TXOK;
-
-       if (opmode == ATH9K_M_HOSTAP)
-               ahp->ah_maskReg |= AR_IMR_MIB;
-
-       REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
-       REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
-
-       if (!AR_SREV_9100(ah)) {
-               REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
-               REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
-               REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
+       if (!IS_CHAN_HT40(chan)) {
+               centers->ctl_center = centers->ext_center =
+                       centers->synth_center = chan->channel;
+               return;
        }
-}
 
-static void ath9k_hw_init_qos(struct ath_hal *ah)
-{
-       REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
-       REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
+       if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
+           (chan->chanmode == CHANNEL_G_HT40PLUS)) {
+               centers->synth_center =
+                       chan->channel + HT40_CHANNEL_CENTER_SHIFT;
+               extoff = 1;
+       } else {
+               centers->synth_center =
+                       chan->channel - HT40_CHANNEL_CENTER_SHIFT;
+               extoff = -1;
+       }
 
-       REG_WRITE(ah, AR_QOS_NO_ACK,
-                 SM(2, AR_QOS_NO_ACK_TWO_BIT) |
-                 SM(5, AR_QOS_NO_ACK_BIT_OFF) |
-                 SM(0, AR_QOS_NO_ACK_BYTE_OFF));
+       centers->ctl_center =
+               centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
+       centers->ext_center =
+               centers->synth_center + (extoff *
+                        ((ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ?
+                         HT40_CHANNEL_CENTER_SHIFT : 15));
 
-       REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
-       REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
-       REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
-       REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
-       REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
 }
 
-static void ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
-                                     u32 reg,
-                                     u32 mask,
-                                     u32 shift,
-                                     u32 val)
+/******************/
+/* Chip Revisions */
+/******************/
+
+static void ath9k_hw_read_revisions(struct ath_hal *ah)
 {
-       u32 regVal;
+       u32 val;
 
-       regVal = REG_READ(ah, reg) & ~mask;
-       regVal |= (val << shift) & mask;
+       val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
 
-       REG_WRITE(ah, reg, regVal);
+       if (val == 0xFF) {
+               val = REG_READ(ah, AR_SREV);
+               ah->ah_macVersion = (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
+               ah->ah_macRev = MS(val, AR_SREV_REVISION2);
+               ah->ah_isPciExpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
+       } else {
+               if (!AR_SREV_9100(ah))
+                       ah->ah_macVersion = MS(val, AR_SREV_VERSION);
 
-       if (ah->ah_config.analog_shiftreg)
-               udelay(100);
+               ah->ah_macRev = val & AR_SREV_REVISION;
 
-       return;
+               if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE)
+                       ah->ah_isPciExpress = true;
+       }
 }
 
-static u8 ath9k_hw_get_num_ant_config(struct ath_hal_5416 *ahp,
-                                     enum ieee80211_band freq_band)
+static int ath9k_hw_get_radiorev(struct ath_hal *ah)
 {
-       struct ar5416_eeprom *eep = &ahp->ah_eeprom;
-       struct modal_eep_header *pModal =
-               &(eep->modalHeader[IEEE80211_BAND_5GHZ == freq_band]);
-       struct base_eep_header *pBase = &eep->baseEepHeader;
-       u8 num_ant_config;
+       u32 val;
+       int i;
 
-       num_ant_config = 1;
+       REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
 
-       if (pBase->version >= 0x0E0D)
-               if (pModal->useAnt1)
-                       num_ant_config += 1;
+       for (i = 0; i < 8; i++)
+               REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
+       val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
+       val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
 
-       return num_ant_config;
+       return ath9k_hw_reverse_bits(val, 8);
 }
 
-static int
-ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal_5416 *ahp,
-                               struct ath9k_channel *chan,
-                               u8 index,
-                               u16 *config)
+/************************************/
+/* HW Attach, Detach, Init Routines */
+/************************************/
+
+static void ath9k_hw_disablepcie(struct ath_hal *ah)
 {
-       struct ar5416_eeprom *eep = &ahp->ah_eeprom;
-       struct modal_eep_header *pModal =
-               &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-       struct base_eep_header *pBase = &eep->baseEepHeader;
+       if (!AR_SREV_9100(ah))
+               return;
 
-       switch (index) {
-       case 0:
-               *config = pModal->antCtrlCommon & 0xFFFF;
-               return 0;
-       case 1:
-               if (pBase->version >= 0x0E0D) {
-                       if (pModal->useAnt1) {
-                               *config =
-                               ((pModal->antCtrlCommon & 0xFFFF0000) >> 16);
-                               return 0;
-                       }
-               }
-               break;
-       default:
-               break;
-       }
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
 
-       return -EINVAL;
+       REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
 }
 
-static inline bool ath9k_hw_nvram_read(struct ath_hal *ah,
-                                      u32 off,
-                                      u16 *data)
+static bool ath9k_hw_chip_test(struct ath_hal *ah)
 {
-       if (ath9k_hw_use_flash(ah))
-               return ath9k_hw_flash_read(ah, off, data);
-       else
-               return ath9k_hw_eeprom_read(ah, off, data);
-}
+       u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
+       u32 regHold[2];
+       u32 patternData[4] = { 0x55555555,
+                              0xaaaaaaaa,
+                              0x66666666,
+                              0x99999999 };
+       int i, j;
 
-static bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ar5416_eeprom *eep = &ahp->ah_eeprom;
-       u16 *eep_data;
-       int addr, ar5416_eep_start_loc = 0;
+       for (i = 0; i < 2; i++) {
+               u32 addr = regAddr[i];
+               u32 wrData, rdData;
 
-       if (!ath9k_hw_use_flash(ah)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                        "%s: Reading from EEPROM, not flash\n", __func__);
-               ar5416_eep_start_loc = 256;
-       }
-       if (AR_SREV_9100(ah))
-               ar5416_eep_start_loc = 256;
-
-       eep_data = (u16 *) eep;
-       for (addr = 0;
-            addr < sizeof(struct ar5416_eeprom) / sizeof(u16);
-            addr++) {
-               if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
-                                        eep_data)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                                "%s: Unable to read eeprom region \n",
-                                __func__);
-                       return false;
+               regHold[i] = REG_READ(ah, addr);
+               for (j = 0; j < 0x100; j++) {
+                       wrData = (j << 16) | j;
+                       REG_WRITE(ah, addr, wrData);
+                       rdData = REG_READ(ah, addr);
+                       if (rdData != wrData) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+                                       "%s: address test failed "
+                                       "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+                                       __func__, addr, wrData, rdData);
+                               return false;
+                       }
+               }
+               for (j = 0; j < 4; j++) {
+                       wrData = patternData[j];
+                       REG_WRITE(ah, addr, wrData);
+                       rdData = REG_READ(ah, addr);
+                       if (wrData != rdData) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+                                       "%s: address test failed "
+                                       "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+                                       __func__, addr, wrData, rdData);
+                               return false;
+                       }
                }
-               eep_data++;
+               REG_WRITE(ah, regAddr[i], regHold[i]);
        }
+       udelay(100);
        return true;
 }
 
-/* XXX: Clean me up, make me more legible */
-static bool
-ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
-                                struct ath9k_channel *chan)
+static const char *ath9k_hw_devname(u16 devid)
 {
-       struct modal_eep_header *pModal;
-       int i, regChainOffset;
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ar5416_eeprom *eep = &ahp->ah_eeprom;
-       u8 txRxAttenLocal;
-       u16 ant_config;
-
-       pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-
-       txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
-
-       ath9k_hw_get_eeprom_antenna_cfg(ahp, chan, 1, &ant_config);
-       REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               if (AR_SREV_9280(ah)) {
-                       if (i >= 2)
-                               break;
-               }
-
-               if (AR_SREV_5416_V20_OR_LATER(ah) &&
-                   (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
-                   && (i != 0))
-                       regChainOffset = (i == 1) ? 0x2000 : 0x1000;
-               else
-                       regChainOffset = i * 0x1000;
-
-               REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
-                         pModal->antCtrlChain[i]);
-
-               REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
-                         (REG_READ(ah,
-                                   AR_PHY_TIMING_CTRL4(0) +
-                                   regChainOffset) &
-                          ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
-                            AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
-                         SM(pModal->iqCalICh[i],
-                            AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
-                         SM(pModal->iqCalQCh[i],
-                            AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
-
-               if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
-                       if ((eep->baseEepHeader.version &
-                            AR5416_EEP_VER_MINOR_MASK) >=
-                           AR5416_EEP_MINOR_VER_3) {
-                               txRxAttenLocal = pModal->txRxAttenCh[i];
-                               if (AR_SREV_9280_10_OR_LATER(ah)) {
-                                       REG_RMW_FIELD(ah,
-                                               AR_PHY_GAIN_2GHZ +
-                                               regChainOffset,
-                                               AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
-                                               pModal->
-                                               bswMargin[i]);
-                                       REG_RMW_FIELD(ah,
-                                               AR_PHY_GAIN_2GHZ +
-                                               regChainOffset,
-                                               AR_PHY_GAIN_2GHZ_XATTEN1_DB,
-                                               pModal->
-                                               bswAtten[i]);
-                                       REG_RMW_FIELD(ah,
-                                               AR_PHY_GAIN_2GHZ +
-                                               regChainOffset,
-                                               AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
-                                               pModal->
-                                               xatten2Margin[i]);
-                                       REG_RMW_FIELD(ah,
-                                               AR_PHY_GAIN_2GHZ +
-                                               regChainOffset,
-                                               AR_PHY_GAIN_2GHZ_XATTEN2_DB,
-                                               pModal->
-                                               xatten2Db[i]);
-                               } else {
-                                       REG_WRITE(ah,
-                                                 AR_PHY_GAIN_2GHZ +
-                                                 regChainOffset,
-                                                 (REG_READ(ah,
-                                                           AR_PHY_GAIN_2GHZ +
-                                                           regChainOffset) &
-                                                  ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
-                                                 | SM(pModal->
-                                                 bswMargin[i],
-                                                 AR_PHY_GAIN_2GHZ_BSW_MARGIN));
-                                       REG_WRITE(ah,
-                                                 AR_PHY_GAIN_2GHZ +
-                                                 regChainOffset,
-                                                 (REG_READ(ah,
-                                                           AR_PHY_GAIN_2GHZ +
-                                                           regChainOffset) &
-                                                  ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
-                                                 | SM(pModal->bswAtten[i],
-                                                 AR_PHY_GAIN_2GHZ_BSW_ATTEN));
-                               }
-                       }
-                       if (AR_SREV_9280_10_OR_LATER(ah)) {
-                               REG_RMW_FIELD(ah,
-                                             AR_PHY_RXGAIN +
-                                             regChainOffset,
-                                             AR9280_PHY_RXGAIN_TXRX_ATTEN,
-                                             txRxAttenLocal);
-                               REG_RMW_FIELD(ah,
-                                             AR_PHY_RXGAIN +
-                                             regChainOffset,
-                                             AR9280_PHY_RXGAIN_TXRX_MARGIN,
-                                             pModal->rxTxMarginCh[i]);
-                       } else {
-                               REG_WRITE(ah,
-                                         AR_PHY_RXGAIN + regChainOffset,
-                                         (REG_READ(ah,
-                                                   AR_PHY_RXGAIN +
-                                                   regChainOffset) &
-                                          ~AR_PHY_RXGAIN_TXRX_ATTEN) |
-                                         SM(txRxAttenLocal,
-                                            AR_PHY_RXGAIN_TXRX_ATTEN));
-                               REG_WRITE(ah,
-                                         AR_PHY_GAIN_2GHZ +
-                                         regChainOffset,
-                                         (REG_READ(ah,
-                                                   AR_PHY_GAIN_2GHZ +
-                                                   regChainOffset) &
-                                          ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
-                                         SM(pModal->rxTxMarginCh[i],
-                                            AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
-                       }
-               }
+       switch (devid) {
+       case AR5416_DEVID_PCI:
+       case AR5416_DEVID_PCIE:
+               return "Atheros 5416";
+       case AR9160_DEVID_PCI:
+               return "Atheros 9160";
+       case AR9280_DEVID_PCI:
+       case AR9280_DEVID_PCIE:
+               return "Atheros 9280";
        }
 
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               if (IS_CHAN_2GHZ(chan)) {
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
-                                                 AR_AN_RF2G1_CH0_OB,
-                                                 AR_AN_RF2G1_CH0_OB_S,
-                                                 pModal->ob);
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
-                                                 AR_AN_RF2G1_CH0_DB,
-                                                 AR_AN_RF2G1_CH0_DB_S,
-                                                 pModal->db);
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
-                                                 AR_AN_RF2G1_CH1_OB,
-                                                 AR_AN_RF2G1_CH1_OB_S,
-                                                 pModal->ob_ch1);
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
-                                                 AR_AN_RF2G1_CH1_DB,
-                                                 AR_AN_RF2G1_CH1_DB_S,
-                                                 pModal->db_ch1);
-               } else {
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
-                                                 AR_AN_RF5G1_CH0_OB5,
-                                                 AR_AN_RF5G1_CH0_OB5_S,
-                                                 pModal->ob);
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
-                                                 AR_AN_RF5G1_CH0_DB5,
-                                                 AR_AN_RF5G1_CH0_DB5_S,
-                                                 pModal->db);
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
-                                                 AR_AN_RF5G1_CH1_OB5,
-                                                 AR_AN_RF5G1_CH1_OB5_S,
-                                                 pModal->ob_ch1);
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
-                                                 AR_AN_RF5G1_CH1_DB5,
-                                                 AR_AN_RF5G1_CH1_DB5_S,
-                                                 pModal->db_ch1);
-               }
-               ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
-                                         AR_AN_TOP2_XPABIAS_LVL,
-                                         AR_AN_TOP2_XPABIAS_LVL_S,
-                                         pModal->xpaBiasLvl);
-               ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
-                                         AR_AN_TOP2_LOCALBIAS,
-                                         AR_AN_TOP2_LOCALBIAS_S,
-                                         pModal->local_bias);
-               DPRINTF(ah->ah_sc, ATH_DBG_ANY, "ForceXPAon: %d\n",
-                       pModal->force_xpaon);
-               REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
-                             pModal->force_xpaon);
-       }
+       return NULL;
+}
 
-       REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
-                     pModal->switchSettling);
-       REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
-                     pModal->adcDesiredSize);
+static void ath9k_hw_set_defaults(struct ath_hal *ah)
+{
+       int i;
 
-       if (!AR_SREV_9280_10_OR_LATER(ah))
-               REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
-                             AR_PHY_DESIRED_SZ_PGA,
-                             pModal->pgaDesiredSize);
-
-       REG_WRITE(ah, AR_PHY_RF_CTL4,
-                 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
-                 | SM(pModal->txEndToXpaOff,
-                      AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
-                 | SM(pModal->txFrameToXpaOn,
-                      AR_PHY_RF_CTL4_FRAME_XPAA_ON)
-                 | SM(pModal->txFrameToXpaOn,
-                      AR_PHY_RF_CTL4_FRAME_XPAB_ON));
-
-       REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
-                     pModal->txEndToRxOn);
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
-                             pModal->thresh62);
-               REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
-                             AR_PHY_EXT_CCA0_THRESH62,
-                             pModal->thresh62);
-       } else {
-               REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
-                             pModal->thresh62);
-               REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
-                             AR_PHY_EXT_CCA_THRESH62,
-                             pModal->thresh62);
-       }
-
-       if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-           AR5416_EEP_MINOR_VER_2) {
-               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
-                             AR_PHY_TX_END_DATA_START,
-                             pModal->txFrameToDataStart);
-               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
-                             pModal->txFrameToPaOn);
-       }
-
-       if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-           AR5416_EEP_MINOR_VER_3) {
-               if (IS_CHAN_HT40(chan))
-                       REG_RMW_FIELD(ah, AR_PHY_SETTLING,
-                                     AR_PHY_SETTLING_SWITCH,
-                                     pModal->swSettleHt40);
-       }
-
-       return true;
-}
-
-static int ath9k_hw_check_eeprom(struct ath_hal *ah)
-{
-       u32 sum = 0, el;
-       u16 *eepdata;
-       int i;
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       bool need_swap = false;
-       struct ar5416_eeprom *eep =
-               (struct ar5416_eeprom *) &ahp->ah_eeprom;
-
-       if (!ath9k_hw_use_flash(ah)) {
-               u16 magic, magic2;
-               int addr;
-
-               if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
-                                       &magic)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                                "%s: Reading Magic # failed\n", __func__);
-                       return false;
-               }
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "%s: Read Magic = 0x%04X\n",
-                        __func__, magic);
-
-               if (magic != AR5416_EEPROM_MAGIC) {
-                       magic2 = swab16(magic);
-
-                       if (magic2 == AR5416_EEPROM_MAGIC) {
-                               need_swap = true;
-                               eepdata = (u16 *) (&ahp->ah_eeprom);
-
-                               for (addr = 0;
-                                    addr <
-                                            sizeof(struct ar5416_eeprom) /
-                                            sizeof(u16); addr++) {
-                                       u16 temp;
-
-                                       temp = swab16(*eepdata);
-                                       *eepdata = temp;
-                                       eepdata++;
-
-                                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                                                "0x%04X  ", *eepdata);
-                                       if (((addr + 1) % 6) == 0)
-                                               DPRINTF(ah->ah_sc,
-                                                        ATH_DBG_EEPROM,
-                                                        "\n");
-                               }
-                       } else {
-                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                                        "Invalid EEPROM Magic. "
-                                       "endianness missmatch.\n");
-                               return -EINVAL;
-                       }
-               }
-       }
-       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
-                need_swap ? "True" : "False");
-
-       if (need_swap)
-               el = swab16(ahp->ah_eeprom.baseEepHeader.length);
-       else
-               el = ahp->ah_eeprom.baseEepHeader.length;
-
-       if (el > sizeof(struct ar5416_eeprom))
-               el = sizeof(struct ar5416_eeprom) / sizeof(u16);
-       else
-               el = el / sizeof(u16);
-
-       eepdata = (u16 *) (&ahp->ah_eeprom);
-
-       for (i = 0; i < el; i++)
-               sum ^= *eepdata++;
-
-       if (need_swap) {
-               u32 integer, j;
-               u16 word;
-
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                        "EEPROM Endianness is not native.. Changing \n");
-
-               word = swab16(eep->baseEepHeader.length);
-               eep->baseEepHeader.length = word;
-
-               word = swab16(eep->baseEepHeader.checksum);
-               eep->baseEepHeader.checksum = word;
-
-               word = swab16(eep->baseEepHeader.version);
-               eep->baseEepHeader.version = word;
-
-               word = swab16(eep->baseEepHeader.regDmn[0]);
-               eep->baseEepHeader.regDmn[0] = word;
-
-               word = swab16(eep->baseEepHeader.regDmn[1]);
-               eep->baseEepHeader.regDmn[1] = word;
-
-               word = swab16(eep->baseEepHeader.rfSilent);
-               eep->baseEepHeader.rfSilent = word;
-
-               word = swab16(eep->baseEepHeader.blueToothOptions);
-               eep->baseEepHeader.blueToothOptions = word;
-
-               word = swab16(eep->baseEepHeader.deviceCap);
-               eep->baseEepHeader.deviceCap = word;
-
-               for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
-                       struct modal_eep_header *pModal =
-                               &eep->modalHeader[j];
-                       integer = swab32(pModal->antCtrlCommon);
-                       pModal->antCtrlCommon = integer;
-
-                       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-                               integer = swab32(pModal->antCtrlChain[i]);
-                               pModal->antCtrlChain[i] = integer;
-                       }
-
-                       for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
-                               word = swab16(pModal->spurChans[i].spurChan);
-                               pModal->spurChans[i].spurChan = word;
-                       }
-               }
-       }
-
-       if (sum != 0xffff || ar5416_get_eep_ver(ahp) != AR5416_EEP_VER ||
-           ar5416_get_eep_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                        "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
-                        sum, ar5416_get_eep_ver(ahp));
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static bool ath9k_hw_chip_test(struct ath_hal *ah)
-{
-       u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
-       u32 regHold[2];
-       u32 patternData[4] = { 0x55555555,
-                                    0xaaaaaaaa,
-                                    0x66666666,
-                                    0x99999999 };
-       int i, j;
-
-       for (i = 0; i < 2; i++) {
-               u32 addr = regAddr[i];
-               u32 wrData, rdData;
-
-               regHold[i] = REG_READ(ah, addr);
-               for (j = 0; j < 0x100; j++) {
-                       wrData = (j << 16) | j;
-                       REG_WRITE(ah, addr, wrData);
-                       rdData = REG_READ(ah, addr);
-                       if (rdData != wrData) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                                "%s: address test failed "
-                               "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
-                                __func__, addr, wrData, rdData);
-                               return false;
-                       }
-               }
-               for (j = 0; j < 4; j++) {
-                       wrData = patternData[j];
-                       REG_WRITE(ah, addr, wrData);
-                       rdData = REG_READ(ah, addr);
-                       if (wrData != rdData) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                                "%s: address test failed "
-                               "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
-                                __func__, addr, wrData, rdData);
-                               return false;
-                       }
-               }
-               REG_WRITE(ah, regAddr[i], regHold[i]);
-       }
-       udelay(100);
-       return true;
-}
-
-u32 ath9k_hw_getrxfilter(struct ath_hal *ah)
-{
-       u32 bits = REG_READ(ah, AR_RX_FILTER);
-       u32 phybits = REG_READ(ah, AR_PHY_ERR);
-
-       if (phybits & AR_PHY_ERR_RADAR)
-               bits |= ATH9K_RX_FILTER_PHYRADAR;
-       if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING))
-               bits |= ATH9K_RX_FILTER_PHYERR;
-       return bits;
-}
-
-void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits)
-{
-       u32 phybits;
-
-       REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff) | AR_RX_COMPR_BAR);
-       phybits = 0;
-       if (bits & ATH9K_RX_FILTER_PHYRADAR)
-               phybits |= AR_PHY_ERR_RADAR;
-       if (bits & ATH9K_RX_FILTER_PHYERR)
-               phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
-       REG_WRITE(ah, AR_PHY_ERR, phybits);
-
-       if (phybits)
-               REG_WRITE(ah, AR_RXCFG,
-                         REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
-       else
-               REG_WRITE(ah, AR_RXCFG,
-                         REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
-}
-
-bool ath9k_hw_setcapability(struct ath_hal *ah,
-                           enum ath9k_capability_type type,
-                           u32 capability,
-                           u32 setting,
-                           int *status)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       u32 v;
-
-       switch (type) {
-       case ATH9K_CAP_TKIP_MIC:
-               if (setting)
-                       ahp->ah_staId1Defaults |=
-                               AR_STA_ID1_CRPT_MIC_ENABLE;
-               else
-                       ahp->ah_staId1Defaults &=
-                               ~AR_STA_ID1_CRPT_MIC_ENABLE;
-               return true;
-       case ATH9K_CAP_DIVERSITY:
-               v = REG_READ(ah, AR_PHY_CCK_DETECT);
-               if (setting)
-                       v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
-               else
-                       v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
-               REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
-               return true;
-       case ATH9K_CAP_MCAST_KEYSRCH:
-               if (setting)
-                       ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
-               else
-                       ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
-               return true;
-       case ATH9K_CAP_TSF_ADJUST:
-               if (setting)
-                       ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
-               else
-                       ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
-               return true;
-       default:
-               return false;
-       }
-}
-
-void ath9k_hw_dmaRegDump(struct ath_hal *ah)
-{
-       u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
-       int qcuOffset = 0, dcuOffset = 0;
-       u32 *qcuBase = &val[0], *dcuBase = &val[4];
-       int i;
-
-       REG_WRITE(ah, AR_MACMISC,
-                 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
-                  (AR_MACMISC_MISC_OBS_BUS_1 <<
-                   AR_MACMISC_MISC_OBS_BUS_MSB_S)));
-
-       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "Raw DMA Debug values:\n");
-       for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
-               if (i % 4 == 0)
-                       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
-
-               val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
-               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "%d: %08x ", i, val[i]);
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n\n");
-       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
-
-       for (i = 0; i < ATH9K_NUM_QUEUES;
-            i++, qcuOffset += 4, dcuOffset += 5) {
-               if (i == 8) {
-                       qcuOffset = 0;
-                       qcuBase++;
-               }
-
-               if (i == 6) {
-                       dcuOffset = 0;
-                       dcuBase++;
-               }
-
-               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                        "%2d          %2x      %1x     %2x           %2x\n",
-                        i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
-                        (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset +
-                                                            3),
-                        val[2] & (0x7 << (i * 3)) >> (i * 3),
-                        (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
-       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                "qcu_stitch state:   %2x    qcu_fetch state:        %2x\n",
-                (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
-       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                "qcu_complete state: %2x    dcu_complete state:     %2x\n",
-                (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
-       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                "dcu_arb state:      %2x    dcu_fp state:           %2x\n",
-                (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
-       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                "chan_idle_dur:     %3d    chan_idle_dur_valid:     %1d\n",
-                (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
-       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                "txfifo_valid_0:      %1d    txfifo_valid_1:          %1d\n",
-                (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
-       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                "txfifo_dcu_num_0:   %2d    txfifo_dcu_num_1:       %2d\n",
-                (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
-
-       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "pcu observe 0x%x \n",
-               REG_READ(ah, AR_OBS_BUS_1));
-       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-               "AR_CR 0x%x \n", REG_READ(ah, AR_CR));
-}
-
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
-                                       u32 *rxc_pcnt,
-                                       u32 *rxf_pcnt,
-                                       u32 *txf_pcnt)
-{
-       static u32 cycles, rx_clear, rx_frame, tx_frame;
-       u32 good = 1;
-
-       u32 rc = REG_READ(ah, AR_RCCNT);
-       u32 rf = REG_READ(ah, AR_RFCNT);
-       u32 tf = REG_READ(ah, AR_TFCNT);
-       u32 cc = REG_READ(ah, AR_CCCNT);
+       ah->ah_config.dma_beacon_response_time = 2;
+       ah->ah_config.sw_beacon_response_time = 10;
+       ah->ah_config.additional_swba_backoff = 0;
+       ah->ah_config.ack_6mb = 0x0;
+       ah->ah_config.cwm_ignore_extcca = 0;
+       ah->ah_config.pcie_powersave_enable = 0;
+       ah->ah_config.pcie_l1skp_enable = 0;
+       ah->ah_config.pcie_clock_req = 0;
+       ah->ah_config.pcie_power_reset = 0x100;
+       ah->ah_config.pcie_restore = 0;
+       ah->ah_config.pcie_waen = 0;
+       ah->ah_config.analog_shiftreg = 1;
+       ah->ah_config.ht_enable = 1;
+       ah->ah_config.ofdm_trig_low = 200;
+       ah->ah_config.ofdm_trig_high = 500;
+       ah->ah_config.cck_trig_high = 200;
+       ah->ah_config.cck_trig_low = 100;
+       ah->ah_config.enable_ani = 1;
+       ah->ah_config.noise_immunity_level = 4;
+       ah->ah_config.ofdm_weaksignal_det = 1;
+       ah->ah_config.cck_weaksignal_thr = 0;
+       ah->ah_config.spur_immunity_level = 2;
+       ah->ah_config.firstep_level = 0;
+       ah->ah_config.rssi_thr_high = 40;
+       ah->ah_config.rssi_thr_low = 7;
+       ah->ah_config.diversity_control = 0;
+       ah->ah_config.antenna_switch_swap = 0;
 
-       if (cycles == 0 || cycles > cc) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-                        "%s: cycle counter wrap. ExtBusy = 0\n",
-                        __func__);
-               good = 0;
-       } else {
-               u32 cc_d = cc - cycles;
-               u32 rc_d = rc - rx_clear;
-               u32 rf_d = rf - rx_frame;
-               u32 tf_d = tf - tx_frame;
-
-               if (cc_d != 0) {
-                       *rxc_pcnt = rc_d * 100 / cc_d;
-                       *rxf_pcnt = rf_d * 100 / cc_d;
-                       *txf_pcnt = tf_d * 100 / cc_d;
-               } else {
-                       good = 0;
-               }
+       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+               ah->ah_config.spurchans[i][0] = AR_NO_SPUR;
+               ah->ah_config.spurchans[i][1] = AR_NO_SPUR;
        }
 
-       cycles = cc;
-       rx_frame = rf;
-       rx_clear = rc;
-       tx_frame = tf;
-
-       return good;
-}
-
-void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode)
-{
-       u32 macmode;
-
-       if (mode == ATH9K_HT_MACMODE_2040 &&
-           !ah->ah_config.cwm_ignore_extcca)
-               macmode = AR_2040_JOINED_RX_CLEAR;
-       else
-               macmode = 0;
-
-       REG_WRITE(ah, AR_2040_MODE, macmode);
-}
-
-static void ath9k_hw_mark_phy_inactive(struct ath_hal *ah)
-{
-       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
+       ah->ah_config.intr_mitigation = 1;
 }
 
-
 static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
                                              struct ath_softc *sc,
                                              void __iomem *mem,
@@ -1165,20 +447,17 @@ static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
        ahp = kzalloc(sizeof(struct ath_hal_5416), GFP_KERNEL);
        if (ahp == NULL) {
                DPRINTF(sc, ATH_DBG_FATAL,
-                        "%s: cannot allocate memory for state block\n",
-                        __func__);
+                       "%s: cannot allocate memory for state block\n",
+                       __func__);
                *status = -ENOMEM;
                return NULL;
        }
 
        ah = &ahp->ah;
-
        ah->ah_sc = sc;
        ah->ah_sh = mem;
-
        ah->ah_magic = AR5416_MAGIC;
        ah->ah_countryCode = CTRY_DEFAULT;
-
        ah->ah_devid = devid;
        ah->ah_subvendorid = 0;
 
@@ -1190,12 +469,10 @@ static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
 
        ah->ah_powerLimit = MAX_RATE_POWER;
        ah->ah_tpScale = ATH9K_TP_SCALE_MAX;
-
        ahp->ah_atimWindow = 0;
        ahp->ah_diversityControl = ah->ah_config.diversity_control;
        ahp->ah_antennaSwitchSwap =
                ah->ah_config.antenna_switch_swap;
-
        ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
        ahp->ah_beaconInterval = 100;
        ahp->ah_enable32kHzClock = DONT_USE_32KHZ;
@@ -1210,79 +487,49 @@ static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
        return ahp;
 }
 
-static int ath9k_hw_eeprom_attach(struct ath_hal *ah)
+static int ath9k_hw_rfattach(struct ath_hal *ah)
 {
-       int status;
-
-       if (ath9k_hw_use_flash(ah))
-               ath9k_hw_flash_map(ah);
-
-       if (!ath9k_hw_fill_eeprom(ah))
-               return -EIO;
+       bool rfStatus = false;
+       int ecode = 0;
 
-       status = ath9k_hw_check_eeprom(ah);
+       rfStatus = ath9k_hw_init_rf(ah, &ecode);
+       if (!rfStatus) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+                       "%s: RF setup failed, status %u\n", __func__,
+                       ecode);
+               return ecode;
+       }
 
-       return status;
+       return 0;
 }
 
-u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
-                             enum eeprom_param param)
+static int ath9k_hw_rf_claim(struct ath_hal *ah)
 {
-       struct ar5416_eeprom *eep = &ahp->ah_eeprom;
-       struct modal_eep_header *pModal = eep->modalHeader;
-       struct base_eep_header *pBase = &eep->baseEepHeader;
-
-       switch (param) {
-       case EEP_NFTHRESH_5:
-               return -pModal[0].noiseFloorThreshCh[0];
-       case EEP_NFTHRESH_2:
-               return -pModal[1].noiseFloorThreshCh[0];
-       case AR_EEPROM_MAC(0):
-               return pBase->macAddr[0] << 8 | pBase->macAddr[1];
-       case AR_EEPROM_MAC(1):
-               return pBase->macAddr[2] << 8 | pBase->macAddr[3];
-       case AR_EEPROM_MAC(2):
-               return pBase->macAddr[4] << 8 | pBase->macAddr[5];
-       case EEP_REG_0:
-               return pBase->regDmn[0];
-       case EEP_REG_1:
-               return pBase->regDmn[1];
-       case EEP_OP_CAP:
-               return pBase->deviceCap;
-       case EEP_OP_MODE:
-               return pBase->opCapFlags;
-       case EEP_RF_SILENT:
-               return pBase->rfSilent;
-       case EEP_OB_5:
-               return pModal[0].ob;
-       case EEP_DB_5:
-               return pModal[0].db;
-       case EEP_OB_2:
-               return pModal[1].ob;
-       case EEP_DB_2:
-               return pModal[1].db;
-       case EEP_MINOR_REV:
-               return pBase->version & AR5416_EEP_VER_MINOR_MASK;
-       case EEP_TX_MASK:
-               return pBase->txMask;
-       case EEP_RX_MASK:
-               return pBase->rxMask;
-       default:
-               return 0;
+       u32 val;
+
+       REG_WRITE(ah, AR_PHY(0), 0x00000007);
+
+       val = ath9k_hw_get_radiorev(ah);
+       switch (val & AR_RADIO_SREV_MAJOR) {
+       case 0:
+               val = AR_RAD5133_SREV_MAJOR;
+               break;
+       case AR_RAD5133_SREV_MAJOR:
+       case AR_RAD5122_SREV_MAJOR:
+       case AR_RAD2133_SREV_MAJOR:
+       case AR_RAD2122_SREV_MAJOR:
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
+                       "%s: 5G Radio Chip Rev 0x%02X is not "
+                       "supported by this driver\n",
+                       __func__, ah->ah_analog5GhzRev);
+               return -EOPNOTSUPP;
        }
-}
 
-static int ath9k_hw_get_radiorev(struct ath_hal *ah)
-{
-       u32 val;
-       int i;
+       ah->ah_analog5GhzRev = val;
 
-       REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
-       for (i = 0; i < 8; i++)
-               REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
-       val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
-       val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
-       return ath9k_hw_reverse_bits(val, 8);
+       return 0;
 }
 
 static int ath9k_hw_init_macaddr(struct ath_hal *ah)
@@ -1291,3833 +538,413 @@ static int ath9k_hw_init_macaddr(struct ath_hal *ah)
        int i;
        u16 eeval;
        struct ath_hal_5416 *ahp = AH5416(ah);
-       DECLARE_MAC_BUF(mac);
 
        sum = 0;
        for (i = 0; i < 3; i++) {
-               eeval = ath9k_hw_get_eeprom(ahp, AR_EEPROM_MAC(i));
+               eeval = ath9k_hw_get_eeprom(ah, AR_EEPROM_MAC(i));
                sum += eeval;
                ahp->ah_macaddr[2 * i] = eeval >> 8;
                ahp->ah_macaddr[2 * i + 1] = eeval & 0xff;
        }
        if (sum == 0 || sum == 0xffff * 3) {
                DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                        "%s: mac address read failed: %s\n", __func__,
-                        print_mac(mac, ahp->ah_macaddr));
+                       "%s: mac address read failed: %pM\n", __func__,
+                       ahp->ah_macaddr);
                return -EADDRNOTAVAIL;
        }
 
        return 0;
 }
 
-static inline int16_t ath9k_hw_interpolate(u16 target,
-                                          u16 srcLeft,
-                                          u16 srcRight,
-                                          int16_t targetLeft,
-                                          int16_t targetRight)
-{
-       int16_t rv;
-
-       if (srcRight == srcLeft) {
-               rv = targetLeft;
-       } else {
-               rv = (int16_t) (((target - srcLeft) * targetRight +
-                                (srcRight - target) * targetLeft) /
-                               (srcRight - srcLeft));
-       }
-       return rv;
-}
-
-static inline u16 ath9k_hw_fbin2freq(u8 fbin,
-                                          bool is2GHz)
-{
-
-       if (fbin == AR5416_BCHAN_UNUSED)
-               return fbin;
-
-       return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
-}
-
-static u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah,
-                                              u16 i,
-                                              bool is2GHz)
+static int ath9k_hw_post_attach(struct ath_hal *ah)
 {
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ar5416_eeprom *eep =
-               (struct ar5416_eeprom *) &ahp->ah_eeprom;
-       u16 spur_val = AR_NO_SPUR;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                "Getting spur idx %d is2Ghz. %d val %x\n",
-                i, is2GHz, ah->ah_config.spurchans[i][is2GHz]);
-
-       switch (ah->ah_config.spurmode) {
-       case SPUR_DISABLE:
-               break;
-       case SPUR_ENABLE_IOCTL:
-               spur_val = ah->ah_config.spurchans[i][is2GHz];
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                        "Getting spur val from new loc. %d\n", spur_val);
-               break;
-       case SPUR_ENABLE_EEPROM:
-               spur_val = eep->modalHeader[is2GHz].spurChans[i].spurChan;
-               break;
+       int ecode;
 
+       if (!ath9k_hw_chip_test(ah)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+                       "%s: hardware self-test failed\n", __func__);
+               return -ENODEV;
        }
-       return spur_val;
-}
-
-static int ath9k_hw_rfattach(struct ath_hal *ah)
-{
-       bool rfStatus = false;
-       int ecode = 0;
 
-       rfStatus = ath9k_hw_init_rf(ah, &ecode);
-       if (!rfStatus) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                        "%s: RF setup failed, status %u\n", __func__,
-                        ecode);
+       ecode = ath9k_hw_rf_claim(ah);
+       if (ecode != 0)
                return ecode;
-       }
-
-       return 0;
-}
-
-static int ath9k_hw_rf_claim(struct ath_hal *ah)
-{
-       u32 val;
 
-       REG_WRITE(ah, AR_PHY(0), 0x00000007);
+       ecode = ath9k_hw_eeprom_attach(ah);
+       if (ecode != 0)
+               return ecode;
+       ecode = ath9k_hw_rfattach(ah);
+       if (ecode != 0)
+               return ecode;
 
-       val = ath9k_hw_get_radiorev(ah);
-       switch (val & AR_RADIO_SREV_MAJOR) {
-       case 0:
-               val = AR_RAD5133_SREV_MAJOR;
-               break;
-       case AR_RAD5133_SREV_MAJOR:
-       case AR_RAD5122_SREV_MAJOR:
-       case AR_RAD2133_SREV_MAJOR:
-       case AR_RAD2122_SREV_MAJOR:
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-                        "%s: 5G Radio Chip Rev 0x%02X is not "
-                       "supported by this driver\n",
-                        __func__, ah->ah_analog5GhzRev);
-               return -EOPNOTSUPP;
+       if (!AR_SREV_9100(ah)) {
+               ath9k_hw_ani_setup(ah);
+               ath9k_hw_ani_attach(ah);
        }
 
-       ah->ah_analog5GhzRev = val;
-
        return 0;
 }
 
-static void ath9k_hw_init_pll(struct ath_hal *ah,
-                             struct ath9k_channel *chan)
+static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
+                                         void __iomem *mem, int *status)
 {
-       u32 pll;
-
-       if (AR_SREV_9100(ah)) {
-               if (chan && IS_CHAN_5GHZ(chan))
-                       pll = 0x1450;
-               else
-                       pll = 0x1458;
-       } else {
-               if (AR_SREV_9280_10_OR_LATER(ah)) {
-                       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
-
-                       if (chan && IS_CHAN_HALF_RATE(chan))
-                               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
-                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
-                               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
+       struct ath_hal_5416 *ahp;
+       struct ath_hal *ah;
+       int ecode;
+#ifndef CONFIG_SLOW_ANT_DIV
+       u32 i;
+       u32 j;
+#endif
 
-                       if (chan && IS_CHAN_5GHZ(chan)) {
-                               pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
+       ahp = ath9k_hw_newstate(devid, sc, mem, status);
+       if (ahp == NULL)
+               return NULL;
 
+       ah = &ahp->ah;
 
-                               if (AR_SREV_9280_20(ah)) {
-                                       if (((chan->channel % 20) == 0)
-                                           || ((chan->channel % 10) == 0))
-                                               pll = 0x2850;
-                                       else
-                                               pll = 0x142c;
-                               }
-                       } else {
-                               pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
-                       }
+       ath9k_hw_set_defaults(ah);
 
-               } else if (AR_SREV_9160_10_OR_LATER(ah)) {
+       if (ah->ah_config.intr_mitigation != 0)
+               ahp->ah_intrMitigation = true;
 
-                       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
+       if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't reset chip\n",
+                        __func__);
+               ecode = -EIO;
+               goto bad;
+       }
 
-                       if (chan && IS_CHAN_HALF_RATE(chan))
-                               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
-                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
-                               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
+       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't wakeup chip\n",
+                        __func__);
+               ecode = -EIO;
+               goto bad;
+       }
 
-                       if (chan && IS_CHAN_5GHZ(chan))
-                               pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
-                       else
-                               pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
+       if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) {
+               if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) {
+                       ah->ah_config.serialize_regmode =
+                               SER_REG_MODE_ON;
                } else {
-                       pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
-
-                       if (chan && IS_CHAN_HALF_RATE(chan))
-                               pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
-                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
-                               pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
-
-                       if (chan && IS_CHAN_5GHZ(chan))
-                               pll |= SM(0xa, AR_RTC_PLL_DIV);
-                       else
-                               pll |= SM(0xb, AR_RTC_PLL_DIV);
+                       ah->ah_config.serialize_regmode =
+                               SER_REG_MODE_OFF;
                }
        }
-       REG_WRITE(ah, (u16) (AR_RTC_PLL_CONTROL), pll);
-
-       udelay(RTC_PLL_SETTLE_DELAY);
-
-       REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
-}
 
-static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
-                             enum ath9k_ht_macmode macmode)
-{
-       u32 phymode;
-       struct ath_hal_5416 *ahp = AH5416(ah);
+       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+               "%s: serialize_regmode is %d\n",
+               __func__, ah->ah_config.serialize_regmode);
 
-       phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
-               | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH;
+       if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
+           (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
+           (ah->ah_macVersion != AR_SREV_VERSION_9160) &&
+           (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+                       "%s: Mac Chip Rev 0x%02x.%x is not supported by "
+                       "this driver\n", __func__,
+                       ah->ah_macVersion, ah->ah_macRev);
+               ecode = -EOPNOTSUPP;
+               goto bad;
+       }
 
-       if (IS_CHAN_HT40(chan)) {
-               phymode |= AR_PHY_FC_DYN2040_EN;
+       if (AR_SREV_9100(ah)) {
+               ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
+               ahp->ah_suppCals = IQ_MISMATCH_CAL;
+               ah->ah_isPciExpress = false;
+       }
+       ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
 
-               if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
-                   (chan->chanmode == CHANNEL_G_HT40PLUS))
-                       phymode |= AR_PHY_FC_DYN2040_PRI_CH;
+       if (AR_SREV_9160_10_OR_LATER(ah)) {
+               if (AR_SREV_9280_10_OR_LATER(ah)) {
+                       ahp->ah_iqCalData.calData = &iq_cal_single_sample;
+                       ahp->ah_adcGainCalData.calData =
+                               &adc_gain_cal_single_sample;
+                       ahp->ah_adcDcCalData.calData =
+                               &adc_dc_cal_single_sample;
+                       ahp->ah_adcDcCalInitData.calData =
+                               &adc_init_dc_cal;
+               } else {
+                       ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
+                       ahp->ah_adcGainCalData.calData =
+                               &adc_gain_cal_multi_sample;
+                       ahp->ah_adcDcCalData.calData =
+                               &adc_dc_cal_multi_sample;
+                       ahp->ah_adcDcCalInitData.calData =
+                               &adc_init_dc_cal;
+               }
+               ahp->ah_suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
+       }
 
-               if (ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
-                       phymode |= AR_PHY_FC_DYN2040_EXT_CH;
+       if (AR_SREV_9160(ah)) {
+               ah->ah_config.enable_ani = 1;
+               ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
+                                       ATH9K_ANI_FIRSTEP_LEVEL);
+       } else {
+               ahp->ah_ani_function = ATH9K_ANI_ALL;
+               if (AR_SREV_9280_10_OR_LATER(ah)) {
+                       ahp->ah_ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
+               }
        }
-       REG_WRITE(ah, AR_PHY_TURBO, phymode);
 
-       ath9k_hw_set11nmac2040(ah, macmode);
+       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+               "%s: This Mac Chip Rev 0x%02x.%x is \n", __func__,
+               ah->ah_macVersion, ah->ah_macRev);
 
-       REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
-       REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
-}
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
+                              ARRAY_SIZE(ar9280Modes_9280_2), 6);
+               INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
+                              ARRAY_SIZE(ar9280Common_9280_2), 2);
 
-static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
-{
-       u32 val;
-
-       val = REG_READ(ah, AR_STA_ID1);
-       val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
-       switch (opmode) {
-       case ATH9K_M_HOSTAP:
-               REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
-                         | AR_STA_ID1_KSRCH_MODE);
-               REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
-               break;
-       case ATH9K_M_IBSS:
-               REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
-                         | AR_STA_ID1_KSRCH_MODE);
-               REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
-               break;
-       case ATH9K_M_STA:
-       case ATH9K_M_MONITOR:
-               REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
-               break;
+               if (ah->ah_config.pcie_clock_req) {
+                       INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+                              ar9280PciePhy_clkreq_off_L1_9280,
+                              ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2);
+               } else {
+                       INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+                              ar9280PciePhy_clkreq_always_on_L1_9280,
+                              ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
+               }
+               INIT_INI_ARRAY(&ahp->ah_iniModesAdditional,
+                              ar9280Modes_fast_clock_9280_2,
+                              ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
+       } else if (AR_SREV_9280_10_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280,
+                              ARRAY_SIZE(ar9280Modes_9280), 6);
+               INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280,
+                              ARRAY_SIZE(ar9280Common_9280), 2);
+       } else if (AR_SREV_9160_10_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160,
+                              ARRAY_SIZE(ar5416Modes_9160), 6);
+               INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160,
+                              ARRAY_SIZE(ar5416Common_9160), 2);
+               INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160,
+                              ARRAY_SIZE(ar5416Bank0_9160), 2);
+               INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160,
+                              ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
+               INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160,
+                              ARRAY_SIZE(ar5416Bank1_9160), 2);
+               INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160,
+                              ARRAY_SIZE(ar5416Bank2_9160), 2);
+               INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160,
+                              ARRAY_SIZE(ar5416Bank3_9160), 3);
+               INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160,
+                              ARRAY_SIZE(ar5416Bank6_9160), 3);
+               INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160,
+                              ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
+               INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160,
+                              ARRAY_SIZE(ar5416Bank7_9160), 2);
+               if (AR_SREV_9160_11(ah)) {
+                       INIT_INI_ARRAY(&ahp->ah_iniAddac,
+                                      ar5416Addac_91601_1,
+                                      ARRAY_SIZE(ar5416Addac_91601_1), 2);
+               } else {
+                       INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160,
+                                      ARRAY_SIZE(ar5416Addac_9160), 2);
+               }
+       } else if (AR_SREV_9100_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100,
+                              ARRAY_SIZE(ar5416Modes_9100), 6);
+               INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100,
+                              ARRAY_SIZE(ar5416Common_9100), 2);
+               INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100,
+                              ARRAY_SIZE(ar5416Bank0_9100), 2);
+               INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100,
+                              ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
+               INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100,
+                              ARRAY_SIZE(ar5416Bank1_9100), 2);
+               INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100,
+                              ARRAY_SIZE(ar5416Bank2_9100), 2);
+               INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100,
+                              ARRAY_SIZE(ar5416Bank3_9100), 3);
+               INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100,
+                              ARRAY_SIZE(ar5416Bank6_9100), 3);
+               INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100,
+                              ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
+               INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100,
+                              ARRAY_SIZE(ar5416Bank7_9100), 2);
+               INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100,
+                              ARRAY_SIZE(ar5416Addac_9100), 2);
+       } else {
+               INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes,
+                              ARRAY_SIZE(ar5416Modes), 6);
+               INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common,
+                              ARRAY_SIZE(ar5416Common), 2);
+               INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0,
+                              ARRAY_SIZE(ar5416Bank0), 2);
+               INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain,
+                              ARRAY_SIZE(ar5416BB_RfGain), 3);
+               INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1,
+                              ARRAY_SIZE(ar5416Bank1), 2);
+               INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2,
+                              ARRAY_SIZE(ar5416Bank2), 2);
+               INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3,
+                              ARRAY_SIZE(ar5416Bank3), 3);
+               INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6,
+                              ARRAY_SIZE(ar5416Bank6), 3);
+               INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC,
+                              ARRAY_SIZE(ar5416Bank6TPC), 3);
+               INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7,
+                              ARRAY_SIZE(ar5416Bank7), 2);
+               INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac,
+                              ARRAY_SIZE(ar5416Addac), 2);
        }
-}
-
-static void
-ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
-{
-       u32 rfMode = 0;
-
-       if (chan == NULL)
-               return;
-
-       rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
-               ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
-
-       if (!AR_SREV_9280_10_OR_LATER(ah))
-               rfMode |= (IS_CHAN_5GHZ(chan)) ? AR_PHY_MODE_RF5GHZ :
-                       AR_PHY_MODE_RF2GHZ;
 
-       if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan))
-               rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
+       if (ah->ah_isPciExpress)
+               ath9k_hw_configpcipowersave(ah, 0);
+       else
+               ath9k_hw_disablepcie(ah);
 
-       REG_WRITE(ah, AR_PHY_MODE, rfMode);
-}
+       ecode = ath9k_hw_post_attach(ah);
+       if (ecode != 0)
+               goto bad;
 
-static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
-{
-       u32 rst_flags;
-       u32 tmpReg;
+#ifndef CONFIG_SLOW_ANT_DIV
+       if (ah->ah_devid == AR9280_DEVID_PCI) {
+               for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
+                       u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
 
-       REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
-                 AR_RTC_FORCE_WAKE_ON_INT);
+                       for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) {
+                               u32 val = INI_RA(&ahp->ah_iniModes, i, j);
 
-       if (AR_SREV_9100(ah)) {
-               rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD |
-                       AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
-       } else {
-               tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
-               if (tmpReg &
-                   (AR_INTR_SYNC_LOCAL_TIMEOUT |
-                    AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
-                       REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
-                       REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
-               } else {
-                       REG_WRITE(ah, AR_RC, AR_RC_AHB);
+                               INI_RA(&ahp->ah_iniModes, i, j) =
+                                       ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom,
+                                                          reg, val);
+                       }
                }
-
-               rst_flags = AR_RTC_RC_MAC_WARM;
-               if (type == ATH9K_RESET_COLD)
-                       rst_flags |= AR_RTC_RC_MAC_COLD;
+       }
+#endif
+       if (!ath9k_hw_fill_cap_info(ah)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+                       "%s:failed ath9k_hw_fill_cap_info\n", __func__);
+               ecode = -EINVAL;
+               goto bad;
        }
 
-       REG_WRITE(ah, (u16) (AR_RTC_RC), rst_flags);
-       udelay(50);
-
-       REG_WRITE(ah, (u16) (AR_RTC_RC), 0);
-       if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) {
+       ecode = ath9k_hw_init_macaddr(ah);
+       if (ecode != 0) {
                DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                       "%s: RTC stuck in MAC reset\n",
+                       "%s: failed initializing mac address\n",
                        __func__);
-               return false;
+               goto bad;
        }
 
-       if (!AR_SREV_9100(ah))
-               REG_WRITE(ah, AR_RC, 0);
+       if (AR_SREV_9285(ah))
+               ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S);
+       else
+               ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S);
 
-       ath9k_hw_init_pll(ah, NULL);
+       ath9k_init_nfcal_hist_buffer(ah);
 
-       if (AR_SREV_9100(ah))
-               udelay(50);
+       return ah;
+bad:
+       if (ahp)
+               ath9k_hw_detach((struct ath_hal *) ahp);
+       if (status)
+               *status = ecode;
 
-       return true;
+       return NULL;
 }
 
-static bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
+static void ath9k_hw_init_bb(struct ath_hal *ah,
+                            struct ath9k_channel *chan)
 {
-       REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
-                 AR_RTC_FORCE_WAKE_ON_INT);
-
-       REG_WRITE(ah, (u16) (AR_RTC_RESET), 0);
-       REG_WRITE(ah, (u16) (AR_RTC_RESET), 1);
+       u32 synthDelay;
 
-       if (!ath9k_hw_wait(ah,
-                          AR_RTC_STATUS,
-                          AR_RTC_STATUS_M,
-                          AR_RTC_STATUS_ON)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: RTC not waking up\n",
-                        __func__);
-               return false;
-       }
+       synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+       if (IS_CHAN_CCK(chan))
+               synthDelay = (4 * synthDelay) / 22;
+       else
+               synthDelay /= 10;
 
-       ath9k_hw_read_revisions(ah);
+       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
 
-       return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
+       udelay(synthDelay + BASE_ACTIVATE_DELAY);
 }
 
-static bool ath9k_hw_set_reset_reg(struct ath_hal *ah,
-                                  u32 type)
+static void ath9k_hw_init_qos(struct ath_hal *ah)
 {
-       REG_WRITE(ah, AR_RTC_FORCE_WAKE,
-                 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
+       REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
+       REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
 
-       switch (type) {
-       case ATH9K_RESET_POWER_ON:
-               return ath9k_hw_set_reset_power_on(ah);
-               break;
-       case ATH9K_RESET_WARM:
-       case ATH9K_RESET_COLD:
-               return ath9k_hw_set_reset(ah, type);
-               break;
-       default:
-               return false;
-       }
+       REG_WRITE(ah, AR_QOS_NO_ACK,
+                 SM(2, AR_QOS_NO_ACK_TWO_BIT) |
+                 SM(5, AR_QOS_NO_ACK_BIT_OFF) |
+                 SM(0, AR_QOS_NO_ACK_BYTE_OFF));
+
+       REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
+       REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
+       REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
+       REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
+       REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
 }
 
-static
-struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah,
-                                         struct ath9k_channel *chan)
+static void ath9k_hw_init_pll(struct ath_hal *ah,
+                             struct ath9k_channel *chan)
 {
-       if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-                        "%s: invalid channel %u/0x%x; not marked as "
-                        "2GHz or 5GHz\n", __func__, chan->channel,
-                        chan->channelFlags);
-               return NULL;
-       }
+       u32 pll;
 
-       if (!IS_CHAN_OFDM(chan) &&
-             !IS_CHAN_CCK(chan) &&
-             !IS_CHAN_HT20(chan) &&
-             !IS_CHAN_HT40(chan)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-                       "%s: invalid channel %u/0x%x; not marked as "
-                       "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
-                       __func__, chan->channel, chan->channelFlags);
-               return NULL;
-       }
-
-       return ath9k_regd_check_channel(ah, chan);
-}
-
-static inline bool
-ath9k_hw_get_lower_upper_index(u8 target,
-                              u8 *pList,
-                              u16 listSize,
-                              u16 *indexL,
-                              u16 *indexR)
-{
-       u16 i;
-
-       if (target <= pList[0]) {
-               *indexL = *indexR = 0;
-               return true;
-       }
-       if (target >= pList[listSize - 1]) {
-               *indexL = *indexR = (u16) (listSize - 1);
-               return true;
-       }
-
-       for (i = 0; i < listSize - 1; i++) {
-               if (pList[i] == target) {
-                       *indexL = *indexR = i;
-                       return true;
-               }
-               if (target < pList[i + 1]) {
-                       *indexL = i;
-                       *indexR = (u16) (i + 1);
-                       return false;
-               }
-       }
-       return false;
-}
-
-static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
-{
-       int16_t nfval;
-       int16_t sort[ATH9K_NF_CAL_HIST_MAX];
-       int i, j;
-
-       for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
-               sort[i] = nfCalBuffer[i];
-
-       for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
-               for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
-                       if (sort[j] > sort[j - 1]) {
-                               nfval = sort[j];
-                               sort[j] = sort[j - 1];
-                               sort[j - 1] = nfval;
-                       }
-               }
-       }
-       nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
-
-       return nfval;
-}
-
-static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
-                                             int16_t *nfarray)
-{
-       int i;
-
-       for (i = 0; i < NUM_NF_READINGS; i++) {
-               h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
-
-               if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
-                       h[i].currIndex = 0;
-
-               if (h[i].invalidNFcount > 0) {
-                       if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE
-                           || nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
-                               h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
-                       } else {
-                               h[i].invalidNFcount--;
-                               h[i].privNF = nfarray[i];
-                       }
-               } else {
-                       h[i].privNF =
-                               ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
-               }
-       }
-       return;
-}
-
-static void ar5416GetNoiseFloor(struct ath_hal *ah,
-                               int16_t nfarray[NUM_NF_READINGS])
-{
-       int16_t nf;
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
-       else
-               nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
-
-       if (nf & 0x100)
-               nf = 0 - ((nf ^ 0x1ff) + 1);
-       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                "NF calibrated [ctl] [chain 0] is %d\n", nf);
-       nfarray[0] = nf;
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
-                       AR9280_PHY_CH1_MINCCA_PWR);
-       else
-               nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
-                       AR_PHY_CH1_MINCCA_PWR);
-
-       if (nf & 0x100)
-               nf = 0 - ((nf ^ 0x1ff) + 1);
-       DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
-                "NF calibrated [ctl] [chain 1] is %d\n", nf);
-       nfarray[1] = nf;
-
-       if (!AR_SREV_9280(ah)) {
-               nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
-                       AR_PHY_CH2_MINCCA_PWR);
-               if (nf & 0x100)
-                       nf = 0 - ((nf ^ 0x1ff) + 1);
-               DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
-                        "NF calibrated [ctl] [chain 2] is %d\n", nf);
-               nfarray[2] = nf;
-       }
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
-                       AR9280_PHY_EXT_MINCCA_PWR);
-       else
-               nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
-                       AR_PHY_EXT_MINCCA_PWR);
-
-       if (nf & 0x100)
-               nf = 0 - ((nf ^ 0x1ff) + 1);
-       DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
-                "NF calibrated [ext] [chain 0] is %d\n", nf);
-       nfarray[3] = nf;
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
-                       AR9280_PHY_CH1_EXT_MINCCA_PWR);
-       else
-               nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
-                       AR_PHY_CH1_EXT_MINCCA_PWR);
-
-       if (nf & 0x100)
-               nf = 0 - ((nf ^ 0x1ff) + 1);
-       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                "NF calibrated [ext] [chain 1] is %d\n", nf);
-       nfarray[4] = nf;
-
-       if (!AR_SREV_9280(ah)) {
-               nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
-                       AR_PHY_CH2_EXT_MINCCA_PWR);
-               if (nf & 0x100)
-                       nf = 0 - ((nf ^ 0x1ff) + 1);
-               DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
-                        "NF calibrated [ext] [chain 2] is %d\n", nf);
-               nfarray[5] = nf;
-       }
-}
-
-static bool
-getNoiseFloorThresh(struct ath_hal *ah,
-                   const struct ath9k_channel *chan,
-                   int16_t *nft)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-
-       switch (chan->chanmode) {
-       case CHANNEL_A:
-       case CHANNEL_A_HT20:
-       case CHANNEL_A_HT40PLUS:
-       case CHANNEL_A_HT40MINUS:
-               *nft = (int16_t) ath9k_hw_get_eeprom(ahp, EEP_NFTHRESH_5);
-               break;
-       case CHANNEL_B:
-       case CHANNEL_G:
-       case CHANNEL_G_HT20:
-       case CHANNEL_G_HT40PLUS:
-       case CHANNEL_G_HT40MINUS:
-               *nft = (int16_t) ath9k_hw_get_eeprom(ahp, EEP_NFTHRESH_2);
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-                        "%s: invalid channel flags 0x%x\n", __func__,
-                        chan->channelFlags);
-               return false;
-       }
-       return true;
-}
-
-static void ath9k_hw_start_nfcal(struct ath_hal *ah)
-{
-       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
-                   AR_PHY_AGC_CONTROL_ENABLE_NF);
-       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
-                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
-       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
-}
-
-static void
-ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
-{
-       struct ath9k_nfcal_hist *h;
-       int i, j;
-       int32_t val;
-       const u32 ar5416_cca_regs[6] = {
-               AR_PHY_CCA,
-               AR_PHY_CH1_CCA,
-               AR_PHY_CH2_CCA,
-               AR_PHY_EXT_CCA,
-               AR_PHY_CH1_EXT_CCA,
-               AR_PHY_CH2_EXT_CCA
-       };
-       u8 chainmask;
-
-       if (AR_SREV_9280(ah))
-               chainmask = 0x1B;
-       else
-               chainmask = 0x3F;
-
-#ifdef ATH_NF_PER_CHAN
-       h = chan->nfCalHist;
-#else
-       h = ah->nfCalHist;
-#endif
-
-       for (i = 0; i < NUM_NF_READINGS; i++) {
-               if (chainmask & (1 << i)) {
-                       val = REG_READ(ah, ar5416_cca_regs[i]);
-                       val &= 0xFFFFFE00;
-                       val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
-                       REG_WRITE(ah, ar5416_cca_regs[i], val);
-               }
-       }
-
-       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-                   AR_PHY_AGC_CONTROL_ENABLE_NF);
-       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
-       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
-
-       for (j = 0; j < 1000; j++) {
-               if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
-                    AR_PHY_AGC_CONTROL_NF) == 0)
-                       break;
-               udelay(10);
-       }
-
-       for (i = 0; i < NUM_NF_READINGS; i++) {
-               if (chainmask & (1 << i)) {
-                       val = REG_READ(ah, ar5416_cca_regs[i]);
-                       val &= 0xFFFFFE00;
-                       val |= (((u32) (-50) << 1) & 0x1ff);
-                       REG_WRITE(ah, ar5416_cca_regs[i], val);
-               }
-       }
-}
-
-static int16_t ath9k_hw_getnf(struct ath_hal *ah,
-                             struct ath9k_channel *chan)
-{
-       int16_t nf, nfThresh;
-       int16_t nfarray[NUM_NF_READINGS] = { 0 };
-       struct ath9k_nfcal_hist *h;
-       u8 chainmask;
-
-       if (AR_SREV_9280(ah))
-               chainmask = 0x1B;
-       else
-               chainmask = 0x3F;
-
-       chan->channelFlags &= (~CHANNEL_CW_INT);
-       if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "%s: NF did not complete in calibration window\n",
-                        __func__);
-               nf = 0;
-               chan->rawNoiseFloor = nf;
-               return chan->rawNoiseFloor;
-       } else {
-               ar5416GetNoiseFloor(ah, nfarray);
-               nf = nfarray[0];
-               if (getNoiseFloorThresh(ah, chan, &nfThresh)
-                   && nf > nfThresh) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                "%s: noise floor failed detected; "
-                                "detected %d, threshold %d\n", __func__,
-                                nf, nfThresh);
-                       chan->channelFlags |= CHANNEL_CW_INT;
-               }
-       }
-
-#ifdef ATH_NF_PER_CHAN
-       h = chan->nfCalHist;
-#else
-       h = ah->nfCalHist;
-#endif
-
-       ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
-       chan->rawNoiseFloor = h[0].privNF;
-
-       return chan->rawNoiseFloor;
-}
-
-static void ath9k_hw_update_mibstats(struct ath_hal *ah,
-                             struct ath9k_mib_stats *stats)
-{
-       stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
-       stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
-       stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
-       stats->rts_good += REG_READ(ah, AR_RTS_OK);
-       stats->beacons += REG_READ(ah, AR_BEACON_CNT);
-}
-
-static void ath9k_enable_mib_counters(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable mib counters\n");
-
-       ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
-
-       REG_WRITE(ah, AR_FILT_OFDM, 0);
-       REG_WRITE(ah, AR_FILT_CCK, 0);
-       REG_WRITE(ah, AR_MIBC,
-                 ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS)
-                 & 0x0f);
-       REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
-       REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
-}
-
-static void ath9k_hw_disable_mib_counters(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disabling MIB counters\n");
-
-       REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC);
-
-       ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
-
-       REG_WRITE(ah, AR_FILT_OFDM, 0);
-       REG_WRITE(ah, AR_FILT_CCK, 0);
-}
-
-static int ath9k_hw_get_ani_channel_idx(struct ath_hal *ah,
-                                       struct ath9k_channel *chan)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
-               if (ahp->ah_ani[i].c.channel == chan->channel)
-                       return i;
-               if (ahp->ah_ani[i].c.channel == 0) {
-                       ahp->ah_ani[i].c.channel = chan->channel;
-                       ahp->ah_ani[i].c.channelFlags = chan->channelFlags;
-                       return i;
-               }
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                "No more channel states left. Using channel 0\n");
-       return 0;
-}
-
-static void ath9k_hw_ani_attach(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       int i;
-
-       ahp->ah_hasHwPhyCounters = 1;
-
-       memset(ahp->ah_ani, 0, sizeof(ahp->ah_ani));
-       for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
-               ahp->ah_ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
-               ahp->ah_ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
-               ahp->ah_ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
-               ahp->ah_ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
-               ahp->ah_ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
-               ahp->ah_ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
-               ahp->ah_ani[i].ofdmWeakSigDetectOff =
-                       !ATH9K_ANI_USE_OFDM_WEAK_SIG;
-               ahp->ah_ani[i].cckWeakSigThreshold =
-                       ATH9K_ANI_CCK_WEAK_SIG_THR;
-               ahp->ah_ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
-               ahp->ah_ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
-               if (ahp->ah_hasHwPhyCounters) {
-                       ahp->ah_ani[i].ofdmPhyErrBase =
-                               AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
-                       ahp->ah_ani[i].cckPhyErrBase =
-                               AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
-               }
-       }
-       if (ahp->ah_hasHwPhyCounters) {
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                       "Setting OfdmErrBase = 0x%08x\n",
-                       ahp->ah_ani[0].ofdmPhyErrBase);
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
-                       ahp->ah_ani[0].cckPhyErrBase);
-
-               REG_WRITE(ah, AR_PHY_ERR_1, ahp->ah_ani[0].ofdmPhyErrBase);
-               REG_WRITE(ah, AR_PHY_ERR_2, ahp->ah_ani[0].cckPhyErrBase);
-               ath9k_enable_mib_counters(ah);
-       }
-       ahp->ah_aniPeriod = ATH9K_ANI_PERIOD;
-       if (ah->ah_config.enable_ani)
-               ahp->ah_procPhyErr |= HAL_PROCESS_ANI;
-}
-
-static void ath9k_hw_ani_setup(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       int i;
-
-       const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
-       const int coarseHigh[] = { -14, -14, -14, -14, -12 };
-       const int coarseLow[] = { -64, -64, -64, -64, -70 };
-       const int firpwr[] = { -78, -78, -78, -78, -80 };
-
-       for (i = 0; i < 5; i++) {
-               ahp->ah_totalSizeDesired[i] = totalSizeDesired[i];
-               ahp->ah_coarseHigh[i] = coarseHigh[i];
-               ahp->ah_coarseLow[i] = coarseLow[i];
-               ahp->ah_firpwr[i] = firpwr[i];
-       }
-}
-
-static void ath9k_hw_ani_detach(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detaching Ani\n");
-       if (ahp->ah_hasHwPhyCounters) {
-               ath9k_hw_disable_mib_counters(ah);
-               REG_WRITE(ah, AR_PHY_ERR_1, 0);
-               REG_WRITE(ah, AR_PHY_ERR_2, 0);
-       }
-}
-
-
-static bool ath9k_hw_ani_control(struct ath_hal *ah,
-                                enum ath9k_ani_cmd cmd, int param)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ar5416AniState *aniState = ahp->ah_curani;
-
-       switch (cmd & ahp->ah_ani_function) {
-       case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
-               u32 level = param;
-
-               if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                                "%s: level out of range (%u > %u)\n",
-                                __func__, level,
-                                (unsigned) ARRAY_SIZE(ahp->
-                                                      ah_totalSizeDesired));
-                       return false;
-               }
-
-               REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
-                             AR_PHY_DESIRED_SZ_TOT_DES,
-                             ahp->ah_totalSizeDesired[level]);
-               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
-                             AR_PHY_AGC_CTL1_COARSE_LOW,
-                             ahp->ah_coarseLow[level]);
-               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
-                             AR_PHY_AGC_CTL1_COARSE_HIGH,
-                             ahp->ah_coarseHigh[level]);
-               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
-                             AR_PHY_FIND_SIG_FIRPWR,
-                             ahp->ah_firpwr[level]);
-
-               if (level > aniState->noiseImmunityLevel)
-                       ahp->ah_stats.ast_ani_niup++;
-               else if (level < aniState->noiseImmunityLevel)
-                       ahp->ah_stats.ast_ani_nidown++;
-               aniState->noiseImmunityLevel = level;
-               break;
-       }
-       case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
-               const int m1ThreshLow[] = { 127, 50 };
-               const int m2ThreshLow[] = { 127, 40 };
-               const int m1Thresh[] = { 127, 0x4d };
-               const int m2Thresh[] = { 127, 0x40 };
-               const int m2CountThr[] = { 31, 16 };
-               const int m2CountThrLow[] = { 63, 48 };
-               u32 on = param ? 1 : 0;
-
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-                             AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
-                             m1ThreshLow[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-                             AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
-                             m2ThreshLow[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-                             AR_PHY_SFCORR_M1_THRESH,
-                             m1Thresh[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-                             AR_PHY_SFCORR_M2_THRESH,
-                             m2Thresh[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-                             AR_PHY_SFCORR_M2COUNT_THR,
-                             m2CountThr[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-                             AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
-                             m2CountThrLow[on]);
-
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-                             AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
-                             m1ThreshLow[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-                             AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
-                             m2ThreshLow[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-                             AR_PHY_SFCORR_EXT_M1_THRESH,
-                             m1Thresh[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-                             AR_PHY_SFCORR_EXT_M2_THRESH,
-                             m2Thresh[on]);
-
-               if (on)
-                       REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
-                                   AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+       if (AR_SREV_9100(ah)) {
+               if (chan && IS_CHAN_5GHZ(chan))
+                       pll = 0x1450;
                else
-                       REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
-                                   AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
-
-               if (!on != aniState->ofdmWeakSigDetectOff) {
-                       if (on)
-                               ahp->ah_stats.ast_ani_ofdmon++;
-                       else
-                               ahp->ah_stats.ast_ani_ofdmoff++;
-                       aniState->ofdmWeakSigDetectOff = !on;
-               }
-               break;
-       }
-       case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
-               const int weakSigThrCck[] = { 8, 6 };
-               u32 high = param ? 1 : 0;
-
-               REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
-                             AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
-                             weakSigThrCck[high]);
-               if (high != aniState->cckWeakSigThreshold) {
-                       if (high)
-                               ahp->ah_stats.ast_ani_cckhigh++;
-                       else
-                               ahp->ah_stats.ast_ani_ccklow++;
-                       aniState->cckWeakSigThreshold = high;
-               }
-               break;
-       }
-       case ATH9K_ANI_FIRSTEP_LEVEL:{
-               const int firstep[] = { 0, 4, 8 };
-               u32 level = param;
-
-               if (level >= ARRAY_SIZE(firstep)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                                "%s: level out of range (%u > %u)\n",
-                                __func__, level,
-                               (unsigned) ARRAY_SIZE(firstep));
-                       return false;
-               }
-               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
-                             AR_PHY_FIND_SIG_FIRSTEP,
-                             firstep[level]);
-               if (level > aniState->firstepLevel)
-                       ahp->ah_stats.ast_ani_stepup++;
-               else if (level < aniState->firstepLevel)
-                       ahp->ah_stats.ast_ani_stepdown++;
-               aniState->firstepLevel = level;
-               break;
-       }
-       case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
-               const int cycpwrThr1[] =
-                       { 2, 4, 6, 8, 10, 12, 14, 16 };
-               u32 level = param;
-
-               if (level >= ARRAY_SIZE(cycpwrThr1)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                                "%s: level out of range (%u > %u)\n",
-                                __func__, level,
-                                (unsigned)
-                               ARRAY_SIZE(cycpwrThr1));
-                       return false;
-               }
-               REG_RMW_FIELD(ah, AR_PHY_TIMING5,
-                             AR_PHY_TIMING5_CYCPWR_THR1,
-                             cycpwrThr1[level]);
-               if (level > aniState->spurImmunityLevel)
-                       ahp->ah_stats.ast_ani_spurup++;
-               else if (level < aniState->spurImmunityLevel)
-                       ahp->ah_stats.ast_ani_spurdown++;
-               aniState->spurImmunityLevel = level;
-               break;
-       }
-       case ATH9K_ANI_PRESENT:
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                       "%s: invalid cmd %u\n", __func__, cmd);
-               return false;
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "%s: ANI parameters:\n", __func__);
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-               "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
-               "ofdmWeakSigDetectOff=%d\n",
-                aniState->noiseImmunityLevel, aniState->spurImmunityLevel,
-                !aniState->ofdmWeakSigDetectOff);
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-               "cckWeakSigThreshold=%d, "
-               "firstepLevel=%d, listenTime=%d\n",
-                aniState->cckWeakSigThreshold, aniState->firstepLevel,
-                aniState->listenTime);
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
-                aniState->cycleCount, aniState->ofdmPhyErrCount,
-                aniState->cckPhyErrCount);
-       return true;
-}
-
-static void ath9k_ani_restart(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ar5416AniState *aniState;
-
-       if (!DO_ANI(ah))
-               return;
-
-       aniState = ahp->ah_curani;
-
-       aniState->listenTime = 0;
-       if (ahp->ah_hasHwPhyCounters) {
-               if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
-                       aniState->ofdmPhyErrBase = 0;
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                                "OFDM Trigger is too high for hw counters\n");
-               } else {
-                       aniState->ofdmPhyErrBase =
-                               AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
-               }
-               if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
-                       aniState->cckPhyErrBase = 0;
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                                "CCK Trigger is too high for hw counters\n");
-               } else {
-                       aniState->cckPhyErrBase =
-                               AR_PHY_COUNTMAX - aniState->cckTrigHigh;
-               }
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                        "%s: Writing ofdmbase=%u   cckbase=%u\n",
-                        __func__, aniState->ofdmPhyErrBase,
-                        aniState->cckPhyErrBase);
-               REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
-               REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
-               REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
-               REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
-
-               ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
-       }
-       aniState->ofdmPhyErrCount = 0;
-       aniState->cckPhyErrCount = 0;
-}
-
-static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ath9k_channel *chan = ah->ah_curchan;
-       struct ar5416AniState *aniState;
-       enum wireless_mode mode;
-       int32_t rssi;
-
-       if (!DO_ANI(ah))
-               return;
+                       pll = 0x1458;
+       } else {
+               if (AR_SREV_9280_10_OR_LATER(ah)) {
+                       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
 
-       aniState = ahp->ah_curani;
+                       if (chan && IS_CHAN_HALF_RATE(chan))
+                               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
+                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
+                               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
 
-       if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
-               if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
-                                        aniState->noiseImmunityLevel + 1)) {
-                       return;
-               }
-       }
+                       if (chan && IS_CHAN_5GHZ(chan)) {
+                               pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
 
-       if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
-               if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
-                                        aniState->spurImmunityLevel + 1)) {
-                       return;
-               }
-       }
 
-       if (ah->ah_opmode == ATH9K_M_HOSTAP) {
-               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
-                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                            aniState->firstepLevel + 1);
-               }
-               return;
-       }
-       rssi = BEACON_RSSI(ahp);
-       if (rssi > aniState->rssiThrHigh) {
-               if (!aniState->ofdmWeakSigDetectOff) {
-                       if (ath9k_hw_ani_control(ah,
-                                        ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                        false)) {
-                               ath9k_hw_ani_control(ah,
-                                       ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
-                                       0);
-                               return;
-                       }
-               }
-               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
-                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                            aniState->firstepLevel + 1);
-                       return;
-               }
-       } else if (rssi > aniState->rssiThrLow) {
-               if (aniState->ofdmWeakSigDetectOff)
-                       ath9k_hw_ani_control(ah,
-                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                    true);
-               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
-                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                            aniState->firstepLevel + 1);
-               return;
-       } else {
-               mode = ath9k_hw_chan2wmode(ah, chan);
-               if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
-                       if (!aniState->ofdmWeakSigDetectOff)
-                               ath9k_hw_ani_control(ah,
-                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                    false);
-                       if (aniState->firstepLevel > 0)
-                               ath9k_hw_ani_control(ah,
-                                                    ATH9K_ANI_FIRSTEP_LEVEL,
-                                                    0);
-                       return;
-               }
-       }
-}
-
-static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ath9k_channel *chan = ah->ah_curchan;
-       struct ar5416AniState *aniState;
-       enum wireless_mode mode;
-       int32_t rssi;
-
-       if (!DO_ANI(ah))
-               return;
-
-       aniState = ahp->ah_curani;
-       if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
-               if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
-                                        aniState->noiseImmunityLevel + 1)) {
-                       return;
-               }
-       }
-       if (ah->ah_opmode == ATH9K_M_HOSTAP) {
-               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
-                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                            aniState->firstepLevel + 1);
-               }
-               return;
-       }
-       rssi = BEACON_RSSI(ahp);
-       if (rssi > aniState->rssiThrLow) {
-               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
-                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                            aniState->firstepLevel + 1);
-       } else {
-               mode = ath9k_hw_chan2wmode(ah, chan);
-               if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
-                       if (aniState->firstepLevel > 0)
-                               ath9k_hw_ani_control(ah,
-                                                    ATH9K_ANI_FIRSTEP_LEVEL,
-                                                    0);
-               }
-       }
-}
-
-static void ath9k_ani_reset(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ar5416AniState *aniState;
-       struct ath9k_channel *chan = ah->ah_curchan;
-       int index;
-
-       if (!DO_ANI(ah))
-               return;
-
-       index = ath9k_hw_get_ani_channel_idx(ah, chan);
-       aniState = &ahp->ah_ani[index];
-       ahp->ah_curani = aniState;
-
-       if (DO_ANI(ah) && ah->ah_opmode != ATH9K_M_STA
-           && ah->ah_opmode != ATH9K_M_IBSS) {
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                        "%s: Reset ANI state opmode %u\n", __func__,
-                        ah->ah_opmode);
-               ahp->ah_stats.ast_ani_reset++;
-               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
-               ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
-               ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
-               ath9k_hw_ani_control(ah,
-                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                    !ATH9K_ANI_USE_OFDM_WEAK_SIG);
-               ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
-                                    ATH9K_ANI_CCK_WEAK_SIG_THR);
-               ath9k_hw_setrxfilter(ah,
-                                    ath9k_hw_getrxfilter(ah) |
-                                    ATH9K_RX_FILTER_PHYERR);
-               if (ah->ah_opmode == ATH9K_M_HOSTAP) {
-                       ahp->ah_curani->ofdmTrigHigh =
-                               ah->ah_config.ofdm_trig_high;
-                       ahp->ah_curani->ofdmTrigLow =
-                               ah->ah_config.ofdm_trig_low;
-                       ahp->ah_curani->cckTrigHigh =
-                               ah->ah_config.cck_trig_high;
-                       ahp->ah_curani->cckTrigLow =
-                               ah->ah_config.cck_trig_low;
-               }
-               ath9k_ani_restart(ah);
-               return;
-       }
-
-       if (aniState->noiseImmunityLevel != 0)
-               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
-                                    aniState->noiseImmunityLevel);
-       if (aniState->spurImmunityLevel != 0)
-               ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
-                                    aniState->spurImmunityLevel);
-       if (aniState->ofdmWeakSigDetectOff)
-               ath9k_hw_ani_control(ah,
-                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                    !aniState->ofdmWeakSigDetectOff);
-       if (aniState->cckWeakSigThreshold)
-               ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
-                                    aniState->cckWeakSigThreshold);
-       if (aniState->firstepLevel != 0)
-               ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                    aniState->firstepLevel);
-       if (ahp->ah_hasHwPhyCounters) {
-               ath9k_hw_setrxfilter(ah,
-                                    ath9k_hw_getrxfilter(ah) &
-                                    ~ATH9K_RX_FILTER_PHYERR);
-               ath9k_ani_restart(ah);
-               REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
-               REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
-
-       } else {
-               ath9k_ani_restart(ah);
-               ath9k_hw_setrxfilter(ah,
-                                    ath9k_hw_getrxfilter(ah) |
-                                    ATH9K_RX_FILTER_PHYERR);
-       }
-}
-
-/*
- * 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)
-{
-       struct ath_hal_5416 *ahp = AH5416(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) ||
-           ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
-               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;
-               aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
-
-               cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
-               ahp->ah_stats.ast_ani_cckerrs +=
-                       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);
-       }
-}
-
-static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ar5416AniState *aniState;
-       int32_t rssi;
-
-       aniState = ahp->ah_curani;
-
-       if (ah->ah_opmode == ATH9K_M_HOSTAP) {
-               if (aniState->firstepLevel > 0) {
-                       if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                                aniState->firstepLevel - 1)) {
-                               return;
-                       }
-               }
-       } else {
-               rssi = BEACON_RSSI(ahp);
-               if (rssi > aniState->rssiThrHigh) {
-                       /* XXX: Handle me */
-               } else if (rssi > aniState->rssiThrLow) {
-                       if (aniState->ofdmWeakSigDetectOff) {
-                               if (ath9k_hw_ani_control(ah,
-                                        ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                        true) ==
-                                   true) {
-                                       return;
-                               }
-                       }
-                       if (aniState->firstepLevel > 0) {
-                               if (ath9k_hw_ani_control
-                                   (ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                    aniState->firstepLevel - 1) ==
-                                   true) {
-                                       return;
-                               }
-                       }
-               } else {
-                       if (aniState->firstepLevel > 0) {
-                               if (ath9k_hw_ani_control
-                                   (ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                    aniState->firstepLevel - 1) ==
-                                   true) {
-                                       return;
+                               if (AR_SREV_9280_20(ah)) {
+                                       if (((chan->channel % 20) == 0)
+                                           || ((chan->channel % 10) == 0))
+                                               pll = 0x2850;
+                                       else
+                                               pll = 0x142c;
                                }
-                       }
-               }
-       }
-
-       if (aniState->spurImmunityLevel > 0) {
-               if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
-                                        aniState->spurImmunityLevel - 1)) {
-                       return;
-               }
-       }
-
-       if (aniState->noiseImmunityLevel > 0) {
-               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
-                                    aniState->noiseImmunityLevel - 1);
-               return;
-       }
-}
-
-static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ar5416AniState *aniState;
-       u32 txFrameCount, rxFrameCount, cycleCount;
-       int32_t listenTime;
-
-       txFrameCount = REG_READ(ah, AR_TFCNT);
-       rxFrameCount = REG_READ(ah, AR_RFCNT);
-       cycleCount = REG_READ(ah, AR_CCCNT);
-
-       aniState = ahp->ah_curani;
-       if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
-
-               listenTime = 0;
-               ahp->ah_stats.ast_ani_lzero++;
-       } else {
-               int32_t ccdelta = cycleCount - aniState->cycleCount;
-               int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
-               int32_t tfdelta = txFrameCount - aniState->txFrameCount;
-               listenTime = (ccdelta - rfdelta - tfdelta) / 44000;
-       }
-       aniState->cycleCount = cycleCount;
-       aniState->txFrameCount = txFrameCount;
-       aniState->rxFrameCount = rxFrameCount;
-
-       return listenTime;
-}
-
-void ath9k_hw_ani_monitor(struct ath_hal *ah,
-                         const struct ath9k_node_stats *stats,
-                         struct ath9k_channel *chan)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ar5416AniState *aniState;
-       int32_t listenTime;
-
-       aniState = ahp->ah_curani;
-       ahp->ah_stats.ast_nodestats = *stats;
-
-       listenTime = ath9k_hw_ani_get_listen_time(ah);
-       if (listenTime < 0) {
-               ahp->ah_stats.ast_ani_lneg++;
-               ath9k_ani_restart(ah);
-               return;
-       }
-
-       aniState->listenTime += listenTime;
-
-       if (ahp->ah_hasHwPhyCounters) {
-               u32 phyCnt1, phyCnt2;
-               u32 ofdmPhyErrCnt, cckPhyErrCnt;
-
-               ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
-
-               phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
-               phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
-
-               if (phyCnt1 < aniState->ofdmPhyErrBase ||
-                   phyCnt2 < aniState->cckPhyErrBase) {
-                       if (phyCnt1 < aniState->ofdmPhyErrBase) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                                        "%s: phyCnt1 0x%x, resetting "
-                                        "counter value to 0x%x\n",
-                                        __func__, phyCnt1,
-                                        aniState->ofdmPhyErrBase);
-                               REG_WRITE(ah, AR_PHY_ERR_1,
-                                         aniState->ofdmPhyErrBase);
-                               REG_WRITE(ah, AR_PHY_ERR_MASK_1,
-                                         AR_PHY_ERR_OFDM_TIMING);
-                       }
-                       if (phyCnt2 < aniState->cckPhyErrBase) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                                        "%s: phyCnt2 0x%x, resetting "
-                                        "counter value to 0x%x\n",
-                                        __func__, phyCnt2,
-                                        aniState->cckPhyErrBase);
-                               REG_WRITE(ah, AR_PHY_ERR_2,
-                                         aniState->cckPhyErrBase);
-                               REG_WRITE(ah, AR_PHY_ERR_MASK_2,
-                                         AR_PHY_ERR_CCK_TIMING);
-                       }
-                       return;
-               }
-
-               ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
-               ahp->ah_stats.ast_ani_ofdmerrs +=
-                       ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
-               aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
-
-               cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
-               ahp->ah_stats.ast_ani_cckerrs +=
-                       cckPhyErrCnt - aniState->cckPhyErrCount;
-               aniState->cckPhyErrCount = cckPhyErrCnt;
-       }
-
-       if (!DO_ANI(ah))
-               return;
-
-       if (aniState->listenTime > 5 * ahp->ah_aniPeriod) {
-               if (aniState->ofdmPhyErrCount <= aniState->listenTime *
-                   aniState->ofdmTrigLow / 1000 &&
-                   aniState->cckPhyErrCount <= aniState->listenTime *
-                   aniState->cckTrigLow / 1000)
-                       ath9k_hw_ani_lower_immunity(ah);
-               ath9k_ani_restart(ah);
-       } else if (aniState->listenTime > ahp->ah_aniPeriod) {
-               if (aniState->ofdmPhyErrCount > aniState->listenTime *
-                   aniState->ofdmTrigHigh / 1000) {
-                       ath9k_hw_ani_ofdm_err_trigger(ah);
-                       ath9k_ani_restart(ah);
-               } else if (aniState->cckPhyErrCount >
-                          aniState->listenTime * aniState->cckTrigHigh /
-                          1000) {
-                       ath9k_hw_ani_cck_err_trigger(ah);
-                       ath9k_ani_restart(ah);
-               }
-       }
-}
-
-#ifndef ATH_NF_PER_CHAN
-static void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
-{
-       int i, j;
-
-       for (i = 0; i < NUM_NF_READINGS; i++) {
-               ah->nfCalHist[i].currIndex = 0;
-               ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE;
-               ah->nfCalHist[i].invalidNFcount =
-                       AR_PHY_CCA_FILTERWINDOW_LENGTH;
-               for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
-                       ah->nfCalHist[i].nfCalBuffer[j] =
-                               AR_PHY_CCA_MAX_GOOD_VALUE;
-               }
-       }
-       return;
-}
-#endif
-
-static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
-                                        u32 gpio, u32 type)
-{
-       int addr;
-       u32 gpio_shift, tmp;
-
-       if (gpio > 11)
-               addr = AR_GPIO_OUTPUT_MUX3;
-       else if (gpio > 5)
-               addr = AR_GPIO_OUTPUT_MUX2;
-       else
-               addr = AR_GPIO_OUTPUT_MUX1;
-
-       gpio_shift = (gpio % 6) * 5;
-
-       if (AR_SREV_9280_20_OR_LATER(ah)
-           || (addr != AR_GPIO_OUTPUT_MUX1)) {
-               REG_RMW(ah, addr, (type << gpio_shift),
-                       (0x1f << gpio_shift));
-       } else {
-               tmp = REG_READ(ah, addr);
-               tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
-               tmp &= ~(0x1f << gpio_shift);
-               tmp |= (type << gpio_shift);
-               REG_WRITE(ah, addr, tmp);
-       }
-}
-
-void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
-                        u32 ah_signal_type)
-{
-       u32 gpio_shift;
-
-       ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
-
-       gpio_shift = 2 * gpio;
-
-       REG_RMW(ah,
-               AR_GPIO_OE_OUT,
-               (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
-               (AR_GPIO_OE_OUT_DRV << gpio_shift));
-}
-
-void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val)
-{
-       REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
-               AR_GPIO_BIT(gpio));
-}
-
-/*
- * Configure GPIO Input lines
- */
-void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio)
-{
-       u32 gpio_shift;
-
-       ASSERT(gpio < ah->ah_caps.num_gpio_pins);
-
-       gpio_shift = gpio << 1;
-
-       REG_RMW(ah,
-               AR_GPIO_OE_OUT,
-               (AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
-               (AR_GPIO_OE_OUT_DRV << gpio_shift));
-}
-
-#ifdef CONFIG_RFKILL
-static void ath9k_enable_rfkill(struct ath_hal *ah)
-{
-       REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-                   AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
-
-       REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
-                   AR_GPIO_INPUT_MUX2_RFSILENT);
-
-       ath9k_hw_cfg_gpio_input(ah, ah->ah_rfkill_gpio);
-       REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
-}
-#endif
-
-u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
-{
-       if (gpio >= ah->ah_caps.num_gpio_pins)
-               return 0xffffffff;
-
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               return (MS
-                       (REG_READ(ah, AR_GPIO_IN_OUT),
-                        AR928X_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0;
-       } else {
-               return (MS(REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL) &
-                       AR_GPIO_BIT(gpio)) != 0;
-       }
-}
-
-static int ath9k_hw_post_attach(struct ath_hal *ah)
-{
-       int ecode;
-
-       if (!ath9k_hw_chip_test(ah)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                        "%s: hardware self-test failed\n", __func__);
-               return -ENODEV;
-       }
-
-       ecode = ath9k_hw_rf_claim(ah);
-       if (ecode != 0)
-               return ecode;
-
-       ecode = ath9k_hw_eeprom_attach(ah);
-       if (ecode != 0)
-               return ecode;
-       ecode = ath9k_hw_rfattach(ah);
-       if (ecode != 0)
-               return ecode;
-
-       if (!AR_SREV_9100(ah)) {
-               ath9k_hw_ani_setup(ah);
-               ath9k_hw_ani_attach(ah);
-       }
-       return 0;
-}
-
-static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
-                                   struct ar5416_eeprom *pEepData,
-                                   u32 reg, u32 value)
-{
-       struct base_eep_header *pBase = &(pEepData->baseEepHeader);
-
-       switch (ah->ah_devid) {
-       case AR9280_DEVID_PCI:
-               if (reg == 0x7894) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                                "ini VAL: %x  EEPROM: %x\n", value,
-                                (pBase->version & 0xff));
-
-                       if ((pBase->version & 0xff) > 0x0a) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                                        "PWDCLKIND: %d\n",
-                                        pBase->pwdclkind);
-                               value &= ~AR_AN_TOP2_PWDCLKIND;
-                               value |= AR_AN_TOP2_PWDCLKIND & (pBase->
-                                        pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
                        } else {
-                               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                                        "PWDCLKIND Earlier Rev\n");
-                       }
-
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                                "final ini VAL: %x\n", value);
-               }
-               break;
-       }
-       return value;
-}
-
-static bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-       u16 capField = 0, eeval;
-
-       eeval = ath9k_hw_get_eeprom(ahp, EEP_REG_0);
-
-       ah->ah_currentRD = eeval;
-
-       eeval = ath9k_hw_get_eeprom(ahp, EEP_REG_1);
-       ah->ah_currentRDExt = eeval;
-
-       capField = ath9k_hw_get_eeprom(ahp, EEP_OP_CAP);
-
-       if (ah->ah_opmode != ATH9K_M_HOSTAP &&
-           ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) {
-               if (ah->ah_currentRD == 0x64 || ah->ah_currentRD == 0x65)
-                       ah->ah_currentRD += 5;
-               else if (ah->ah_currentRD == 0x41)
-                       ah->ah_currentRD = 0x43;
-               DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-                        "%s: regdomain mapped to 0x%x\n", __func__,
-                        ah->ah_currentRD);
-       }
-
-       eeval = ath9k_hw_get_eeprom(ahp, EEP_OP_MODE);
-       bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
-
-       if (eeval & AR5416_OPFLAGS_11A) {
-               set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
-               if (ah->ah_config.ht_enable) {
-                       if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
-                               set_bit(ATH9K_MODE_11NA_HT20,
-                                       pCap->wireless_modes);
-                       if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
-                               set_bit(ATH9K_MODE_11NA_HT40PLUS,
-                                       pCap->wireless_modes);
-                               set_bit(ATH9K_MODE_11NA_HT40MINUS,
-                                       pCap->wireless_modes);
-                       }
-               }
-       }
-
-       if (eeval & AR5416_OPFLAGS_11G) {
-               set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
-               set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
-               if (ah->ah_config.ht_enable) {
-                       if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
-                               set_bit(ATH9K_MODE_11NG_HT20,
-                                       pCap->wireless_modes);
-                       if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
-                               set_bit(ATH9K_MODE_11NG_HT40PLUS,
-                                       pCap->wireless_modes);
-                               set_bit(ATH9K_MODE_11NG_HT40MINUS,
-                                       pCap->wireless_modes);
-                       }
-               }
-       }
-
-       pCap->tx_chainmask = ath9k_hw_get_eeprom(ahp, EEP_TX_MASK);
-       if ((ah->ah_isPciExpress)
-           || (eeval & AR5416_OPFLAGS_11A)) {
-               pCap->rx_chainmask =
-                       ath9k_hw_get_eeprom(ahp, EEP_RX_MASK);
-       } else {
-               pCap->rx_chainmask =
-                       (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
-       }
-
-       if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0)))
-               ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA;
-
-       pCap->low_2ghz_chan = 2312;
-       pCap->high_2ghz_chan = 2732;
-
-       pCap->low_5ghz_chan = 4920;
-       pCap->high_5ghz_chan = 6100;
-
-       pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP;
-       pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP;
-       pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM;
-
-       pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP;
-       pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
-       pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
-
-       pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
-
-       if (ah->ah_config.ht_enable)
-               pCap->hw_caps |= ATH9K_HW_CAP_HT;
-       else
-               pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
-
-       pCap->hw_caps |= ATH9K_HW_CAP_GTT;
-       pCap->hw_caps |= ATH9K_HW_CAP_VEOL;
-       pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK;
-       pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH;
-
-       if (capField & AR_EEPROM_EEPCAP_MAXQCU)
-               pCap->total_queues =
-                       MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
-       else
-               pCap->total_queues = ATH9K_NUM_TX_QUEUES;
-
-       if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
-               pCap->keycache_size =
-                       1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
-       else
-               pCap->keycache_size = AR_KEYTABLE_SIZE;
-
-       pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
-       pCap->num_mr_retries = 4;
-       pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               pCap->num_gpio_pins = AR928X_NUM_GPIO;
-       else
-               pCap->num_gpio_pins = AR_NUM_GPIO;
-
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               pCap->hw_caps |= ATH9K_HW_CAP_WOW;
-               pCap->hw_caps |= ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
-       } else {
-               pCap->hw_caps &= ~ATH9K_HW_CAP_WOW;
-               pCap->hw_caps &= ~ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
-       }
-
-       if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
-               pCap->hw_caps |= ATH9K_HW_CAP_CST;
-               pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
-       } else {
-               pCap->rts_aggr_limit = (8 * 1024);
-       }
-
-       pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
-
-#ifdef CONFIG_RFKILL
-       ah->ah_rfsilent = ath9k_hw_get_eeprom(ahp, EEP_RF_SILENT);
-       if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) {
-               ah->ah_rfkill_gpio =
-                       MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL);
-               ah->ah_rfkill_polarity =
-                       MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY);
-
-               pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
-       }
-#endif
-
-       if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) ||
-           (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) ||
-           (ah->ah_macVersion == AR_SREV_VERSION_9160) ||
-           (ah->ah_macVersion == AR_SREV_VERSION_9100) ||
-           (ah->ah_macVersion == AR_SREV_VERSION_9280))
-               pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
-       else
-               pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
-
-       if (AR_SREV_9280(ah))
-               pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
-       else
-               pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
-
-       if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) {
-               pCap->reg_cap =
-                       AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
-                       AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
-                       AR_EEPROM_EEREGCAP_EN_KK_U2 |
-                       AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
-       } else {
-               pCap->reg_cap =
-                       AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
-                       AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
-       }
-
-       pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
-
-       pCap->num_antcfg_5ghz =
-               ath9k_hw_get_num_ant_config(ahp, IEEE80211_BAND_5GHZ);
-       pCap->num_antcfg_2ghz =
-               ath9k_hw_get_num_ant_config(ahp, IEEE80211_BAND_2GHZ);
-
-       return true;
-}
-
-static void ar5416DisablePciePhy(struct ath_hal *ah)
-{
-       if (!AR_SREV_9100(ah))
-               return;
-
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
-
-       REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
-}
-
-static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
-{
-       REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
-       if (setChip) {
-               REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
-                           AR_RTC_FORCE_WAKE_EN);
-               if (!AR_SREV_9100(ah))
-                       REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
-
-               REG_CLR_BIT(ah, (u16) (AR_RTC_RESET),
-                           AR_RTC_RESET_EN);
-       }
-}
-
-static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
-{
-       REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
-       if (setChip) {
-               struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-
-               if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
-                       REG_WRITE(ah, AR_RTC_FORCE_WAKE,
-                                 AR_RTC_FORCE_WAKE_ON_INT);
-               } else {
-                       REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
-                                   AR_RTC_FORCE_WAKE_EN);
-               }
-       }
-}
-
-static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
-                                    int setChip)
-{
-       u32 val;
-       int i;
-
-       if (setChip) {
-               if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) ==
-                   AR_RTC_STATUS_SHUTDOWN) {
-                       if (ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)
-                           != true) {
-                               return false;
-                       }
-               }
-               if (AR_SREV_9100(ah))
-                       REG_SET_BIT(ah, AR_RTC_RESET,
-                                      AR_RTC_RESET_EN);
-
-               REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
-                           AR_RTC_FORCE_WAKE_EN);
-               udelay(50);
-
-               for (i = POWER_UP_TIME / 50; i > 0; i--) {
-                       val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
-                       if (val == AR_RTC_STATUS_ON)
-                               break;
-                       udelay(50);
-                       REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
-                                      AR_RTC_FORCE_WAKE_EN);
-               }
-               if (i == 0) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                                "%s: Failed to wakeup in %uus\n",
-                                __func__, POWER_UP_TIME / 20);
-                       return false;
-               }
-       }
-
-       REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
-       return true;
-}
-
-bool ath9k_hw_setpower(struct ath_hal *ah,
-                      enum ath9k_power_mode mode)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       static const char *modes[] = {
-               "AWAKE",
-               "FULL-SLEEP",
-               "NETWORK SLEEP",
-               "UNDEFINED"
-       };
-       int status = true, setChip = true;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__,
-                modes[ahp->ah_powerMode], modes[mode],
-                setChip ? "set chip " : "");
-
-       switch (mode) {
-       case ATH9K_PM_AWAKE:
-               status = ath9k_hw_set_power_awake(ah, setChip);
-               break;
-       case ATH9K_PM_FULL_SLEEP:
-               ath9k_set_power_sleep(ah, setChip);
-               ahp->ah_chipFullSleep = true;
-               break;
-       case ATH9K_PM_NETWORK_SLEEP:
-               ath9k_set_power_network_sleep(ah, setChip);
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                        "%s: unknown power mode %u\n", __func__, mode);
-               return false;
-       }
-       ahp->ah_powerMode = mode;
-       return status;
-}
-
-static struct ath_hal *ath9k_hw_do_attach(u16 devid,
-                                         struct ath_softc *sc,
-                                         void __iomem *mem,
-                                         int *status)
-{
-       struct ath_hal_5416 *ahp;
-       struct ath_hal *ah;
-       int ecode;
-#ifndef CONFIG_SLOW_ANT_DIV
-       u32 i;
-       u32 j;
-#endif
-
-       ahp = ath9k_hw_newstate(devid, sc, mem, status);
-       if (ahp == NULL)
-               return NULL;
-
-       ah = &ahp->ah;
-
-       ath9k_hw_set_defaults(ah);
-
-       if (ah->ah_config.intr_mitigation != 0)
-               ahp->ah_intrMitigation = true;
-
-       if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't reset chip\n",
-                        __func__);
-               ecode = -EIO;
-               goto bad;
-       }
-
-       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't wakeup chip\n",
-                        __func__);
-               ecode = -EIO;
-               goto bad;
-       }
-
-       if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) {
-               if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) {
-                       ah->ah_config.serialize_regmode =
-                               SER_REG_MODE_ON;
-               } else {
-                       ah->ah_config.serialize_regmode =
-                               SER_REG_MODE_OFF;
-               }
-       }
-       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-               "%s: serialize_regmode is %d\n",
-               __func__, ah->ah_config.serialize_regmode);
-
-       if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
-           (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
-           (ah->ah_macVersion != AR_SREV_VERSION_9160) &&
-           (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                        "%s: Mac Chip Rev 0x%02x.%x is not supported by "
-                        "this driver\n", __func__,
-                        ah->ah_macVersion, ah->ah_macRev);
-               ecode = -EOPNOTSUPP;
-               goto bad;
-       }
-
-       if (AR_SREV_9100(ah)) {
-               ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
-               ahp->ah_suppCals = IQ_MISMATCH_CAL;
-               ah->ah_isPciExpress = false;
-       }
-       ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
-
-       if (AR_SREV_9160_10_OR_LATER(ah)) {
-               if (AR_SREV_9280_10_OR_LATER(ah)) {
-                       ahp->ah_iqCalData.calData = &iq_cal_single_sample;
-                       ahp->ah_adcGainCalData.calData =
-                               &adc_gain_cal_single_sample;
-                       ahp->ah_adcDcCalData.calData =
-                               &adc_dc_cal_single_sample;
-                       ahp->ah_adcDcCalInitData.calData =
-                               &adc_init_dc_cal;
-               } else {
-                       ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
-                       ahp->ah_adcGainCalData.calData =
-                               &adc_gain_cal_multi_sample;
-                       ahp->ah_adcDcCalData.calData =
-                               &adc_dc_cal_multi_sample;
-                       ahp->ah_adcDcCalInitData.calData =
-                               &adc_init_dc_cal;
-               }
-               ahp->ah_suppCals =
-                       ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
-       }
-
-       if (AR_SREV_9160(ah)) {
-               ah->ah_config.enable_ani = 1;
-               ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
-                                       ATH9K_ANI_FIRSTEP_LEVEL);
-       } else {
-               ahp->ah_ani_function = ATH9K_ANI_ALL;
-               if (AR_SREV_9280_10_OR_LATER(ah)) {
-                       ahp->ah_ani_function &=
-                               ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
-               }
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                "%s: This Mac Chip Rev 0x%02x.%x is \n", __func__,
-                ah->ah_macVersion, ah->ah_macRev);
-
-       if (AR_SREV_9280_20_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
-                              ARRAY_SIZE(ar9280Modes_9280_2), 6);
-               INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
-                              ARRAY_SIZE(ar9280Common_9280_2), 2);
-
-               if (ah->ah_config.pcie_clock_req) {
-                       INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
-                                      ar9280PciePhy_clkreq_off_L1_9280,
-                                      ARRAY_SIZE
-                                      (ar9280PciePhy_clkreq_off_L1_9280),
-                                      2);
-               } else {
-                       INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
-                                      ar9280PciePhy_clkreq_always_on_L1_9280,
-                                      ARRAY_SIZE
-                                      (ar9280PciePhy_clkreq_always_on_L1_9280),
-                                      2);
-               }
-               INIT_INI_ARRAY(&ahp->ah_iniModesAdditional,
-                              ar9280Modes_fast_clock_9280_2,
-                              ARRAY_SIZE(ar9280Modes_fast_clock_9280_2),
-                              3);
-       } else if (AR_SREV_9280_10_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280,
-                              ARRAY_SIZE(ar9280Modes_9280), 6);
-               INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280,
-                              ARRAY_SIZE(ar9280Common_9280), 2);
-       } else if (AR_SREV_9160_10_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160,
-                              ARRAY_SIZE(ar5416Modes_9160), 6);
-               INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160,
-                              ARRAY_SIZE(ar5416Common_9160), 2);
-               INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160,
-                              ARRAY_SIZE(ar5416Bank0_9160), 2);
-               INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160,
-                              ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
-               INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160,
-                              ARRAY_SIZE(ar5416Bank1_9160), 2);
-               INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160,
-                              ARRAY_SIZE(ar5416Bank2_9160), 2);
-               INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160,
-                              ARRAY_SIZE(ar5416Bank3_9160), 3);
-               INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160,
-                              ARRAY_SIZE(ar5416Bank6_9160), 3);
-               INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160,
-                              ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
-               INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160,
-                              ARRAY_SIZE(ar5416Bank7_9160), 2);
-               if (AR_SREV_9160_11(ah)) {
-                       INIT_INI_ARRAY(&ahp->ah_iniAddac,
-                                      ar5416Addac_91601_1,
-                                      ARRAY_SIZE(ar5416Addac_91601_1), 2);
-               } else {
-                       INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160,
-                                      ARRAY_SIZE(ar5416Addac_9160), 2);
-               }
-       } else if (AR_SREV_9100_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100,
-                              ARRAY_SIZE(ar5416Modes_9100), 6);
-               INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100,
-                              ARRAY_SIZE(ar5416Common_9100), 2);
-               INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100,
-                              ARRAY_SIZE(ar5416Bank0_9100), 2);
-               INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100,
-                              ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
-               INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100,
-                              ARRAY_SIZE(ar5416Bank1_9100), 2);
-               INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100,
-                              ARRAY_SIZE(ar5416Bank2_9100), 2);
-               INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100,
-                              ARRAY_SIZE(ar5416Bank3_9100), 3);
-               INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100,
-                              ARRAY_SIZE(ar5416Bank6_9100), 3);
-               INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100,
-                              ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
-               INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100,
-                              ARRAY_SIZE(ar5416Bank7_9100), 2);
-               INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100,
-                              ARRAY_SIZE(ar5416Addac_9100), 2);
-       } else {
-               INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes,
-                              ARRAY_SIZE(ar5416Modes), 6);
-               INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common,
-                              ARRAY_SIZE(ar5416Common), 2);
-               INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0,
-                              ARRAY_SIZE(ar5416Bank0), 2);
-               INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain,
-                              ARRAY_SIZE(ar5416BB_RfGain), 3);
-               INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1,
-                              ARRAY_SIZE(ar5416Bank1), 2);
-               INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2,
-                              ARRAY_SIZE(ar5416Bank2), 2);
-               INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3,
-                              ARRAY_SIZE(ar5416Bank3), 3);
-               INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6,
-                              ARRAY_SIZE(ar5416Bank6), 3);
-               INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC,
-                              ARRAY_SIZE(ar5416Bank6TPC), 3);
-               INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7,
-                              ARRAY_SIZE(ar5416Bank7), 2);
-               INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac,
-                              ARRAY_SIZE(ar5416Addac), 2);
-       }
-
-       if (ah->ah_isPciExpress)
-               ath9k_hw_configpcipowersave(ah, 0);
-       else
-               ar5416DisablePciePhy(ah);
-
-       ecode = ath9k_hw_post_attach(ah);
-       if (ecode != 0)
-               goto bad;
-
-#ifndef CONFIG_SLOW_ANT_DIV
-       if (ah->ah_devid == AR9280_DEVID_PCI) {
-               for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
-                       u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
-
-                       for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) {
-                               u32 val = INI_RA(&ahp->ah_iniModes, i, j);
-
-                               INI_RA(&ahp->ah_iniModes, i, j) =
-                                       ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom,
-                                                          reg, val);
-                       }
-               }
-       }
-#endif
-
-       if (!ath9k_hw_fill_cap_info(ah)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                        "%s:failed ath9k_hw_fill_cap_info\n", __func__);
-               ecode = -EINVAL;
-               goto bad;
-       }
-
-       ecode = ath9k_hw_init_macaddr(ah);
-       if (ecode != 0) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                        "%s: failed initializing mac address\n",
-                        __func__);
-               goto bad;
-       }
-
-       if (AR_SREV_9285(ah))
-               ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S);
-       else
-               ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S);
-
-#ifndef ATH_NF_PER_CHAN
-
-       ath9k_init_nfcal_hist_buffer(ah);
-#endif
-
-       return ah;
-
-bad:
-       if (ahp)
-               ath9k_hw_detach((struct ath_hal *) ahp);
-       if (status)
-               *status = ecode;
-       return NULL;
-}
-
-void ath9k_hw_detach(struct ath_hal *ah)
-{
-       if (!AR_SREV_9100(ah))
-               ath9k_hw_ani_detach(ah);
-       ath9k_hw_rfdetach(ah);
-
-       ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
-       kfree(ah);
-}
-
-bool ath9k_get_channel_edges(struct ath_hal *ah,
-                            u16 flags, u16 *low,
-                            u16 *high)
-{
-       struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-
-       if (flags & CHANNEL_5GHZ) {
-               *low = pCap->low_5ghz_chan;
-               *high = pCap->high_5ghz_chan;
-               return true;
-       }
-       if ((flags & CHANNEL_2GHZ)) {
-               *low = pCap->low_2ghz_chan;
-               *high = pCap->high_2ghz_chan;
-
-               return true;
-       }
-       return false;
-}
-
-static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin,
-                                          u8 pwrMax,
-                                          u8 *pPwrList,
-                                          u8 *pVpdList,
-                                          u16
-                                          numIntercepts,
-                                          u8 *pRetVpdList)
-{
-       u16 i, k;
-       u8 currPwr = pwrMin;
-       u16 idxL = 0, idxR = 0;
-
-       for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
-               ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
-                                              numIntercepts, &(idxL),
-                                              &(idxR));
-               if (idxR < 1)
-                       idxR = 1;
-               if (idxL == numIntercepts - 1)
-                       idxL = (u16) (numIntercepts - 2);
-               if (pPwrList[idxL] == pPwrList[idxR])
-                       k = pVpdList[idxL];
-               else
-                       k = (u16) (((currPwr -
-                                          pPwrList[idxL]) *
-                                         pVpdList[idxR] +
-                                         (pPwrList[idxR] -
-                                          currPwr) * pVpdList[idxL]) /
-                                        (pPwrList[idxR] -
-                                         pPwrList[idxL]));
-               pRetVpdList[i] = (u8) k;
-               currPwr += 2;
-       }
-
-       return true;
-}
-
-static void
-ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
-                                   struct ath9k_channel *chan,
-                                   struct cal_data_per_freq *pRawDataSet,
-                                   u8 *bChans,
-                                   u16 availPiers,
-                                   u16 tPdGainOverlap,
-                                   int16_t *pMinCalPower,
-                                   u16 *pPdGainBoundaries,
-                                   u8 *pPDADCValues,
-                                   u16 numXpdGains)
-{
-       int i, j, k;
-       int16_t ss;
-       u16 idxL = 0, idxR = 0, numPiers;
-       static u8 vpdTableL[AR5416_NUM_PD_GAINS]
-               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-       static u8 vpdTableR[AR5416_NUM_PD_GAINS]
-               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-       static u8 vpdTableI[AR5416_NUM_PD_GAINS]
-               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-
-       u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
-       u8 minPwrT4[AR5416_NUM_PD_GAINS];
-       u8 maxPwrT4[AR5416_NUM_PD_GAINS];
-       int16_t vpdStep;
-       int16_t tmpVal;
-       u16 sizeCurrVpdTable, maxIndex, tgtIndex;
-       bool match;
-       int16_t minDelta = 0;
-       struct chan_centers centers;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-       for (numPiers = 0; numPiers < availPiers; numPiers++) {
-               if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
-                       break;
-       }
-
-       match = ath9k_hw_get_lower_upper_index((u8)
-                                              FREQ2FBIN(centers.
-                                                        synth_center,
-                                                        IS_CHAN_2GHZ
-                                                        (chan)), bChans,
-                                              numPiers, &idxL, &idxR);
-
-       if (match) {
-               for (i = 0; i < numXpdGains; i++) {
-                       minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
-                       maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
-                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-                                               pRawDataSet[idxL].
-                                               pwrPdg[i],
-                                               pRawDataSet[idxL].
-                                               vpdPdg[i],
-                                               AR5416_PD_GAIN_ICEPTS,
-                                               vpdTableI[i]);
-               }
-       } else {
-               for (i = 0; i < numXpdGains; i++) {
-                       pVpdL = pRawDataSet[idxL].vpdPdg[i];
-                       pPwrL = pRawDataSet[idxL].pwrPdg[i];
-                       pVpdR = pRawDataSet[idxR].vpdPdg[i];
-                       pPwrR = pRawDataSet[idxR].pwrPdg[i];
-
-                       minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
-
-                       maxPwrT4[i] =
-                               min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
-                                   pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
-
-
-                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-                                               pPwrL, pVpdL,
-                                               AR5416_PD_GAIN_ICEPTS,
-                                               vpdTableL[i]);
-                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-                                               pPwrR, pVpdR,
-                                               AR5416_PD_GAIN_ICEPTS,
-                                               vpdTableR[i]);
-
-                       for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
-                               vpdTableI[i][j] =
-                                       (u8) (ath9k_hw_interpolate
-                                                   ((u16)
-                                                    FREQ2FBIN(centers.
-                                                              synth_center,
-                                                              IS_CHAN_2GHZ
-                                                              (chan)),
-                                                    bChans[idxL],
-                                                    bChans[idxR], vpdTableL[i]
-                                                    [j], vpdTableR[i]
-                                                    [j]));
-                       }
-               }
-       }
-
-       *pMinCalPower = (int16_t) (minPwrT4[0] / 2);
-
-       k = 0;
-       for (i = 0; i < numXpdGains; i++) {
-               if (i == (numXpdGains - 1))
-                       pPdGainBoundaries[i] =
-                               (u16) (maxPwrT4[i] / 2);
-               else
-                       pPdGainBoundaries[i] =
-                               (u16) ((maxPwrT4[i] +
-                                             minPwrT4[i + 1]) / 4);
-
-               pPdGainBoundaries[i] =
-                       min((u16) AR5416_MAX_RATE_POWER,
-                           pPdGainBoundaries[i]);
-
-               if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
-                       minDelta = pPdGainBoundaries[0] - 23;
-                       pPdGainBoundaries[0] = 23;
-               } else {
-                       minDelta = 0;
-               }
-
-               if (i == 0) {
-                       if (AR_SREV_9280_10_OR_LATER(ah))
-                               ss = (int16_t) (0 - (minPwrT4[i] / 2));
-                       else
-                               ss = 0;
-               } else {
-                       ss = (int16_t) ((pPdGainBoundaries[i - 1] -
-                                        (minPwrT4[i] / 2)) -
-                                       tPdGainOverlap + 1 + minDelta);
-               }
-               vpdStep = (int16_t) (vpdTableI[i][1] - vpdTableI[i][0]);
-               vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
-
-               while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-                       tmpVal = (int16_t) (vpdTableI[i][0] + ss * vpdStep);
-                       pPDADCValues[k++] =
-                               (u8) ((tmpVal < 0) ? 0 : tmpVal);
-                       ss++;
-               }
-
-               sizeCurrVpdTable =
-                       (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
-               tgtIndex = (u8) (pPdGainBoundaries[i] + tPdGainOverlap -
-                                      (minPwrT4[i] / 2));
-               maxIndex = (tgtIndex <
-                           sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;
-
-               while ((ss < maxIndex)
-                      && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-                       pPDADCValues[k++] = vpdTableI[i][ss++];
-               }
-
-               vpdStep = (int16_t) (vpdTableI[i][sizeCurrVpdTable - 1] -
-                                    vpdTableI[i][sizeCurrVpdTable - 2]);
-               vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
-
-               if (tgtIndex > maxIndex) {
-                       while ((ss <= tgtIndex)
-                              && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-                               tmpVal = (int16_t) ((vpdTableI[i]
-                                                    [sizeCurrVpdTable -
-                                                     1] + (ss - maxIndex +
-                                                           1) * vpdStep));
-                               pPDADCValues[k++] = (u8) ((tmpVal >
-                                                255) ? 255 : tmpVal);
-                               ss++;
-                       }
-               }
-       }
-
-       while (i < AR5416_PD_GAINS_IN_MASK) {
-               pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
-               i++;
-       }
-
-       while (k < AR5416_NUM_PDADC_VALUES) {
-               pPDADCValues[k] = pPDADCValues[k - 1];
-               k++;
-       }
-       return;
-}
-
-static bool
-ath9k_hw_set_power_cal_table(struct ath_hal *ah,
-                            struct ar5416_eeprom *pEepData,
-                            struct ath9k_channel *chan,
-                            int16_t *pTxPowerIndexOffset)
-{
-       struct cal_data_per_freq *pRawDataset;
-       u8 *pCalBChans = NULL;
-       u16 pdGainOverlap_t2;
-       static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
-       u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
-       u16 numPiers, i, j;
-       int16_t tMinCalPower;
-       u16 numXpdGain, xpdMask;
-       u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
-       u32 reg32, regOffset, regChainOffset;
-       int16_t modalIdx;
-       struct ath_hal_5416 *ahp = AH5416(ah);
-
-       modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
-       xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
-
-       if ((pEepData->baseEepHeader.
-            version & AR5416_EEP_VER_MINOR_MASK) >=
-           AR5416_EEP_MINOR_VER_2) {
-               pdGainOverlap_t2 =
-                       pEepData->modalHeader[modalIdx].pdGainOverlap;
-       } else {
-               pdGainOverlap_t2 =
-                       (u16) (MS
-                                    (REG_READ(ah, AR_PHY_TPCRG5),
-                                     AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
-       }
-
-       if (IS_CHAN_2GHZ(chan)) {
-               pCalBChans = pEepData->calFreqPier2G;
-               numPiers = AR5416_NUM_2G_CAL_PIERS;
-       } else {
-               pCalBChans = pEepData->calFreqPier5G;
-               numPiers = AR5416_NUM_5G_CAL_PIERS;
-       }
-
-       numXpdGain = 0;
-
-       for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
-               if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
-                       if (numXpdGain >= AR5416_NUM_PD_GAINS)
-                               break;
-                       xpdGainValues[numXpdGain] =
-                               (u16) (AR5416_PD_GAINS_IN_MASK - i);
-                       numXpdGain++;
-               }
-       }
-
-       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
-                     (numXpdGain - 1) & 0x3);
-       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
-                     xpdGainValues[0]);
-       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
-                     xpdGainValues[1]);
-       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
-                     xpdGainValues[2]);
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               if (AR_SREV_5416_V20_OR_LATER(ah) &&
-                   (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
-                   && (i != 0)) {
-                       regChainOffset = (i == 1) ? 0x2000 : 0x1000;
-               } else
-                       regChainOffset = i * 0x1000;
-               if (pEepData->baseEepHeader.txMask & (1 << i)) {
-                       if (IS_CHAN_2GHZ(chan))
-                               pRawDataset = pEepData->calPierData2G[i];
-                       else
-                               pRawDataset = pEepData->calPierData5G[i];
-
-                       ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
-                                                           pRawDataset,
-                                                           pCalBChans,
-                                                           numPiers,
-                                                           pdGainOverlap_t2,
-                                                           &tMinCalPower,
-                                                           gainBoundaries,
-                                                           pdadcValues,
-                                                           numXpdGain);
-
-                       if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
-
-                               REG_WRITE(ah,
-                                         AR_PHY_TPCRG5 + regChainOffset,
-                                         SM(pdGainOverlap_t2,
-                                            AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
-                                         | SM(gainBoundaries[0],
-                                              AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
-                                         | SM(gainBoundaries[1],
-                                              AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
-                                         | SM(gainBoundaries[2],
-                                              AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
-                                         | SM(gainBoundaries[3],
-                                      AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
-                       }
-
-                       regOffset =
-                               AR_PHY_BASE + (672 << 2) + regChainOffset;
-                       for (j = 0; j < 32; j++) {
-                               reg32 =
-                                       ((pdadcValues[4 * j + 0] & 0xFF) << 0)
-                                       | ((pdadcValues[4 * j + 1] & 0xFF) <<
-                                          8) | ((pdadcValues[4 * j + 2] &
-                                                 0xFF) << 16) |
-                                       ((pdadcValues[4 * j + 3] & 0xFF) <<
-                                        24);
-                               REG_WRITE(ah, regOffset, reg32);
-
-                               DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
-                                        "PDADC (%d,%4x): %4.4x %8.8x\n",
-                                        i, regChainOffset, regOffset,
-                                        reg32);
-                               DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
-                               "PDADC: Chain %d | PDADC %3d Value %3d | "
-                               "PDADC %3d Value %3d | PDADC %3d Value %3d | "
-                               "PDADC %3d Value %3d |\n",
-                                        i, 4 * j, pdadcValues[4 * j],
-                                        4 * j + 1, pdadcValues[4 * j + 1],
-                                        4 * j + 2, pdadcValues[4 * j + 2],
-                                        4 * j + 3,
-                                        pdadcValues[4 * j + 3]);
-
-                               regOffset += 4;
-                       }
-               }
-       }
-       *pTxPowerIndexOffset = 0;
-
-       return true;
-}
-
-void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       u8 i;
-
-       if (ah->ah_isPciExpress != true)
-               return;
-
-       if (ah->ah_config.pcie_powersave_enable == 2)
-               return;
-
-       if (restore)
-               return;
-
-       if (AR_SREV_9280_20_OR_LATER(ah)) {
-               for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) {
-                       REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0),
-                                 INI_RA(&ahp->ah_iniPcieSerdes, i, 1));
-               }
-               udelay(1000);
-       } else if (AR_SREV_9280(ah)
-                  && (ah->ah_macRev == AR_SREV_REVISION_9280_10)) {
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
-
-               REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
-
-               if (ah->ah_config.pcie_clock_req)
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
-               else
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
-
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
-
-               REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
-
-               udelay(1000);
-       } else {
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
-               REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
-       }
-
-       REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
-
-       if (ah->ah_config.pcie_waen) {
-               REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
-       } else {
-               if (AR_SREV_9280(ah))
-                       REG_WRITE(ah, AR_WA, 0x0040073f);
-               else
-                       REG_WRITE(ah, AR_WA, 0x0000073f);
-       }
-}
-
-static void
-ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
-                                 struct ath9k_channel *chan,
-                                 struct cal_target_power_leg *powInfo,
-                                 u16 numChannels,
-                                 struct cal_target_power_leg *pNewPower,
-                                 u16 numRates,
-                                 bool isExtTarget)
-{
-       u16 clo, chi;
-       int i;
-       int matchIndex = -1, lowIndex = -1;
-       u16 freq;
-       struct chan_centers centers;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
-
-       if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
-               IS_CHAN_2GHZ(chan))) {
-               matchIndex = 0;
-       } else {
-               for (i = 0; (i < numChannels)
-                    && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
-                       if (freq ==
-                           ath9k_hw_fbin2freq(powInfo[i].bChannel,
-                                              IS_CHAN_2GHZ(chan))) {
-                               matchIndex = i;
-                               break;
-                       } else if ((freq <
-                                   ath9k_hw_fbin2freq(powInfo[i].bChannel,
-                                                      IS_CHAN_2GHZ(chan)))
-                                  && (freq >
-                                      ath9k_hw_fbin2freq(powInfo[i - 1].
-                                                         bChannel,
-                                                         IS_CHAN_2GHZ
-                                                         (chan)))) {
-                               lowIndex = i - 1;
-                               break;
-                       }
-               }
-               if ((matchIndex == -1) && (lowIndex == -1))
-                       matchIndex = i - 1;
-       }
-
-       if (matchIndex != -1) {
-               *pNewPower = powInfo[matchIndex];
-       } else {
-               clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
-                                        IS_CHAN_2GHZ(chan));
-               chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
-                                        IS_CHAN_2GHZ(chan));
-
-               for (i = 0; i < numRates; i++) {
-                       pNewPower->tPow2x[i] =
-                               (u8) ath9k_hw_interpolate(freq, clo, chi,
-                                                               powInfo
-                                                               [lowIndex].
-                                                               tPow2x[i],
-                                                               powInfo
-                                                               [lowIndex +
-                                                                1].tPow2x[i]);
-               }
-       }
-}
-
-static void
-ath9k_hw_get_target_powers(struct ath_hal *ah,
-                          struct ath9k_channel *chan,
-                          struct cal_target_power_ht *powInfo,
-                          u16 numChannels,
-                          struct cal_target_power_ht *pNewPower,
-                          u16 numRates,
-                          bool isHt40Target)
-{
-       u16 clo, chi;
-       int i;
-       int matchIndex = -1, lowIndex = -1;
-       u16 freq;
-       struct chan_centers centers;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       freq = isHt40Target ? centers.synth_center : centers.ctl_center;
-
-       if (freq <=
-               ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
-               matchIndex = 0;
-       } else {
-               for (i = 0; (i < numChannels)
-                    && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
-                       if (freq ==
-                           ath9k_hw_fbin2freq(powInfo[i].bChannel,
-                                              IS_CHAN_2GHZ(chan))) {
-                               matchIndex = i;
-                               break;
-                       } else
-                               if ((freq <
-                                    ath9k_hw_fbin2freq(powInfo[i].bChannel,
-                                                       IS_CHAN_2GHZ(chan)))
-                                   && (freq >
-                                       ath9k_hw_fbin2freq(powInfo[i - 1].
-                                                          bChannel,
-                                                          IS_CHAN_2GHZ
-                                                          (chan)))) {
-                                       lowIndex = i - 1;
-                                       break;
-                               }
-               }
-               if ((matchIndex == -1) && (lowIndex == -1))
-                       matchIndex = i - 1;
-       }
-
-       if (matchIndex != -1) {
-               *pNewPower = powInfo[matchIndex];
-       } else {
-               clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
-                                        IS_CHAN_2GHZ(chan));
-               chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
-                                        IS_CHAN_2GHZ(chan));
-
-               for (i = 0; i < numRates; i++) {
-                       pNewPower->tPow2x[i] =
-                               (u8) ath9k_hw_interpolate(freq, clo, chi,
-                                                               powInfo
-                                                               [lowIndex].
-                                                               tPow2x[i],
-                                                               powInfo
-                                                               [lowIndex +
-                                                                1].tPow2x[i]);
-               }
-       }
-}
-
-static u16
-ath9k_hw_get_max_edge_power(u16 freq,
-                           struct cal_ctl_edges *pRdEdgesPower,
-                           bool is2GHz)
-{
-       u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-       int i;
-
-       for (i = 0; (i < AR5416_NUM_BAND_EDGES)
-            && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
-               if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
-                                              is2GHz)) {
-                       twiceMaxEdgePower = pRdEdgesPower[i].tPower;
-                       break;
-               } else if ((i > 0)
-                          && (freq <
-                              ath9k_hw_fbin2freq(pRdEdgesPower[i].
-                                                 bChannel, is2GHz))) {
-                       if (ath9k_hw_fbin2freq
-                           (pRdEdgesPower[i - 1].bChannel, is2GHz) < freq
-                           && pRdEdgesPower[i - 1].flag) {
-                               twiceMaxEdgePower =
-                                       pRdEdgesPower[i - 1].tPower;
-                       }
-                       break;
-               }
-       }
-       return twiceMaxEdgePower;
-}
-
-static bool
-ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
-                                 struct ar5416_eeprom *pEepData,
-                                 struct ath9k_channel *chan,
-                                 int16_t *ratesArray,
-                                 u16 cfgCtl,
-                                 u8 AntennaReduction,
-                                 u8 twiceMaxRegulatoryPower,
-                                 u8 powerLimit)
-{
-       u8 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-       static const u16 tpScaleReductionTable[5] =
-               { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
-
-       int i;
-       int8_t twiceLargestAntenna;
-       struct cal_ctl_data *rep;
-       struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
-               0, { 0, 0, 0, 0}
-       };
-       struct cal_target_power_leg targetPowerOfdmExt = {
-               0, { 0, 0, 0, 0} }, targetPowerCckExt = {
-               0, { 0, 0, 0, 0 }
-       };
-       struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
-               0, {0, 0, 0, 0}
-       };
-       u8 scaledPower = 0, minCtlPower, maxRegAllowedPower;
-       u16 ctlModesFor11a[] =
-               { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
-       u16 ctlModesFor11g[] =
-               { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
-                 CTL_2GHT40
-               };
-       u16 numCtlModes, *pCtlMode, ctlMode, freq;
-       struct chan_centers centers;
-       int tx_chainmask;
-       u8 twiceMinEdgePower;
-       struct ath_hal_5416 *ahp = AH5416(ah);
-
-       tx_chainmask = ahp->ah_txchainmask;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-       twiceLargestAntenna = max(
-               pEepData->modalHeader
-                       [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
-               pEepData->modalHeader
-                       [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
-
-       twiceLargestAntenna = max((u8) twiceLargestAntenna,
-               pEepData->modalHeader
-                       [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
-
-       twiceLargestAntenna =
-               (int8_t) min(AntennaReduction - twiceLargestAntenna, 0);
-
-       maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
-
-       if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
-               maxRegAllowedPower -=
-                       (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
-       }
-
-       scaledPower = min(powerLimit, maxRegAllowedPower);
-
-       switch (ar5416_get_ntxchains(tx_chainmask)) {
-       case 1:
-               break;
-       case 2:
-               scaledPower -=
-                       pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
-                       pwrDecreaseFor2Chain;
-               break;
-       case 3:
-               scaledPower -=
-                       pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
-                       pwrDecreaseFor3Chain;
-               break;
-       }
-
-       scaledPower = max(0, (int32_t) scaledPower);
-
-       if (IS_CHAN_2GHZ(chan)) {
-               numCtlModes =
-                       ARRAY_SIZE(ctlModesFor11g) -
-                       SUB_NUM_CTL_MODES_AT_2G_40;
-               pCtlMode = ctlModesFor11g;
-
-               ath9k_hw_get_legacy_target_powers(ah, chan,
-                       pEepData->
-                       calTargetPowerCck,
-                       AR5416_NUM_2G_CCK_TARGET_POWERS,
-                       &targetPowerCck, 4,
-                       false);
-               ath9k_hw_get_legacy_target_powers(ah, chan,
-                       pEepData->
-                       calTargetPower2G,
-                       AR5416_NUM_2G_20_TARGET_POWERS,
-                       &targetPowerOfdm, 4,
-                       false);
-               ath9k_hw_get_target_powers(ah, chan,
-                       pEepData->calTargetPower2GHT20,
-                       AR5416_NUM_2G_20_TARGET_POWERS,
-                       &targetPowerHt20, 8, false);
-
-               if (IS_CHAN_HT40(chan)) {
-                       numCtlModes = ARRAY_SIZE(ctlModesFor11g);
-                       ath9k_hw_get_target_powers(ah, chan,
-                               pEepData->
-                               calTargetPower2GHT40,
-                               AR5416_NUM_2G_40_TARGET_POWERS,
-                               &targetPowerHt40, 8,
-                               true);
-                       ath9k_hw_get_legacy_target_powers(ah, chan,
-                               pEepData->
-                               calTargetPowerCck,
-                               AR5416_NUM_2G_CCK_TARGET_POWERS,
-                               &targetPowerCckExt,
-                               4, true);
-                       ath9k_hw_get_legacy_target_powers(ah, chan,
-                               pEepData->
-                               calTargetPower2G,
-                               AR5416_NUM_2G_20_TARGET_POWERS,
-                               &targetPowerOfdmExt,
-                               4, true);
-               }
-       } else {
-
-               numCtlModes =
-                       ARRAY_SIZE(ctlModesFor11a) -
-                       SUB_NUM_CTL_MODES_AT_5G_40;
-               pCtlMode = ctlModesFor11a;
-
-               ath9k_hw_get_legacy_target_powers(ah, chan,
-                       pEepData->
-                       calTargetPower5G,
-                       AR5416_NUM_5G_20_TARGET_POWERS,
-                       &targetPowerOfdm, 4,
-                       false);
-               ath9k_hw_get_target_powers(ah, chan,
-                       pEepData->calTargetPower5GHT20,
-                       AR5416_NUM_5G_20_TARGET_POWERS,
-                       &targetPowerHt20, 8, false);
-
-               if (IS_CHAN_HT40(chan)) {
-                       numCtlModes = ARRAY_SIZE(ctlModesFor11a);
-                       ath9k_hw_get_target_powers(ah, chan,
-                               pEepData->
-                               calTargetPower5GHT40,
-                               AR5416_NUM_5G_40_TARGET_POWERS,
-                               &targetPowerHt40, 8,
-                               true);
-                       ath9k_hw_get_legacy_target_powers(ah, chan,
-                               pEepData->
-                               calTargetPower5G,
-                               AR5416_NUM_5G_20_TARGET_POWERS,
-                               &targetPowerOfdmExt,
-                               4, true);
-               }
-       }
-
-       for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
-               bool isHt40CtlMode =
-                       (pCtlMode[ctlMode] == CTL_5GHT40)
-                       || (pCtlMode[ctlMode] == CTL_2GHT40);
-               if (isHt40CtlMode)
-                       freq = centers.synth_center;
-               else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
-                       freq = centers.ext_center;
-               else
-                       freq = centers.ctl_center;
-
-               if (ar5416_get_eep_ver(ahp) == 14
-                   && ar5416_get_eep_rev(ahp) <= 2)
-                       twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-
-               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                       "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
-                       "EXT_ADDITIVE %d\n",
-                        ctlMode, numCtlModes, isHt40CtlMode,
-                        (pCtlMode[ctlMode] & EXT_ADDITIVE));
-
-               for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i];
-                    i++) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                               "  LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
-                               "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
-                               "chan %d\n",
-                               i, cfgCtl, pCtlMode[ctlMode],
-                               pEepData->ctlIndex[i], chan->channel);
-
-                       if ((((cfgCtl & ~CTL_MODE_M) |
-                             (pCtlMode[ctlMode] & CTL_MODE_M)) ==
-                            pEepData->ctlIndex[i])
-                           ||
-                           (((cfgCtl & ~CTL_MODE_M) |
-                             (pCtlMode[ctlMode] & CTL_MODE_M)) ==
-                            ((pEepData->
-                              ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
-                               rep = &(pEepData->ctlData[i]);
-
-                               twiceMinEdgePower =
-                                       ath9k_hw_get_max_edge_power(freq,
-                                               rep->
-                                               ctlEdges
-                                               [ar5416_get_ntxchains
-                                               (tx_chainmask)
-                                               - 1],
-                                               IS_CHAN_2GHZ
-                                               (chan));
-
-                               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                                       "    MATCH-EE_IDX %d: ch %d is2 %d "
-                                       "2xMinEdge %d chainmask %d chains %d\n",
-                                        i, freq, IS_CHAN_2GHZ(chan),
-                                        twiceMinEdgePower, tx_chainmask,
-                                        ar5416_get_ntxchains
-                                        (tx_chainmask));
-                               if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
-                                       twiceMaxEdgePower =
-                                               min(twiceMaxEdgePower,
-                                                   twiceMinEdgePower);
-                               } else {
-                                       twiceMaxEdgePower =
-                                               twiceMinEdgePower;
-                                       break;
-                               }
-                       }
-               }
-
-               minCtlPower = min(twiceMaxEdgePower, scaledPower);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                               "    SEL-Min ctlMode %d pCtlMode %d "
-                               "2xMaxEdge %d sP %d minCtlPwr %d\n",
-                        ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
-                        scaledPower, minCtlPower);
-
-               switch (pCtlMode[ctlMode]) {
-               case CTL_11B:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
-                            i++) {
-                               targetPowerCck.tPow2x[i] =
-                                       min(targetPowerCck.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               case CTL_11A:
-               case CTL_11G:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
-                            i++) {
-                               targetPowerOfdm.tPow2x[i] =
-                                       min(targetPowerOfdm.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               case CTL_5GHT20:
-               case CTL_2GHT20:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
-                            i++) {
-                               targetPowerHt20.tPow2x[i] =
-                                       min(targetPowerHt20.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               case CTL_11B_EXT:
-                       targetPowerCckExt.tPow2x[0] =
-                               min(targetPowerCckExt.tPow2x[0], minCtlPower);
-                       break;
-               case CTL_11A_EXT:
-               case CTL_11G_EXT:
-                       targetPowerOfdmExt.tPow2x[0] =
-                               min(targetPowerOfdmExt.tPow2x[0], minCtlPower);
-                       break;
-               case CTL_5GHT40:
-               case CTL_2GHT40:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
-                            i++) {
-                               targetPowerHt40.tPow2x[i] =
-                                       min(targetPowerHt40.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
-               ratesArray[rate18mb] = ratesArray[rate24mb] =
-               targetPowerOfdm.tPow2x[0];
-       ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
-       ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
-       ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
-       ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
-
-       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
-               ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
-
-       if (IS_CHAN_2GHZ(chan)) {
-               ratesArray[rate1l] = targetPowerCck.tPow2x[0];
-               ratesArray[rate2s] = ratesArray[rate2l] =
-                       targetPowerCck.tPow2x[1];
-               ratesArray[rate5_5s] = ratesArray[rate5_5l] =
-                       targetPowerCck.tPow2x[2];
-               ;
-               ratesArray[rate11s] = ratesArray[rate11l] =
-                       targetPowerCck.tPow2x[3];
-               ;
-       }
-       if (IS_CHAN_HT40(chan)) {
-               for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
-                       ratesArray[rateHt40_0 + i] =
-                               targetPowerHt40.tPow2x[i];
-               }
-               ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
-               ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
-               ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
-               if (IS_CHAN_2GHZ(chan)) {
-                       ratesArray[rateExtCck] =
-                               targetPowerCckExt.tPow2x[0];
-               }
-       }
-       return true;
-}
-
-static int
-ath9k_hw_set_txpower(struct ath_hal *ah,
-                    struct ar5416_eeprom *pEepData,
-                    struct ath9k_channel *chan,
-                    u16 cfgCtl,
-                    u8 twiceAntennaReduction,
-                    u8 twiceMaxRegulatoryPower,
-                    u8 powerLimit)
-{
-       struct modal_eep_header *pModal =
-               &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
-       int16_t ratesArray[Ar5416RateSize];
-       int16_t txPowerIndexOffset = 0;
-       u8 ht40PowerIncForPdadc = 2;
-       int i;
-
-       memset(ratesArray, 0, sizeof(ratesArray));
-
-       if ((pEepData->baseEepHeader.
-            version & AR5416_EEP_VER_MINOR_MASK) >=
-           AR5416_EEP_MINOR_VER_2) {
-               ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
-       }
-
-       if (!ath9k_hw_set_power_per_rate_table(ah, pEepData, chan,
-                                              &ratesArray[0], cfgCtl,
-                                              twiceAntennaReduction,
-                                              twiceMaxRegulatoryPower,
-                                              powerLimit)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "ath9k_hw_set_txpower: unable to set "
-                       "tx power per rate table\n");
-               return -EIO;
-       }
-
-       if (!ath9k_hw_set_power_cal_table
-           (ah, pEepData, chan, &txPowerIndexOffset)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                        "ath9k_hw_set_txpower: unable to set power table\n");
-               return -EIO;
-       }
-
-       for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
-               ratesArray[i] =
-                       (int16_t) (txPowerIndexOffset + ratesArray[i]);
-               if (ratesArray[i] > AR5416_MAX_RATE_POWER)
-                       ratesArray[i] = AR5416_MAX_RATE_POWER;
-       }
-
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               for (i = 0; i < Ar5416RateSize; i++)
-                       ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
-       }
-
-       REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
-                 ATH9K_POW_SM(ratesArray[rate18mb], 24)
-                 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
-                 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
-                 | ATH9K_POW_SM(ratesArray[rate6mb], 0)
-               );
-       REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
-                 ATH9K_POW_SM(ratesArray[rate54mb], 24)
-                 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
-                 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
-                 | ATH9K_POW_SM(ratesArray[rate24mb], 0)
-               );
-
-       if (IS_CHAN_2GHZ(chan)) {
-               REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
-                         ATH9K_POW_SM(ratesArray[rate2s], 24)
-                         | ATH9K_POW_SM(ratesArray[rate2l], 16)
-                         | ATH9K_POW_SM(ratesArray[rateXr], 8)
-                         | ATH9K_POW_SM(ratesArray[rate1l], 0)
-                       );
-               REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
-                         ATH9K_POW_SM(ratesArray[rate11s], 24)
-                         | ATH9K_POW_SM(ratesArray[rate11l], 16)
-                         | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
-                         | ATH9K_POW_SM(ratesArray[rate5_5l], 0)
-                       );
-       }
-
-       REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
-                 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)
-               );
-       REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
-                 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)
-               );
-
-       if (IS_CHAN_HT40(chan)) {
-               REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
-                         ATH9K_POW_SM(ratesArray[rateHt40_3] +
-                                      ht40PowerIncForPdadc, 24)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_2] +
-                                        ht40PowerIncForPdadc, 16)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_1] +
-                                        ht40PowerIncForPdadc, 8)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_0] +
-                                        ht40PowerIncForPdadc, 0)
-                       );
-               REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
-                         ATH9K_POW_SM(ratesArray[rateHt40_7] +
-                                      ht40PowerIncForPdadc, 24)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_6] +
-                                        ht40PowerIncForPdadc, 16)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_5] +
-                                        ht40PowerIncForPdadc, 8)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_4] +
-                                        ht40PowerIncForPdadc, 0)
-                       );
-
-               REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
-                         ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
-                         | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
-                         | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
-                         | ATH9K_POW_SM(ratesArray[rateDupCck], 0)
-                       );
-       }
-
-       REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
-                 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
-                 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)
-               );
-
-       i = rate6mb;
-       if (IS_CHAN_HT40(chan))
-               i = rateHt40_0;
-       else if (IS_CHAN_HT20(chan))
-               i = rateHt20_0;
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               ah->ah_maxPowerLevel =
-                       ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
-       else
-               ah->ah_maxPowerLevel = ratesArray[i];
-
-       return 0;
-}
-
-static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
-                                                u32 coef_scaled,
-                                                u32 *coef_mantissa,
-                                                u32 *coef_exponent)
-{
-       u32 coef_exp, coef_man;
-
-       for (coef_exp = 31; coef_exp > 0; coef_exp--)
-               if ((coef_scaled >> coef_exp) & 0x1)
-                       break;
-
-       coef_exp = 14 - (coef_exp - COEF_SCALE_S);
-
-       coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
-
-       *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
-       *coef_exponent = coef_exp - 16;
-}
-
-static void
-ath9k_hw_set_delta_slope(struct ath_hal *ah,
-                        struct ath9k_channel *chan)
-{
-       u32 coef_scaled, ds_coef_exp, ds_coef_man;
-       u32 clockMhzScaled = 0x64000000;
-       struct chan_centers centers;
-
-       if (IS_CHAN_HALF_RATE(chan))
-               clockMhzScaled = clockMhzScaled >> 1;
-       else if (IS_CHAN_QUARTER_RATE(chan))
-               clockMhzScaled = clockMhzScaled >> 2;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       coef_scaled = clockMhzScaled / centers.synth_center;
-
-       ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
-                                     &ds_coef_exp);
-
-       REG_RMW_FIELD(ah, AR_PHY_TIMING3,
-                     AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
-       REG_RMW_FIELD(ah, AR_PHY_TIMING3,
-                     AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
-
-       coef_scaled = (9 * coef_scaled) / 10;
-
-       ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
-                                     &ds_coef_exp);
-
-       REG_RMW_FIELD(ah, AR_PHY_HALFGI,
-                     AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
-       REG_RMW_FIELD(ah, AR_PHY_HALFGI,
-                     AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
-}
-
-static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah,
-                                       struct ath9k_channel *chan)
-{
-       int bb_spur = AR_NO_SPUR;
-       int freq;
-       int bin, cur_bin;
-       int bb_spur_off, spur_subchannel_sd;
-       int spur_freq_sd;
-       int spur_delta_phase;
-       int denominator;
-       int upper, lower, cur_vit_mask;
-       int tmp, newVal;
-       int i;
-       int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
-                         AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
-       };
-       int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
-                        AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
-       };
-       int inc[4] = { 0, 100, 0, 0 };
-       struct chan_centers centers;
-
-       int8_t mask_m[123];
-       int8_t mask_p[123];
-       int8_t mask_amt;
-       int tmp_mask;
-       int cur_bb_spur;
-       bool is2GHz = IS_CHAN_2GHZ(chan);
-
-       memset(&mask_m, 0, sizeof(int8_t) * 123);
-       memset(&mask_p, 0, sizeof(int8_t) * 123);
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       freq = centers.synth_center;
-
-       ah->ah_config.spurmode = SPUR_ENABLE_EEPROM;
-       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-               cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
-
-               if (is2GHz)
-                       cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
-               else
-                       cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
-
-               if (AR_NO_SPUR == cur_bb_spur)
-                       break;
-               cur_bb_spur = cur_bb_spur - freq;
-
-               if (IS_CHAN_HT40(chan)) {
-                       if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
-                           (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
-                               bb_spur = cur_bb_spur;
-                               break;
-                       }
-               } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
-                          (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
-                       bb_spur = cur_bb_spur;
-                       break;
-               }
-       }
-
-       if (AR_NO_SPUR == bb_spur) {
-               REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
-                           AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
-               return;
-       } else {
-               REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
-                           AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
-       }
-
-       bin = bb_spur * 320;
-
-       tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
-
-       newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
-                       AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
-                       AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
-                       AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
-       REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
-
-       newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
-                 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
-                 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
-                 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
-                 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
-       REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
-
-       if (IS_CHAN_HT40(chan)) {
-               if (bb_spur < 0) {
-                       spur_subchannel_sd = 1;
-                       bb_spur_off = bb_spur + 10;
-               } else {
-                       spur_subchannel_sd = 0;
-                       bb_spur_off = bb_spur - 10;
-               }
-       } else {
-               spur_subchannel_sd = 0;
-               bb_spur_off = bb_spur;
-       }
-
-       if (IS_CHAN_HT40(chan))
-               spur_delta_phase =
-                       ((bb_spur * 262144) /
-                        10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-       else
-               spur_delta_phase =
-                       ((bb_spur * 524288) /
-                        10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-
-       denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
-       spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
-
-       newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
-                 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
-                 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
-       REG_WRITE(ah, AR_PHY_TIMING11, newVal);
-
-       newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
-       REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
-
-       cur_bin = -6000;
-       upper = bin + 100;
-       lower = bin - 100;
-
-       for (i = 0; i < 4; i++) {
-               int pilot_mask = 0;
-               int chan_mask = 0;
-               int bp = 0;
-               for (bp = 0; bp < 30; bp++) {
-                       if ((cur_bin > lower) && (cur_bin < upper)) {
-                               pilot_mask = pilot_mask | 0x1 << bp;
-                               chan_mask = chan_mask | 0x1 << bp;
-                       }
-                       cur_bin += 100;
-               }
-               cur_bin += inc[i];
-               REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
-               REG_WRITE(ah, chan_mask_reg[i], chan_mask);
-       }
-
-       cur_vit_mask = 6100;
-       upper = bin + 120;
-       lower = bin - 120;
-
-       for (i = 0; i < 123; i++) {
-               if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
-
-                       /* workaround for gcc bug #37014 */
-                       volatile int tmp = abs(cur_vit_mask - bin);
-
-                       if (tmp < 75)
-                               mask_amt = 1;
-                       else
-                               mask_amt = 0;
-                       if (cur_vit_mask < 0)
-                               mask_m[abs(cur_vit_mask / 100)] = mask_amt;
-                       else
-                               mask_p[cur_vit_mask / 100] = mask_amt;
-               }
-               cur_vit_mask -= 100;
-       }
-
-       tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
-               | (mask_m[48] << 26) | (mask_m[49] << 24)
-               | (mask_m[50] << 22) | (mask_m[51] << 20)
-               | (mask_m[52] << 18) | (mask_m[53] << 16)
-               | (mask_m[54] << 14) | (mask_m[55] << 12)
-               | (mask_m[56] << 10) | (mask_m[57] << 8)
-               | (mask_m[58] << 6) | (mask_m[59] << 4)
-               | (mask_m[60] << 2) | (mask_m[61] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
-       REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
-
-       tmp_mask = (mask_m[31] << 28)
-               | (mask_m[32] << 26) | (mask_m[33] << 24)
-               | (mask_m[34] << 22) | (mask_m[35] << 20)
-               | (mask_m[36] << 18) | (mask_m[37] << 16)
-               | (mask_m[48] << 14) | (mask_m[39] << 12)
-               | (mask_m[40] << 10) | (mask_m[41] << 8)
-               | (mask_m[42] << 6) | (mask_m[43] << 4)
-               | (mask_m[44] << 2) | (mask_m[45] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
-
-       tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
-               | (mask_m[18] << 26) | (mask_m[18] << 24)
-               | (mask_m[20] << 22) | (mask_m[20] << 20)
-               | (mask_m[22] << 18) | (mask_m[22] << 16)
-               | (mask_m[24] << 14) | (mask_m[24] << 12)
-               | (mask_m[25] << 10) | (mask_m[26] << 8)
-               | (mask_m[27] << 6) | (mask_m[28] << 4)
-               | (mask_m[29] << 2) | (mask_m[30] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
-
-       tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
-               | (mask_m[2] << 26) | (mask_m[3] << 24)
-               | (mask_m[4] << 22) | (mask_m[5] << 20)
-               | (mask_m[6] << 18) | (mask_m[7] << 16)
-               | (mask_m[8] << 14) | (mask_m[9] << 12)
-               | (mask_m[10] << 10) | (mask_m[11] << 8)
-               | (mask_m[12] << 6) | (mask_m[13] << 4)
-               | (mask_m[14] << 2) | (mask_m[15] << 0);
-       REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
-
-       tmp_mask = (mask_p[15] << 28)
-               | (mask_p[14] << 26) | (mask_p[13] << 24)
-               | (mask_p[12] << 22) | (mask_p[11] << 20)
-               | (mask_p[10] << 18) | (mask_p[9] << 16)
-               | (mask_p[8] << 14) | (mask_p[7] << 12)
-               | (mask_p[6] << 10) | (mask_p[5] << 8)
-               | (mask_p[4] << 6) | (mask_p[3] << 4)
-               | (mask_p[2] << 2) | (mask_p[1] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
-
-       tmp_mask = (mask_p[30] << 28)
-               | (mask_p[29] << 26) | (mask_p[28] << 24)
-               | (mask_p[27] << 22) | (mask_p[26] << 20)
-               | (mask_p[25] << 18) | (mask_p[24] << 16)
-               | (mask_p[23] << 14) | (mask_p[22] << 12)
-               | (mask_p[21] << 10) | (mask_p[20] << 8)
-               | (mask_p[19] << 6) | (mask_p[18] << 4)
-               | (mask_p[17] << 2) | (mask_p[16] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
-
-       tmp_mask = (mask_p[45] << 28)
-               | (mask_p[44] << 26) | (mask_p[43] << 24)
-               | (mask_p[42] << 22) | (mask_p[41] << 20)
-               | (mask_p[40] << 18) | (mask_p[39] << 16)
-               | (mask_p[38] << 14) | (mask_p[37] << 12)
-               | (mask_p[36] << 10) | (mask_p[35] << 8)
-               | (mask_p[34] << 6) | (mask_p[33] << 4)
-               | (mask_p[32] << 2) | (mask_p[31] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
-
-       tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
-               | (mask_p[59] << 26) | (mask_p[58] << 24)
-               | (mask_p[57] << 22) | (mask_p[56] << 20)
-               | (mask_p[55] << 18) | (mask_p[54] << 16)
-               | (mask_p[53] << 14) | (mask_p[52] << 12)
-               | (mask_p[51] << 10) | (mask_p[50] << 8)
-               | (mask_p[49] << 6) | (mask_p[48] << 4)
-               | (mask_p[47] << 2) | (mask_p[46] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
-}
-
-static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
-                                  struct ath9k_channel *chan)
-{
-       int bb_spur = AR_NO_SPUR;
-       int bin, cur_bin;
-       int spur_freq_sd;
-       int spur_delta_phase;
-       int denominator;
-       int upper, lower, cur_vit_mask;
-       int tmp, new;
-       int i;
-       int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
-                         AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
-       };
-       int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
-                        AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
-       };
-       int inc[4] = { 0, 100, 0, 0 };
-
-       int8_t mask_m[123];
-       int8_t mask_p[123];
-       int8_t mask_amt;
-       int tmp_mask;
-       int cur_bb_spur;
-       bool is2GHz = IS_CHAN_2GHZ(chan);
-
-       memset(&mask_m, 0, sizeof(int8_t) * 123);
-       memset(&mask_p, 0, sizeof(int8_t) * 123);
-
-       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-               cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
-               if (AR_NO_SPUR == cur_bb_spur)
-                       break;
-               cur_bb_spur = cur_bb_spur - (chan->channel * 10);
-               if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
-                       bb_spur = cur_bb_spur;
-                       break;
-               }
-       }
-
-       if (AR_NO_SPUR == bb_spur)
-               return;
-
-       bin = bb_spur * 32;
-
-       tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
-       new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
-                    AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
-                    AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
-                    AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
-
-       REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
-
-       new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
-              AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
-              AR_PHY_SPUR_REG_MASK_RATE_SELECT |
-              AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
-              SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
-       REG_WRITE(ah, AR_PHY_SPUR_REG, new);
-
-       spur_delta_phase = ((bb_spur * 524288) / 100) &
-               AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-
-       denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
-       spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
-
-       new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
-              SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
-              SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
-       REG_WRITE(ah, AR_PHY_TIMING11, new);
-
-       cur_bin = -6000;
-       upper = bin + 100;
-       lower = bin - 100;
-
-       for (i = 0; i < 4; i++) {
-               int pilot_mask = 0;
-               int chan_mask = 0;
-               int bp = 0;
-               for (bp = 0; bp < 30; bp++) {
-                       if ((cur_bin > lower) && (cur_bin < upper)) {
-                               pilot_mask = pilot_mask | 0x1 << bp;
-                               chan_mask = chan_mask | 0x1 << bp;
-                       }
-                       cur_bin += 100;
-               }
-               cur_bin += inc[i];
-               REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
-               REG_WRITE(ah, chan_mask_reg[i], chan_mask);
-       }
-
-       cur_vit_mask = 6100;
-       upper = bin + 120;
-       lower = bin - 120;
-
-       for (i = 0; i < 123; i++) {
-               if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
-
-                       /* workaround for gcc bug #37014 */
-                       volatile int tmp = abs(cur_vit_mask - bin);
-
-                       if (tmp < 75)
-                               mask_amt = 1;
-                       else
-                               mask_amt = 0;
-                       if (cur_vit_mask < 0)
-                               mask_m[abs(cur_vit_mask / 100)] = mask_amt;
-                       else
-                               mask_p[cur_vit_mask / 100] = mask_amt;
-               }
-               cur_vit_mask -= 100;
-       }
+                               pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
+                       }
 
-       tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
-               | (mask_m[48] << 26) | (mask_m[49] << 24)
-               | (mask_m[50] << 22) | (mask_m[51] << 20)
-               | (mask_m[52] << 18) | (mask_m[53] << 16)
-               | (mask_m[54] << 14) | (mask_m[55] << 12)
-               | (mask_m[56] << 10) | (mask_m[57] << 8)
-               | (mask_m[58] << 6) | (mask_m[59] << 4)
-               | (mask_m[60] << 2) | (mask_m[61] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
-       REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
+               } else if (AR_SREV_9160_10_OR_LATER(ah)) {
 
-       tmp_mask = (mask_m[31] << 28)
-               | (mask_m[32] << 26) | (mask_m[33] << 24)
-               | (mask_m[34] << 22) | (mask_m[35] << 20)
-               | (mask_m[36] << 18) | (mask_m[37] << 16)
-               | (mask_m[48] << 14) | (mask_m[39] << 12)
-               | (mask_m[40] << 10) | (mask_m[41] << 8)
-               | (mask_m[42] << 6) | (mask_m[43] << 4)
-               | (mask_m[44] << 2) | (mask_m[45] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
+                       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
 
-       tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
-               | (mask_m[18] << 26) | (mask_m[18] << 24)
-               | (mask_m[20] << 22) | (mask_m[20] << 20)
-               | (mask_m[22] << 18) | (mask_m[22] << 16)
-               | (mask_m[24] << 14) | (mask_m[24] << 12)
-               | (mask_m[25] << 10) | (mask_m[26] << 8)
-               | (mask_m[27] << 6) | (mask_m[28] << 4)
-               | (mask_m[29] << 2) | (mask_m[30] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
+                       if (chan && IS_CHAN_HALF_RATE(chan))
+                               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
+                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
+                               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
 
-       tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
-               | (mask_m[2] << 26) | (mask_m[3] << 24)
-               | (mask_m[4] << 22) | (mask_m[5] << 20)
-               | (mask_m[6] << 18) | (mask_m[7] << 16)
-               | (mask_m[8] << 14) | (mask_m[9] << 12)
-               | (mask_m[10] << 10) | (mask_m[11] << 8)
-               | (mask_m[12] << 6) | (mask_m[13] << 4)
-               | (mask_m[14] << 2) | (mask_m[15] << 0);
-       REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
+                       if (chan && IS_CHAN_5GHZ(chan))
+                               pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
+                       else
+                               pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
+               } else {
+                       pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
 
-       tmp_mask = (mask_p[15] << 28)
-               | (mask_p[14] << 26) | (mask_p[13] << 24)
-               | (mask_p[12] << 22) | (mask_p[11] << 20)
-               | (mask_p[10] << 18) | (mask_p[9] << 16)
-               | (mask_p[8] << 14) | (mask_p[7] << 12)
-               | (mask_p[6] << 10) | (mask_p[5] << 8)
-               | (mask_p[4] << 6) | (mask_p[3] << 4)
-               | (mask_p[2] << 2) | (mask_p[1] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
+                       if (chan && IS_CHAN_HALF_RATE(chan))
+                               pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
+                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
+                               pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
 
-       tmp_mask = (mask_p[30] << 28)
-               | (mask_p[29] << 26) | (mask_p[28] << 24)
-               | (mask_p[27] << 22) | (mask_p[26] << 20)
-               | (mask_p[25] << 18) | (mask_p[24] << 16)
-               | (mask_p[23] << 14) | (mask_p[22] << 12)
-               | (mask_p[21] << 10) | (mask_p[20] << 8)
-               | (mask_p[19] << 6) | (mask_p[18] << 4)
-               | (mask_p[17] << 2) | (mask_p[16] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
+                       if (chan && IS_CHAN_5GHZ(chan))
+                               pll |= SM(0xa, AR_RTC_PLL_DIV);
+                       else
+                               pll |= SM(0xb, AR_RTC_PLL_DIV);
+               }
+       }
+       REG_WRITE(ah, (u16) (AR_RTC_PLL_CONTROL), pll);
 
-       tmp_mask = (mask_p[45] << 28)
-               | (mask_p[44] << 26) | (mask_p[43] << 24)
-               | (mask_p[42] << 22) | (mask_p[41] << 20)
-               | (mask_p[40] << 18) | (mask_p[39] << 16)
-               | (mask_p[38] << 14) | (mask_p[37] << 12)
-               | (mask_p[36] << 10) | (mask_p[35] << 8)
-               | (mask_p[34] << 6) | (mask_p[33] << 4)
-               | (mask_p[32] << 2) | (mask_p[31] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
+       udelay(RTC_PLL_SETTLE_DELAY);
 
-       tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
-               | (mask_p[59] << 26) | (mask_p[58] << 24)
-               | (mask_p[57] << 22) | (mask_p[56] << 20)
-               | (mask_p[55] << 18) | (mask_p[54] << 16)
-               | (mask_p[53] << 14) | (mask_p[52] << 12)
-               | (mask_p[51] << 10) | (mask_p[50] << 8)
-               | (mask_p[49] << 6) | (mask_p[48] << 4)
-               | (mask_p[47] << 2) | (mask_p[46] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
+       REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
 }
 
 static void ath9k_hw_init_chain_masks(struct ath_hal *ah)
@@ -5160,102 +987,34 @@ static void ath9k_hw_init_chain_masks(struct ath_hal *ah)
                          REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
 }
 
-static void ath9k_hw_set_addac(struct ath_hal *ah,
-                              struct ath9k_channel *chan)
+static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah, enum ath9k_opmode opmode)
 {
-       struct modal_eep_header *pModal;
        struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ar5416_eeprom *eep = &ahp->ah_eeprom;
-       u8 biaslevel;
-
-       if (ah->ah_macVersion != AR_SREV_VERSION_9160)
-               return;
-
-       if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
-               return;
-
-       pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
 
-       if (pModal->xpaBiasLvl != 0xff) {
-               biaslevel = pModal->xpaBiasLvl;
-       } else {
-
-               u16 resetFreqBin, freqBin, freqCount = 0;
-               struct chan_centers centers;
-
-               ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-               resetFreqBin =
-                       FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
-               freqBin = pModal->xpaBiasLvlFreq[0] & 0xff;
-               biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14);
-
-               freqCount++;
-
-               while (freqCount < 3) {
-                       if (pModal->xpaBiasLvlFreq[freqCount] == 0x0)
-                               break;
-
-                       freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff;
-                       if (resetFreqBin >= freqBin) {
-                               biaslevel =
-                                       (u8) (pModal->
-                                                   xpaBiasLvlFreq[freqCount]
-                                                   >> 14);
-                       } else {
-                               break;
-                       }
-                       freqCount++;
-               }
-       }
-
-       if (IS_CHAN_2GHZ(chan)) {
-               INI_RA(&ahp->ah_iniAddac, 7, 1) =
-                       (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel
-                       << 3;
-       } else {
-               INI_RA(&ahp->ah_iniAddac, 6, 1) =
-                       (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel
-                       << 6;
-       }
-}
+       ahp->ah_maskReg = AR_IMR_TXERR |
+               AR_IMR_TXURN |
+               AR_IMR_RXERR |
+               AR_IMR_RXORN |
+               AR_IMR_BCNMISC;
 
-static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
-{
-       if (ah->ah_curchan != NULL)
-               return clks /
-               CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
+       if (ahp->ah_intrMitigation)
+               ahp->ah_maskReg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
        else
-               return clks / CLOCK_RATE[ATH9K_MODE_11B];
-}
-
-static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
-{
-       struct ath9k_channel *chan = ah->ah_curchan;
+               ahp->ah_maskReg |= AR_IMR_RXOK;
 
-       if (chan && IS_CHAN_HT40(chan))
-               return ath9k_hw_mac_usec(ah, clks) / 2;
-       else
-               return ath9k_hw_mac_usec(ah, clks);
-}
+       ahp->ah_maskReg |= AR_IMR_TXOK;
 
-static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
-{
-       if (ah->ah_curchan != NULL)
-               return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
-                       ah->ah_curchan)];
-       else
-               return usecs * CLOCK_RATE[ATH9K_MODE_11B];
-}
+       if (opmode == ATH9K_M_HOSTAP)
+               ahp->ah_maskReg |= AR_IMR_MIB;
 
-static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
-{
-       struct ath9k_channel *chan = ah->ah_curchan;
+       REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
+       REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
 
-       if (chan && IS_CHAN_HT40(chan))
-               return ath9k_hw_mac_clks(ah, usecs) * 2;
-       else
-               return ath9k_hw_mac_clks(ah, usecs);
+       if (!AR_SREV_9100(ah)) {
+               REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
+               REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
+               REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
+       }
 }
 
 static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
@@ -5291,8 +1050,8 @@ static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
                return true;
        }
 }
-static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah,
-                                         u32 tu)
+
+static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah, u32 tu)
 {
        struct ath_hal_5416 *ahp = AH5416(ah);
 
@@ -5308,45 +1067,117 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah,
        }
 }
 
-bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
+static void ath9k_hw_init_user_settings(struct ath_hal *ah)
 {
        struct ath_hal_5416 *ahp = AH5416(ah);
 
-       if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad slot time %u\n",
-                        __func__, us);
-               ahp->ah_slottime = (u32) -1;
-               return false;
-       } else {
-               REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
-               ahp->ah_slottime = us;
-               return true;
+       DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n",
+                __func__, ahp->ah_miscMode);
+
+       if (ahp->ah_miscMode != 0)
+               REG_WRITE(ah, AR_PCU_MISC,
+                         REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
+       if (ahp->ah_slottime != (u32) -1)
+               ath9k_hw_setslottime(ah, ahp->ah_slottime);
+       if (ahp->ah_acktimeout != (u32) -1)
+               ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
+       if (ahp->ah_ctstimeout != (u32) -1)
+               ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
+       if (ahp->ah_globaltxtimeout != (u32) -1)
+               ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
+}
+
+const char *ath9k_hw_probe(u16 vendorid, u16 devid)
+{
+       return vendorid == ATHEROS_VENDOR_ID ?
+               ath9k_hw_devname(devid) : NULL;
+}
+
+void ath9k_hw_detach(struct ath_hal *ah)
+{
+       if (!AR_SREV_9100(ah))
+               ath9k_hw_ani_detach(ah);
+
+       ath9k_hw_rfdetach(ah);
+       ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+       kfree(ah);
+}
+
+struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
+                               void __iomem *mem, int *error)
+{
+       struct ath_hal *ah = NULL;
+
+       switch (devid) {
+       case AR5416_DEVID_PCI:
+       case AR5416_DEVID_PCIE:
+       case AR9160_DEVID_PCI:
+       case AR9280_DEVID_PCI:
+       case AR9280_DEVID_PCIE:
+               ah = ath9k_hw_do_attach(devid, sc, mem, error);
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+                        "devid=0x%x not supported.\n", devid);
+               ah = NULL;
+               *error = -ENXIO;
+               break;
+       }
+
+       return ah;
+}
+
+/*******/
+/* INI */
+/*******/
+
+static void ath9k_hw_override_ini(struct ath_hal *ah,
+                                 struct ath9k_channel *chan)
+{
+       if (!AR_SREV_5416_V20_OR_LATER(ah) ||
+           AR_SREV_9280_10_OR_LATER(ah))
+               return;
+
+       REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
+}
+
+static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
+                             struct ar5416_eeprom *pEepData,
+                             u32 reg, u32 value)
+{
+       struct base_eep_header *pBase = &(pEepData->baseEepHeader);
+
+       switch (ah->ah_devid) {
+       case AR9280_DEVID_PCI:
+               if (reg == 0x7894) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+                               "ini VAL: %x  EEPROM: %x\n", value,
+                               (pBase->version & 0xff));
+
+                       if ((pBase->version & 0xff) > 0x0a) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+                                       "PWDCLKIND: %d\n",
+                                       pBase->pwdclkind);
+                               value &= ~AR_AN_TOP2_PWDCLKIND;
+                               value |= AR_AN_TOP2_PWDCLKIND &
+                                       (pBase->pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
+                       } else {
+                               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+                                       "PWDCLKIND Earlier Rev\n");
+                       }
+
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+                               "final ini VAL: %x\n", value);
+               }
+               break;
        }
-}
-
-static void ath9k_hw_init_user_settings(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
 
-       DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n",
-                __func__, ahp->ah_miscMode);
-       if (ahp->ah_miscMode != 0)
-               REG_WRITE(ah, AR_PCU_MISC,
-                         REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
-       if (ahp->ah_slottime != (u32) -1)
-               ath9k_hw_setslottime(ah, ahp->ah_slottime);
-       if (ahp->ah_acktimeout != (u32) -1)
-               ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
-       if (ahp->ah_ctstimeout != (u32) -1)
-               ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
-       if (ahp->ah_globaltxtimeout != (u32) -1)
-               ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
+       return value;
 }
 
-static int
-ath9k_hw_process_ini(struct ath_hal *ah,
-                    struct ath9k_channel *chan,
-                    enum ath9k_ht_macmode macmode)
+static int ath9k_hw_process_ini(struct ath_hal *ah,
+                               struct ath9k_channel *chan,
+                               enum ath9k_ht_macmode macmode)
 {
        int i, regWrites = 0;
        struct ath_hal_5416 *ahp = AH5416(ah);
@@ -5397,14 +1228,14 @@ ath9k_hw_process_ini(struct ath_hal *ah,
                memcpy(ahp->ah_addac5416_21,
                       ahp->ah_iniAddac.ia_array, addacSize);
 
-               (ahp->ah_addac5416_21)[31 *
-                                      ahp->ah_iniAddac.ia_columns + 1] = 0;
+               (ahp->ah_addac5416_21)[31 * ahp->ah_iniAddac.ia_columns + 1] = 0;
 
                temp.ia_array = ahp->ah_addac5416_21;
                temp.ia_columns = ahp->ah_iniAddac.ia_columns;
                temp.ia_rows = ahp->ah_iniAddac.ia_rows;
                REG_WRITE_ARRAY(&temp, 1, regWrites);
        }
+
        REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
 
        for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
@@ -5413,8 +1244,7 @@ ath9k_hw_process_ini(struct ath_hal *ah,
 
 #ifdef CONFIG_SLOW_ANT_DIV
                if (ah->ah_devid == AR9280_DEVID_PCI)
-                       val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg,
-                                                val);
+                       val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg, val);
 #endif
 
                REG_WRITE(ah, reg, val);
@@ -5452,7 +1282,7 @@ ath9k_hw_process_ini(struct ath_hal *ah,
        ath9k_hw_set_regs(ah, chan, macmode);
        ath9k_hw_init_chain_masks(ah);
 
-       status = ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
+       status = ath9k_hw_set_txpower(ah, chan,
                                      ath9k_regd_get_ctl(ah, chan),
                                      ath9k_regd_get_antenna_allowed(ah,
                                                                     chan),
@@ -5461,178 +1291,323 @@ ath9k_hw_process_ini(struct ath_hal *ah,
                                          (u32) ah->ah_powerLimit));
        if (status != 0) {
                DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                        "%s: error init'ing transmit power\n", __func__);
+                       "%s: error init'ing transmit power\n", __func__);
                return -EIO;
        }
 
        if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
                DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                        "%s: ar5416SetRfRegs failed\n", __func__);
+                       "%s: ar5416SetRfRegs failed\n", __func__);
                return -EIO;
        }
 
        return 0;
 }
 
-static void ath9k_hw_setup_calibration(struct ath_hal *ah,
-                                             struct hal_cal_list *currCal)
+/****************************************/
+/* Reset and Channel Switching Routines */
+/****************************************/
+
+static void ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
 {
-       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
-                     AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
-                     currCal->calData->calCountMax);
-
-       switch (currCal->calData->calType) {
-       case IQ_MISMATCH_CAL:
-               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "%s: starting IQ Mismatch Calibration\n",
-                        __func__);
+       u32 rfMode = 0;
+
+       if (chan == NULL)
+               return;
+
+       rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
+               ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
+
+       if (!AR_SREV_9280_10_OR_LATER(ah))
+               rfMode |= (IS_CHAN_5GHZ(chan)) ?
+                       AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
+
+       if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan))
+               rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
+
+       REG_WRITE(ah, AR_PHY_MODE, rfMode);
+}
+
+static void ath9k_hw_mark_phy_inactive(struct ath_hal *ah)
+{
+       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
+}
+
+static inline void ath9k_hw_set_dma(struct ath_hal *ah)
+{
+       u32 regval;
+
+       regval = REG_READ(ah, AR_AHB_MODE);
+       REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
+
+       regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
+       REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
+
+       REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
+
+       regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
+       REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
+
+       REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
+
+       if (AR_SREV_9285(ah)) {
+               REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
+                         AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
+       } else {
+               REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
+                         AR_PCU_TXBUF_CTRL_USABLE_SIZE);
+       }
+}
+
+static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
+{
+       u32 val;
+
+       val = REG_READ(ah, AR_STA_ID1);
+       val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
+       switch (opmode) {
+       case ATH9K_M_HOSTAP:
+               REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
+                         | AR_STA_ID1_KSRCH_MODE);
+               REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
                break;
-       case ADC_GAIN_CAL:
-               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "%s: starting ADC Gain Calibration\n", __func__);
+       case ATH9K_M_IBSS:
+               REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
+                         | AR_STA_ID1_KSRCH_MODE);
+               REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
                break;
-       case ADC_DC_CAL:
-               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "%s: starting ADC DC Calibration\n", __func__);
+       case ATH9K_M_STA:
+       case ATH9K_M_MONITOR:
+               REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
                break;
-       case ADC_DC_INIT_CAL:
-               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "%s: starting Init ADC DC Calibration\n",
+       }
+}
+
+static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
+                                                u32 coef_scaled,
+                                                u32 *coef_mantissa,
+                                                u32 *coef_exponent)
+{
+       u32 coef_exp, coef_man;
+
+       for (coef_exp = 31; coef_exp > 0; coef_exp--)
+               if ((coef_scaled >> coef_exp) & 0x1)
+                       break;
+
+       coef_exp = 14 - (coef_exp - COEF_SCALE_S);
+
+       coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
+
+       *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
+       *coef_exponent = coef_exp - 16;
+}
+
+static void ath9k_hw_set_delta_slope(struct ath_hal *ah,
+                                    struct ath9k_channel *chan)
+{
+       u32 coef_scaled, ds_coef_exp, ds_coef_man;
+       u32 clockMhzScaled = 0x64000000;
+       struct chan_centers centers;
+
+       if (IS_CHAN_HALF_RATE(chan))
+               clockMhzScaled = clockMhzScaled >> 1;
+       else if (IS_CHAN_QUARTER_RATE(chan))
+               clockMhzScaled = clockMhzScaled >> 2;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       coef_scaled = clockMhzScaled / centers.synth_center;
+
+       ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
+                                     &ds_coef_exp);
+
+       REG_RMW_FIELD(ah, AR_PHY_TIMING3,
+                     AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING3,
+                     AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
+
+       coef_scaled = (9 * coef_scaled) / 10;
+
+       ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
+                                     &ds_coef_exp);
+
+       REG_RMW_FIELD(ah, AR_PHY_HALFGI,
+                     AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
+       REG_RMW_FIELD(ah, AR_PHY_HALFGI,
+                     AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
+}
+
+static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
+{
+       u32 rst_flags;
+       u32 tmpReg;
+
+       REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
+                 AR_RTC_FORCE_WAKE_ON_INT);
+
+       if (AR_SREV_9100(ah)) {
+               rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD |
+                       AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
+       } else {
+               tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
+               if (tmpReg &
+                   (AR_INTR_SYNC_LOCAL_TIMEOUT |
+                    AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
+                       REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
+                       REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
+               } else {
+                       REG_WRITE(ah, AR_RC, AR_RC_AHB);
+               }
+
+               rst_flags = AR_RTC_RC_MAC_WARM;
+               if (type == ATH9K_RESET_COLD)
+                       rst_flags |= AR_RTC_RC_MAC_COLD;
+       }
+
+       REG_WRITE(ah, (u16) (AR_RTC_RC), rst_flags);
+       udelay(50);
+
+       REG_WRITE(ah, (u16) (AR_RTC_RC), 0);
+       if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+                       "%s: RTC stuck in MAC reset\n",
+                       __func__);
+               return false;
+       }
+
+       if (!AR_SREV_9100(ah))
+               REG_WRITE(ah, AR_RC, 0);
+
+       ath9k_hw_init_pll(ah, NULL);
+
+       if (AR_SREV_9100(ah))
+               udelay(50);
+
+       return true;
+}
+
+static bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
+{
+       REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
+                 AR_RTC_FORCE_WAKE_ON_INT);
+
+       REG_WRITE(ah, (u16) (AR_RTC_RESET), 0);
+       REG_WRITE(ah, (u16) (AR_RTC_RESET), 1);
+
+       if (!ath9k_hw_wait(ah,
+                          AR_RTC_STATUS,
+                          AR_RTC_STATUS_M,
+                          AR_RTC_STATUS_ON)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: RTC not waking up\n",
                         __func__);
-               break;
+               return false;
        }
 
-       REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
-                   AR_PHY_TIMING_CTRL4_DO_CAL);
+       ath9k_hw_read_revisions(ah);
+
+       return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
+}
+
+static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type)
+{
+       REG_WRITE(ah, AR_RTC_FORCE_WAKE,
+                 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
+
+       switch (type) {
+       case ATH9K_RESET_POWER_ON:
+               return ath9k_hw_set_reset_power_on(ah);
+               break;
+       case ATH9K_RESET_WARM:
+       case ATH9K_RESET_COLD:
+               return ath9k_hw_set_reset(ah, type);
+               break;
+       default:
+               return false;
+       }
 }
 
-static void ath9k_hw_reset_calibration(struct ath_hal *ah,
-                                      struct hal_cal_list *currCal)
+static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
+                             enum ath9k_ht_macmode macmode)
 {
+       u32 phymode;
        struct ath_hal_5416 *ahp = AH5416(ah);
-       int i;
 
-       ath9k_hw_setup_calibration(ah, currCal);
+       phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
+               | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH;
+
+       if (IS_CHAN_HT40(chan)) {
+               phymode |= AR_PHY_FC_DYN2040_EN;
+
+               if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
+                   (chan->chanmode == CHANNEL_G_HT40PLUS))
+                       phymode |= AR_PHY_FC_DYN2040_PRI_CH;
 
-       currCal->calState = CAL_RUNNING;
+               if (ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
+                       phymode |= AR_PHY_FC_DYN2040_EXT_CH;
+       }
+       REG_WRITE(ah, AR_PHY_TURBO, phymode);
 
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ahp->ah_Meas0.sign[i] = 0;
-               ahp->ah_Meas1.sign[i] = 0;
-               ahp->ah_Meas2.sign[i] = 0;
-               ahp->ah_Meas3.sign[i] = 0;
-       }
+       ath9k_hw_set11nmac2040(ah, macmode);
 
-       ahp->ah_CalSamples = 0;
+       REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
+       REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
 }
 
-static void
-ath9k_hw_per_calibration(struct ath_hal *ah,
-                        struct ath9k_channel *ichan,
-                        u8 rxchainmask,
-                        struct hal_cal_list *currCal,
-                        bool *isCalDone)
+static bool ath9k_hw_chip_reset(struct ath_hal *ah,
+                               struct ath9k_channel *chan)
 {
        struct ath_hal_5416 *ahp = AH5416(ah);
 
-       *isCalDone = false;
-
-       if (currCal->calState == CAL_RUNNING) {
-               if (!(REG_READ(ah,
-                              AR_PHY_TIMING_CTRL4(0)) &
-                     AR_PHY_TIMING_CTRL4_DO_CAL)) {
+       if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
+               return false;
 
-                       currCal->calData->calCollect(ah);
+       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+               return false;
 
-                       ahp->ah_CalSamples++;
+       ahp->ah_chipFullSleep = false;
 
-                       if (ahp->ah_CalSamples >=
-                           currCal->calData->calNumSamples) {
-                               int i, numChains = 0;
-                               for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-                                       if (rxchainmask & (1 << i))
-                                               numChains++;
-                               }
+       ath9k_hw_init_pll(ah, chan);
 
-                               currCal->calData->calPostProc(ah,
-                                                             numChains);
+       ath9k_hw_set_rfmode(ah, chan);
 
-                               ichan->CalValid |=
-                                       currCal->calData->calType;
-                               currCal->calState = CAL_DONE;
-                               *isCalDone = true;
-                       } else {
-                               ath9k_hw_setup_calibration(ah, currCal);
-                       }
-               }
-       } else if (!(ichan->CalValid & currCal->calData->calType)) {
-               ath9k_hw_reset_calibration(ah, currCal);
-       }
+       return true;
 }
 
-static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
-                                         int init_cal_count)
+static struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah,
+                                                struct ath9k_channel *chan)
 {
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ath9k_channel ichan;
-       bool isCalDone;
-       struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
-       const struct hal_percal_data *calData = currCal->calData;
-       int i;
-
-       if (currCal == NULL)
-               return false;
-
-       ichan.CalValid = 0;
-
-       for (i = 0; i < init_cal_count; i++) {
-               ath9k_hw_reset_calibration(ah, currCal);
-
-               if (!ath9k_hw_wait(ah, AR_PHY_TIMING_CTRL4(0),
-                                  AR_PHY_TIMING_CTRL4_DO_CAL, 0)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                "%s: Cal %d failed to complete in 100ms.\n",
-                                __func__, calData->calType);
-
-                       ahp->ah_cal_list = ahp->ah_cal_list_last =
-                               ahp->ah_cal_list_curr = NULL;
-                       return false;
-               }
+       if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
+                       "%s: invalid channel %u/0x%x; not marked as "
+                       "2GHz or 5GHz\n", __func__, chan->channel,
+                       chan->channelFlags);
+               return NULL;
+       }
 
-               ath9k_hw_per_calibration(ah, &ichan, ahp->ah_rxchainmask,
-                                        currCal, &isCalDone);
-               if (!isCalDone) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                "%s: Not able to run Init Cal %d.\n",
-                                __func__, calData->calType);
-               }
-               if (currCal->calNext) {
-                       currCal = currCal->calNext;
-                       calData = currCal->calData;
-               }
+       if (!IS_CHAN_OFDM(chan) &&
+           !IS_CHAN_CCK(chan) &&
+           !IS_CHAN_HT20(chan) &&
+           !IS_CHAN_HT40(chan)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
+                       "%s: invalid channel %u/0x%x; not marked as "
+                       "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
+                       __func__, chan->channel, chan->channelFlags);
+               return NULL;
        }
 
-       ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
-       return true;
+       return ath9k_regd_check_channel(ah, chan);
 }
 
-static bool
-ath9k_hw_channel_change(struct ath_hal *ah,
-                       struct ath9k_channel *chan,
-                       enum ath9k_ht_macmode macmode)
+static bool ath9k_hw_channel_change(struct ath_hal *ah,
+                                   struct ath9k_channel *chan,
+                                   enum ath9k_ht_macmode macmode)
 {
        u32 synthDelay, qnum;
-       struct ath_hal_5416 *ahp = AH5416(ah);
 
        for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
                if (ath9k_hw_numtxpending(ah, qnum)) {
                        DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-                                "%s: Transmit frames pending on queue %d\n",
-                                __func__, qnum);
+                               "%s: Transmit frames pending on queue %d\n",
+                               __func__, qnum);
                        return false;
                }
        }
@@ -5641,7 +1616,7 @@ ath9k_hw_channel_change(struct ath_hal *ah,
        if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
                           AR_PHY_RFBUS_GRANT_EN)) {
                DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
-                        "%s: Could not kill baseband RX\n", __func__);
+                       "%s: Could not kill baseband RX\n", __func__);
                return false;
        }
 
@@ -5650,25 +1625,25 @@ ath9k_hw_channel_change(struct ath_hal *ah,
        if (AR_SREV_9280_10_OR_LATER(ah)) {
                if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
                        DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-                                "%s: failed to set channel\n", __func__);
+                               "%s: failed to set channel\n", __func__);
                        return false;
                }
        } else {
                if (!(ath9k_hw_set_channel(ah, chan))) {
                        DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-                                "%s: failed to set channel\n", __func__);
+                               "%s: failed to set channel\n", __func__);
                        return false;
                }
        }
 
-       if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
+       if (ath9k_hw_set_txpower(ah, chan,
                                 ath9k_regd_get_ctl(ah, chan),
                                 ath9k_regd_get_antenna_allowed(ah, chan),
                                 chan->maxRegTxPower * 2,
                                 min((u32) MAX_RATE_POWER,
                                     (u32) ah->ah_powerLimit)) != 0) {
                DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                        "%s: error init'ing transmit power\n", __func__);
+                       "%s: error init'ing transmit power\n", __func__);
                return false;
        }
 
@@ -5682,190 +1657,476 @@ ath9k_hw_channel_change(struct ath_hal *ah,
 
        REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
 
-       if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
-               ath9k_hw_set_delta_slope(ah, chan);
+       if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
+               ath9k_hw_set_delta_slope(ah, chan);
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               ath9k_hw_9280_spur_mitigate(ah, chan);
+       else
+               ath9k_hw_spur_mitigate(ah, chan);
+
+       if (!chan->oneTimeCalsDone)
+               chan->oneTimeCalsDone = true;
+
+       return true;
+}
+
+static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+       int bb_spur = AR_NO_SPUR;
+       int freq;
+       int bin, cur_bin;
+       int bb_spur_off, spur_subchannel_sd;
+       int spur_freq_sd;
+       int spur_delta_phase;
+       int denominator;
+       int upper, lower, cur_vit_mask;
+       int tmp, newVal;
+       int i;
+       int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
+                         AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+       };
+       int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
+                        AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+       };
+       int inc[4] = { 0, 100, 0, 0 };
+       struct chan_centers centers;
+
+       int8_t mask_m[123];
+       int8_t mask_p[123];
+       int8_t mask_amt;
+       int tmp_mask;
+       int cur_bb_spur;
+       bool is2GHz = IS_CHAN_2GHZ(chan);
+
+       memset(&mask_m, 0, sizeof(int8_t) * 123);
+       memset(&mask_p, 0, sizeof(int8_t) * 123);
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = centers.synth_center;
+
+       ah->ah_config.spurmode = SPUR_ENABLE_EEPROM;
+       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+               cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
+
+               if (is2GHz)
+                       cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
+               else
+                       cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
+
+               if (AR_NO_SPUR == cur_bb_spur)
+                       break;
+               cur_bb_spur = cur_bb_spur - freq;
+
+               if (IS_CHAN_HT40(chan)) {
+                       if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
+                           (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
+                               bb_spur = cur_bb_spur;
+                               break;
+                       }
+               } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
+                          (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
+                       bb_spur = cur_bb_spur;
+                       break;
+               }
+       }
+
+       if (AR_NO_SPUR == bb_spur) {
+               REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
+                           AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
+               return;
+       } else {
+               REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
+                           AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
+       }
+
+       bin = bb_spur * 320;
+
+       tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
+
+       newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
+                       AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
+                       AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
+                       AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
+       REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
+
+       newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
+                 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
+                 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
+                 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
+                 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
+       REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
+
+       if (IS_CHAN_HT40(chan)) {
+               if (bb_spur < 0) {
+                       spur_subchannel_sd = 1;
+                       bb_spur_off = bb_spur + 10;
+               } else {
+                       spur_subchannel_sd = 0;
+                       bb_spur_off = bb_spur - 10;
+               }
+       } else {
+               spur_subchannel_sd = 0;
+               bb_spur_off = bb_spur;
+       }
+
+       if (IS_CHAN_HT40(chan))
+               spur_delta_phase =
+                       ((bb_spur * 262144) /
+                        10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+       else
+               spur_delta_phase =
+                       ((bb_spur * 524288) /
+                        10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+
+       denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
+       spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
+
+       newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
+                 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
+                 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
+       REG_WRITE(ah, AR_PHY_TIMING11, newVal);
+
+       newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
+       REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
+
+       cur_bin = -6000;
+       upper = bin + 100;
+       lower = bin - 100;
+
+       for (i = 0; i < 4; i++) {
+               int pilot_mask = 0;
+               int chan_mask = 0;
+               int bp = 0;
+               for (bp = 0; bp < 30; bp++) {
+                       if ((cur_bin > lower) && (cur_bin < upper)) {
+                               pilot_mask = pilot_mask | 0x1 << bp;
+                               chan_mask = chan_mask | 0x1 << bp;
+                       }
+                       cur_bin += 100;
+               }
+               cur_bin += inc[i];
+               REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
+               REG_WRITE(ah, chan_mask_reg[i], chan_mask);
+       }
+
+       cur_vit_mask = 6100;
+       upper = bin + 120;
+       lower = bin - 120;
+
+       for (i = 0; i < 123; i++) {
+               if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
+
+                       /* workaround for gcc bug #37014 */
+                       volatile int tmp = abs(cur_vit_mask - bin);
+
+                       if (tmp < 75)
+                               mask_amt = 1;
+                       else
+                               mask_amt = 0;
+                       if (cur_vit_mask < 0)
+                               mask_m[abs(cur_vit_mask / 100)] = mask_amt;
+                       else
+                               mask_p[cur_vit_mask / 100] = mask_amt;
+               }
+               cur_vit_mask -= 100;
+       }
+
+       tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
+               | (mask_m[48] << 26) | (mask_m[49] << 24)
+               | (mask_m[50] << 22) | (mask_m[51] << 20)
+               | (mask_m[52] << 18) | (mask_m[53] << 16)
+               | (mask_m[54] << 14) | (mask_m[55] << 12)
+               | (mask_m[56] << 10) | (mask_m[57] << 8)
+               | (mask_m[58] << 6) | (mask_m[59] << 4)
+               | (mask_m[60] << 2) | (mask_m[61] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
+       REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
+
+       tmp_mask = (mask_m[31] << 28)
+               | (mask_m[32] << 26) | (mask_m[33] << 24)
+               | (mask_m[34] << 22) | (mask_m[35] << 20)
+               | (mask_m[36] << 18) | (mask_m[37] << 16)
+               | (mask_m[48] << 14) | (mask_m[39] << 12)
+               | (mask_m[40] << 10) | (mask_m[41] << 8)
+               | (mask_m[42] << 6) | (mask_m[43] << 4)
+               | (mask_m[44] << 2) | (mask_m[45] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
+
+       tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
+               | (mask_m[18] << 26) | (mask_m[18] << 24)
+               | (mask_m[20] << 22) | (mask_m[20] << 20)
+               | (mask_m[22] << 18) | (mask_m[22] << 16)
+               | (mask_m[24] << 14) | (mask_m[24] << 12)
+               | (mask_m[25] << 10) | (mask_m[26] << 8)
+               | (mask_m[27] << 6) | (mask_m[28] << 4)
+               | (mask_m[29] << 2) | (mask_m[30] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
+
+       tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
+               | (mask_m[2] << 26) | (mask_m[3] << 24)
+               | (mask_m[4] << 22) | (mask_m[5] << 20)
+               | (mask_m[6] << 18) | (mask_m[7] << 16)
+               | (mask_m[8] << 14) | (mask_m[9] << 12)
+               | (mask_m[10] << 10) | (mask_m[11] << 8)
+               | (mask_m[12] << 6) | (mask_m[13] << 4)
+               | (mask_m[14] << 2) | (mask_m[15] << 0);
+       REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
+
+       tmp_mask = (mask_p[15] << 28)
+               | (mask_p[14] << 26) | (mask_p[13] << 24)
+               | (mask_p[12] << 22) | (mask_p[11] << 20)
+               | (mask_p[10] << 18) | (mask_p[9] << 16)
+               | (mask_p[8] << 14) | (mask_p[7] << 12)
+               | (mask_p[6] << 10) | (mask_p[5] << 8)
+               | (mask_p[4] << 6) | (mask_p[3] << 4)
+               | (mask_p[2] << 2) | (mask_p[1] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
 
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               ath9k_hw_9280_spur_mitigate(ah, chan);
-       else
-               ath9k_hw_spur_mitigate(ah, chan);
+       tmp_mask = (mask_p[30] << 28)
+               | (mask_p[29] << 26) | (mask_p[28] << 24)
+               | (mask_p[27] << 22) | (mask_p[26] << 20)
+               | (mask_p[25] << 18) | (mask_p[24] << 16)
+               | (mask_p[23] << 14) | (mask_p[22] << 12)
+               | (mask_p[21] << 10) | (mask_p[20] << 8)
+               | (mask_p[19] << 6) | (mask_p[18] << 4)
+               | (mask_p[17] << 2) | (mask_p[16] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
 
-       if (!chan->oneTimeCalsDone)
-               chan->oneTimeCalsDone = true;
+       tmp_mask = (mask_p[45] << 28)
+               | (mask_p[44] << 26) | (mask_p[43] << 24)
+               | (mask_p[42] << 22) | (mask_p[41] << 20)
+               | (mask_p[40] << 18) | (mask_p[39] << 16)
+               | (mask_p[38] << 14) | (mask_p[37] << 12)
+               | (mask_p[36] << 10) | (mask_p[35] << 8)
+               | (mask_p[34] << 6) | (mask_p[33] << 4)
+               | (mask_p[32] << 2) | (mask_p[31] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
 
-       return true;
+       tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
+               | (mask_p[59] << 26) | (mask_p[58] << 24)
+               | (mask_p[57] << 22) | (mask_p[56] << 20)
+               | (mask_p[55] << 18) | (mask_p[54] << 16)
+               | (mask_p[53] << 14) | (mask_p[52] << 12)
+               | (mask_p[51] << 10) | (mask_p[50] << 8)
+               | (mask_p[49] << 6) | (mask_p[48] << 4)
+               | (mask_p[47] << 2) | (mask_p[46] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
 }
 
-static bool ath9k_hw_chip_reset(struct ath_hal *ah,
-                               struct ath9k_channel *chan)
+static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan)
 {
-       struct ath_hal_5416 *ahp = AH5416(ah);
-
-       if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
-               return false;
+       int bb_spur = AR_NO_SPUR;
+       int bin, cur_bin;
+       int spur_freq_sd;
+       int spur_delta_phase;
+       int denominator;
+       int upper, lower, cur_vit_mask;
+       int tmp, new;
+       int i;
+       int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
+                         AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+       };
+       int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
+                        AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+       };
+       int inc[4] = { 0, 100, 0, 0 };
 
-       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
-               return false;
+       int8_t mask_m[123];
+       int8_t mask_p[123];
+       int8_t mask_amt;
+       int tmp_mask;
+       int cur_bb_spur;
+       bool is2GHz = IS_CHAN_2GHZ(chan);
 
-       ahp->ah_chipFullSleep = false;
+       memset(&mask_m, 0, sizeof(int8_t) * 123);
+       memset(&mask_p, 0, sizeof(int8_t) * 123);
 
-       ath9k_hw_init_pll(ah, chan);
+       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+               cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
+               if (AR_NO_SPUR == cur_bb_spur)
+                       break;
+               cur_bb_spur = cur_bb_spur - (chan->channel * 10);
+               if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
+                       bb_spur = cur_bb_spur;
+                       break;
+               }
+       }
 
-       ath9k_hw_set_rfmode(ah, chan);
+       if (AR_NO_SPUR == bb_spur)
+               return;
 
-       return true;
-}
+       bin = bb_spur * 32;
 
-static inline void ath9k_hw_set_dma(struct ath_hal *ah)
-{
-       u32 regval;
+       tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
+       new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
+                    AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
+                    AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
+                    AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
 
-       regval = REG_READ(ah, AR_AHB_MODE);
-       REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
+       REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
 
-       regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
-       REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
+       new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
+              AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
+              AR_PHY_SPUR_REG_MASK_RATE_SELECT |
+              AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
+              SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
+       REG_WRITE(ah, AR_PHY_SPUR_REG, new);
 
-       REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
+       spur_delta_phase = ((bb_spur * 524288) / 100) &
+               AR_PHY_TIMING11_SPUR_DELTA_PHASE;
 
-       regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
-       REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
+       denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
+       spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
 
-       REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
+       new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
+              SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
+              SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
+       REG_WRITE(ah, AR_PHY_TIMING11, new);
 
-       if (AR_SREV_9285(ah)) {
-               REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
-                         AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
-       } else {
-               REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
-                         AR_PCU_TXBUF_CTRL_USABLE_SIZE);
-       }
-}
+       cur_bin = -6000;
+       upper = bin + 100;
+       lower = bin - 100;
 
-bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
-{
-       REG_WRITE(ah, AR_CR, AR_CR_RXD);
-       if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-                       "%s: dma failed to stop in 10ms\n"
-                       "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
-                       __func__,
-                       REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
-               return false;
-       } else {
-               return true;
+       for (i = 0; i < 4; i++) {
+               int pilot_mask = 0;
+               int chan_mask = 0;
+               int bp = 0;
+               for (bp = 0; bp < 30; bp++) {
+                       if ((cur_bin > lower) && (cur_bin < upper)) {
+                               pilot_mask = pilot_mask | 0x1 << bp;
+                               chan_mask = chan_mask | 0x1 << bp;
+                       }
+                       cur_bin += 100;
+               }
+               cur_bin += inc[i];
+               REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
+               REG_WRITE(ah, chan_mask_reg[i], chan_mask);
        }
-}
 
-void ath9k_hw_startpcureceive(struct ath_hal *ah)
-{
-       REG_CLR_BIT(ah, AR_DIAG_SW,
-                   (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
-
-       ath9k_enable_mib_counters(ah);
-
-       ath9k_ani_reset(ah);
-}
-
-void ath9k_hw_stoppcurecv(struct ath_hal *ah)
-{
-       REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
+       cur_vit_mask = 6100;
+       upper = bin + 120;
+       lower = bin - 120;
 
-       ath9k_hw_disable_mib_counters(ah);
-}
+       for (i = 0; i < 123; i++) {
+               if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
 
-static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
-                                    struct ath9k_channel *chan,
-                                    enum hal_cal_types calType)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       bool retval = false;
+                       /* workaround for gcc bug #37014 */
+                       volatile int tmp = abs(cur_vit_mask - bin);
 
-       switch (calType & ahp->ah_suppCals) {
-       case IQ_MISMATCH_CAL:
-               if (!IS_CHAN_B(chan))
-                       retval = true;
-               break;
-       case ADC_GAIN_CAL:
-       case ADC_DC_CAL:
-               if (!IS_CHAN_B(chan)
-                   && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
-                       retval = true;
-               break;
+                       if (tmp < 75)
+                               mask_amt = 1;
+                       else
+                               mask_amt = 0;
+                       if (cur_vit_mask < 0)
+                               mask_m[abs(cur_vit_mask / 100)] = mask_amt;
+                       else
+                               mask_p[cur_vit_mask / 100] = mask_amt;
+               }
+               cur_vit_mask -= 100;
        }
 
-       return retval;
-}
-
-static bool ath9k_hw_init_cal(struct ath_hal *ah,
-                             struct ath9k_channel *chan)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ath9k_channel *ichan =
-               ath9k_regd_check_channel(ah, chan);
-
-       REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-                 REG_READ(ah, AR_PHY_AGC_CONTROL) |
-                 AR_PHY_AGC_CONTROL_CAL);
-
-       if (!ath9k_hw_wait
-           (ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "%s: offset calibration failed to complete in 1ms; "
-                        "noisy environment?\n", __func__);
-               return false;
-       }
+       tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
+               | (mask_m[48] << 26) | (mask_m[49] << 24)
+               | (mask_m[50] << 22) | (mask_m[51] << 20)
+               | (mask_m[52] << 18) | (mask_m[53] << 16)
+               | (mask_m[54] << 14) | (mask_m[55] << 12)
+               | (mask_m[56] << 10) | (mask_m[57] << 8)
+               | (mask_m[58] << 6) | (mask_m[59] << 4)
+               | (mask_m[60] << 2) | (mask_m[61] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
+       REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
 
-       REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-                 REG_READ(ah, AR_PHY_AGC_CONTROL) |
-                 AR_PHY_AGC_CONTROL_NF);
+       tmp_mask = (mask_m[31] << 28)
+               | (mask_m[32] << 26) | (mask_m[33] << 24)
+               | (mask_m[34] << 22) | (mask_m[35] << 20)
+               | (mask_m[36] << 18) | (mask_m[37] << 16)
+               | (mask_m[48] << 14) | (mask_m[39] << 12)
+               | (mask_m[40] << 10) | (mask_m[41] << 8)
+               | (mask_m[42] << 6) | (mask_m[43] << 4)
+               | (mask_m[44] << 2) | (mask_m[45] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
 
-       ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr =
-               NULL;
+       tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
+               | (mask_m[18] << 26) | (mask_m[18] << 24)
+               | (mask_m[20] << 22) | (mask_m[20] << 20)
+               | (mask_m[22] << 18) | (mask_m[22] << 16)
+               | (mask_m[24] << 14) | (mask_m[24] << 12)
+               | (mask_m[25] << 10) | (mask_m[26] << 8)
+               | (mask_m[27] << 6) | (mask_m[28] << 4)
+               | (mask_m[29] << 2) | (mask_m[30] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
 
-       if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
-               if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
-                       INIT_CAL(&ahp->ah_adcGainCalData);
-                       INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                "%s: enabling ADC Gain Calibration.\n",
-                                __func__);
-               }
-               if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
-                       INIT_CAL(&ahp->ah_adcDcCalData);
-                       INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                "%s: enabling ADC DC Calibration.\n",
-                                __func__);
-               }
-               if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
-                       INIT_CAL(&ahp->ah_iqCalData);
-                       INSERT_CAL(ahp, &ahp->ah_iqCalData);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                "%s: enabling IQ Calibration.\n",
-                                __func__);
-               }
+       tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
+               | (mask_m[2] << 26) | (mask_m[3] << 24)
+               | (mask_m[4] << 22) | (mask_m[5] << 20)
+               | (mask_m[6] << 18) | (mask_m[7] << 16)
+               | (mask_m[8] << 14) | (mask_m[9] << 12)
+               | (mask_m[10] << 10) | (mask_m[11] << 8)
+               | (mask_m[12] << 6) | (mask_m[13] << 4)
+               | (mask_m[14] << 2) | (mask_m[15] << 0);
+       REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
 
-               ahp->ah_cal_list_curr = ahp->ah_cal_list;
+       tmp_mask = (mask_p[15] << 28)
+               | (mask_p[14] << 26) | (mask_p[13] << 24)
+               | (mask_p[12] << 22) | (mask_p[11] << 20)
+               | (mask_p[10] << 18) | (mask_p[9] << 16)
+               | (mask_p[8] << 14) | (mask_p[7] << 12)
+               | (mask_p[6] << 10) | (mask_p[5] << 8)
+               | (mask_p[4] << 6) | (mask_p[3] << 4)
+               | (mask_p[2] << 2) | (mask_p[1] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
 
-               if (ahp->ah_cal_list_curr)
-                       ath9k_hw_reset_calibration(ah,
-                                                  ahp->ah_cal_list_curr);
-       }
+       tmp_mask = (mask_p[30] << 28)
+               | (mask_p[29] << 26) | (mask_p[28] << 24)
+               | (mask_p[27] << 22) | (mask_p[26] << 20)
+               | (mask_p[25] << 18) | (mask_p[24] << 16)
+               | (mask_p[23] << 14) | (mask_p[22] << 12)
+               | (mask_p[21] << 10) | (mask_p[20] << 8)
+               | (mask_p[19] << 6) | (mask_p[18] << 4)
+               | (mask_p[17] << 2) | (mask_p[16] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
 
-       ichan->CalValid = 0;
+       tmp_mask = (mask_p[45] << 28)
+               | (mask_p[44] << 26) | (mask_p[43] << 24)
+               | (mask_p[42] << 22) | (mask_p[41] << 20)
+               | (mask_p[40] << 18) | (mask_p[39] << 16)
+               | (mask_p[38] << 14) | (mask_p[37] << 12)
+               | (mask_p[36] << 10) | (mask_p[35] << 8)
+               | (mask_p[34] << 6) | (mask_p[33] << 4)
+               | (mask_p[32] << 2) | (mask_p[31] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
 
-       return true;
+       tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
+               | (mask_p[59] << 26) | (mask_p[58] << 24)
+               | (mask_p[57] << 22) | (mask_p[56] << 20)
+               | (mask_p[55] << 18) | (mask_p[54] << 16)
+               | (mask_p[53] << 14) | (mask_p[52] << 12)
+               | (mask_p[51] << 10) | (mask_p[50] << 8)
+               | (mask_p[49] << 6) | (mask_p[48] << 4)
+               | (mask_p[47] << 2) | (mask_p[46] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
 }
 
-
-bool ath9k_hw_reset(struct ath_hal *ah,
-                   struct ath9k_channel *chan,
+bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
                    enum ath9k_ht_macmode macmode,
                    u8 txchainmask, u8 rxchainmask,
                    enum ath9k_ht_extprotspacing extprotspacing,
-                   bool bChannelChange,
-                   int *status)
+                   bool bChannelChange, int *status)
 {
        u32 saveLedState;
        struct ath_hal_5416 *ahp = AH5416(ah);
@@ -5886,8 +2147,8 @@ bool ath9k_hw_reset(struct ath_hal *ah,
 
        if (ath9k_hw_check_chan(ah, chan) == NULL) {
                DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-                        "%s: invalid channel %u/0x%x; no mapping\n",
-                        __func__, chan->channel, chan->channelFlags);
+                       "%s: invalid channel %u/0x%x; no mapping\n",
+                       __func__, chan->channel, chan->channelFlags);
                ecode = -EINVAL;
                goto bad;
        }
@@ -5965,7 +2226,7 @@ bool ath9k_hw_reset(struct ath_hal *ah,
 
        if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
                DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                        "%s: error setting board options\n", __func__);
+                       "%s: error setting board options\n", __func__);
                ecode = -EIO;
                goto bad;
        }
@@ -6055,15 +2316,15 @@ bool ath9k_hw_reset(struct ath_hal *ah,
                mask = REG_READ(ah, AR_CFG);
                if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
                        DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                                "%s CFG Byte Swap Set 0x%x\n", __func__,
-                                mask);
+                               "%s CFG Byte Swap Set 0x%x\n", __func__,
+                               mask);
                } else {
                        mask =
                                INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
                        REG_WRITE(ah, AR_CFG, mask);
                        DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                                "%s Setting CFG 0x%x\n", __func__,
-                                REG_READ(ah, AR_CFG));
+                               "%s Setting CFG 0x%x\n", __func__,
+                               REG_READ(ah, AR_CFG));
                }
        } else {
 #ifdef __BIG_ENDIAN
@@ -6078,693 +2339,404 @@ bad:
        return false;
 }
 
-bool ath9k_hw_phy_disable(struct ath_hal *ah)
-{
-       return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
-}
-
-bool ath9k_hw_disable(struct ath_hal *ah)
-{
-       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
-               return false;
+/************************/
+/* Key Cache Management */
+/************************/
 
-       return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
-}
-
-bool
-ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
-                  u8 rxchainmask, bool longcal,
-                  bool *isCalDone)
+bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
 {
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
-       struct ath9k_channel *ichan =
-               ath9k_regd_check_channel(ah, chan);
-
-       *isCalDone = true;
+       u32 keyType;
 
-       if (ichan == NULL) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-                        "%s: invalid channel %u/0x%x; no mapping\n",
-                        __func__, chan->channel, chan->channelFlags);
+       if (entry >= ah->ah_caps.keycache_size) {
+               DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+                       "%s: entry %u out of range\n", __func__, entry);
                return false;
        }
 
-       if (currCal &&
-           (currCal->calState == CAL_RUNNING ||
-            currCal->calState == CAL_WAITING)) {
-               ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
-                                        isCalDone);
-               if (*isCalDone) {
-                       ahp->ah_cal_list_curr = currCal = currCal->calNext;
-
-                       if (currCal->calState == CAL_WAITING) {
-                               *isCalDone = false;
-                               ath9k_hw_reset_calibration(ah, currCal);
-                       }
-               }
-       }
-
-       if (longcal) {
-               ath9k_hw_getnf(ah, ichan);
-               ath9k_hw_loadnf(ah, ah->ah_curchan);
-               ath9k_hw_start_nfcal(ah);
-
-               if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
-
-                       chan->channelFlags |= CHANNEL_CW_INT;
-                       ichan->channelFlags &= ~CHANNEL_CW_INT;
-               }
-       }
-
-       return true;
-}
-
-static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       int i;
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ahp->ah_totalPowerMeasI[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-               ahp->ah_totalPowerMeasQ[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-               ahp->ah_totalIqCorrMeas[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
-                        ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
-                        ahp->ah_totalPowerMeasQ[i],
-                        ahp->ah_totalIqCorrMeas[i]);
-       }
-}
-
-static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       int i;
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ahp->ah_totalAdcIOddPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-               ahp->ah_totalAdcIEvenPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-               ahp->ah_totalAdcQOddPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-               ahp->ah_totalAdcQEvenPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
-                       "oddq=0x%08x; evenq=0x%08x;\n",
-                        ahp->ah_CalSamples, i,
-                        ahp->ah_totalAdcIOddPhase[i],
-                        ahp->ah_totalAdcIEvenPhase[i],
-                        ahp->ah_totalAdcQOddPhase[i],
-                        ahp->ah_totalAdcQEvenPhase[i]);
-       }
-}
-
-static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       int i;
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-               ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-               ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-               ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
-                       "oddq=0x%08x; evenq=0x%08x;\n",
-                        ahp->ah_CalSamples, i,
-                        ahp->ah_totalAdcDcOffsetIOddPhase[i],
-                        ahp->ah_totalAdcDcOffsetIEvenPhase[i],
-                        ahp->ah_totalAdcDcOffsetQOddPhase[i],
-                        ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
-       }
-}
-
-static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       u32 powerMeasQ, powerMeasI, iqCorrMeas;
-       u32 qCoffDenom, iCoffDenom;
-       int32_t qCoff, iCoff;
-       int iqCorrNeg, i;
-
-       for (i = 0; i < numChains; i++) {
-               powerMeasI = ahp->ah_totalPowerMeasI[i];
-               powerMeasQ = ahp->ah_totalPowerMeasQ[i];
-               iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Starting IQ Cal and Correction for Chain %d\n",
-                        i);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Orignal: Chn %diq_corr_meas = 0x%08x\n",
-                        i, ahp->ah_totalIqCorrMeas[i]);
-
-               iqCorrNeg = 0;
-
-
-               if (iqCorrMeas > 0x80000000) {
-                       iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
-                       iqCorrNeg = 1;
-               }
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
-                        iqCorrNeg);
-
-               iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
-               qCoffDenom = powerMeasQ / 64;
-
-               if (powerMeasQ != 0) {
-
-                       iCoff = iqCorrMeas / iCoffDenom;
-                       qCoff = powerMeasI / qCoffDenom - 64;
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                "Chn %d iCoff = 0x%08x\n", i, iCoff);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                "Chn %d qCoff = 0x%08x\n", i, qCoff);
-
-
-                       iCoff = iCoff & 0x3f;
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
-                       if (iqCorrNeg == 0x0)
-                               iCoff = 0x40 - iCoff;
-
-                       if (qCoff > 15)
-                               qCoff = 15;
-                       else if (qCoff <= -16)
-                               qCoff = 16;
-
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
-                               i, iCoff, qCoff);
-
-                       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
-                                     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
-                                     iCoff);
-                       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
-                                     AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
-                                     qCoff);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "IQ Cal and Correction done for Chain %d\n",
-                               i);
-               }
-       }
+       keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
 
-       REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
-                   AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
-}
+       REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
+       REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
 
-static void
-ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
-               qEvenMeasOffset;
-       u32 qGainMismatch, iGainMismatch, val, i;
-
-       for (i = 0; i < numChains; i++) {
-               iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
-               iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
-               qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
-               qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Starting ADC Gain Cal for Chain %d\n", i);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
-                        iOddMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Chn %d pwr_meas_even_i = 0x%08x\n", i,
-                        iEvenMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
-                        qOddMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Chn %d pwr_meas_even_q = 0x%08x\n", i,
-                        qEvenMeasOffset);
-
-               if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
-                       iGainMismatch =
-                               ((iEvenMeasOffset * 32) /
-                                iOddMeasOffset) & 0x3f;
-                       qGainMismatch =
-                               ((qOddMeasOffset * 32) /
-                                qEvenMeasOffset) & 0x3f;
-
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                "Chn %d gain_mismatch_i = 0x%08x\n", i,
-                                iGainMismatch);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                "Chn %d gain_mismatch_q = 0x%08x\n", i,
-                                qGainMismatch);
-
-                       val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
-                       val &= 0xfffff000;
-                       val |= (qGainMismatch) | (iGainMismatch << 6);
-                       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
-
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                "ADC Gain Cal done for Chain %d\n", i);
-               }
-       }
+       if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
+               u16 micentry = entry + 64;
 
-       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
-                 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
-                 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
-}
+               REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
 
-static void
-ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       u32 iOddMeasOffset, iEvenMeasOffset, val, i;
-       int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
-       const struct hal_percal_data *calData =
-               ahp->ah_cal_list_curr->calData;
-       u32 numSamples =
-               (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
-
-       for (i = 0; i < numChains; i++) {
-               iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
-               iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
-               qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
-               qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Starting ADC DC Offset Cal for Chain %d\n", i);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Chn %d pwr_meas_odd_i = %d\n", i,
-                        iOddMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Chn %d pwr_meas_even_i = %d\n", i,
-                        iEvenMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Chn %d pwr_meas_odd_q = %d\n", i,
-                        qOddMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Chn %d pwr_meas_even_q = %d\n", i,
-                        qEvenMeasOffset);
-
-               iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
-                              numSamples) & 0x1ff;
-               qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
-                              numSamples) & 0x1ff;
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
-                        iDcMismatch);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
-                        qDcMismatch);
-
-               val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
-               val &= 0xc0000fff;
-               val |= (qDcMismatch << 12) | (iDcMismatch << 21);
-               REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "ADC DC Offset Cal done for Chain %d\n", i);
        }
 
-       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
-                 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
-                 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
-}
-
-bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ath9k_channel *chan = ah->ah_curchan;
-
-       ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
-
-       if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
-                                ath9k_regd_get_ctl(ah, chan),
-                                ath9k_regd_get_antenna_allowed(ah,
-                                                               chan),
-                                chan->maxRegTxPower * 2,
-                                min((u32) MAX_RATE_POWER,
-                                    (u32) ah->ah_powerLimit)) != 0)
-               return false;
+       if (ah->ah_curchan == NULL)
+               return true;
 
        return true;
 }
 
-void
-ath9k_hw_get_channel_centers(struct ath_hal *ah,
-                            struct ath9k_channel *chan,
-                            struct chan_centers *centers)
+bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac)
 {
-       int8_t extoff;
-       struct ath_hal_5416 *ahp = AH5416(ah);
+       u32 macHi, macLo;
 
-       if (!IS_CHAN_HT40(chan)) {
-               centers->ctl_center = centers->ext_center =
-                       centers->synth_center = chan->channel;
-               return;
+       if (entry >= ah->ah_caps.keycache_size) {
+               DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+                       "%s: entry %u out of range\n", __func__, entry);
+               return false;
        }
 
-       if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
-           (chan->chanmode == CHANNEL_G_HT40PLUS)) {
-               centers->synth_center =
-                       chan->channel + HT40_CHANNEL_CENTER_SHIFT;
-               extoff = 1;
+       if (mac != NULL) {
+               macHi = (mac[5] << 8) | mac[4];
+               macLo = (mac[3] << 24) |
+                       (mac[2] << 16) |
+                       (mac[1] << 8) |
+                       mac[0];
+               macLo >>= 1;
+               macLo |= (macHi & 1) << 31;
+               macHi >>= 1;
        } else {
-               centers->synth_center =
-                       chan->channel - HT40_CHANNEL_CENTER_SHIFT;
-               extoff = -1;
+               macLo = macHi = 0;
        }
+       REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
+       REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
 
-       centers->ctl_center = centers->synth_center - (extoff *
-               HT40_CHANNEL_CENTER_SHIFT);
-       centers->ext_center = centers->synth_center + (extoff *
-               ((ahp->
-               ah_extprotspacing
-               ==
-               ATH9K_HT_EXTPROTSPACING_20)
-               ?
-               HT40_CHANNEL_CENTER_SHIFT
-               : 15));
-
+       return true;
 }
 
-void
-ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
-                       bool *isCalDone)
+bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
+                                const struct ath9k_keyval *k,
+                                const u8 *mac, int xorKey)
 {
+       const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+       u32 key0, key1, key2, key3, key4;
+       u32 keyType;
+       u32 xorMask = xorKey ?
+               (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
+                | ATH9K_KEY_XOR) : 0;
        struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ath9k_channel *ichan =
-               ath9k_regd_check_channel(ah, chan);
-       struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
-
-       *isCalDone = true;
-
-       if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
-               return;
-
-       if (currCal == NULL)
-               return;
 
-       if (ichan == NULL) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "%s: invalid channel %u/0x%x; no mapping\n",
-                        __func__, chan->channel, chan->channelFlags);
-               return;
+       if (entry >= pCap->keycache_size) {
+               DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+                       "%s: entry %u out of range\n", __func__, entry);
+               return false;
        }
 
-
-       if (currCal->calState != CAL_DONE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                        "%s: Calibration state incorrect, %d\n",
-                        __func__, currCal->calState);
-               return;
+       switch (k->kv_type) {
+       case ATH9K_CIPHER_AES_OCB:
+               keyType = AR_KEYTABLE_TYPE_AES;
+               break;
+       case ATH9K_CIPHER_AES_CCM:
+               if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+                               "%s: AES-CCM not supported by "
+                               "mac rev 0x%x\n", __func__,
+                               ah->ah_macRev);
+                       return false;
+               }
+               keyType = AR_KEYTABLE_TYPE_CCM;
+               break;
+       case ATH9K_CIPHER_TKIP:
+               keyType = AR_KEYTABLE_TYPE_TKIP;
+               if (ATH9K_IS_MIC_ENABLED(ah)
+                   && entry + 64 >= pCap->keycache_size) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+                               "%s: entry %u inappropriate for TKIP\n",
+                               __func__, entry);
+                       return false;
+               }
+               break;
+       case ATH9K_CIPHER_WEP:
+               if (k->kv_len < LEN_WEP40) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+                               "%s: WEP key length %u too small\n",
+                               __func__, k->kv_len);
+                       return false;
+               }
+               if (k->kv_len <= LEN_WEP40)
+                       keyType = AR_KEYTABLE_TYPE_40;
+               else if (k->kv_len <= LEN_WEP104)
+                       keyType = AR_KEYTABLE_TYPE_104;
+               else
+                       keyType = AR_KEYTABLE_TYPE_128;
+               break;
+       case ATH9K_CIPHER_CLR:
+               keyType = AR_KEYTABLE_TYPE_CLR;
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+                       "%s: cipher %u not supported\n", __func__,
+                       k->kv_type);
+               return false;
        }
 
+       key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
+       key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
+       key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
+       key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
+       key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
+       if (k->kv_len <= LEN_WEP104)
+               key4 &= 0xff;
 
-       if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
-               return;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                "%s: Resetting Cal %d state for channel %u/0x%x\n",
-                __func__, currCal->calData->calType, chan->channel,
-                chan->channelFlags);
-
-       ichan->CalValid &= ~currCal->calData->calType;
-       currCal->calState = CAL_WAITING;
-
-       *isCalDone = false;
-}
-
-void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-
-       memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
-}
+       if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
+               u16 micentry = entry + 64;
 
-bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
+               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
+               REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
+               REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+               REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
+               REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+               (void) ath9k_hw_keysetmac(ah, entry, mac);
 
-       memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
-       return true;
-}
+               if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
+                       u32 mic0, mic1, mic2, mic3, mic4;
 
-void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
+                       mic0 = get_unaligned_le32(k->kv_mic + 0);
+                       mic2 = get_unaligned_le32(k->kv_mic + 4);
+                       mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
+                       mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
+                       mic4 = get_unaligned_le32(k->kv_txmic + 4);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
+                       REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
+                                 AR_KEYTABLE_TYPE_CLR);
 
-       memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
-}
+               } else {
+                       u32 mic0, mic2;
 
-bool
-ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
+                       mic0 = get_unaligned_le32(k->kv_mic + 0);
+                       mic2 = get_unaligned_le32(k->kv_mic + 4);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
+                       REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
+                                 AR_KEYTABLE_TYPE_CLR);
+               }
+               REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
+               REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
+       } else {
+               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
+               REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
+               REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+               REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
+               REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
 
-       memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
+               (void) ath9k_hw_keysetmac(ah, entry, mac);
+       }
 
-       REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
-       REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
+       if (ah->ah_curchan == NULL)
+               return true;
 
        return true;
 }
 
-void
-ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
-                      u16 assocId)
+bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
 {
-       struct ath_hal_5416 *ahp = AH5416(ah);
-
-       memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
-       ahp->ah_assocId = assocId;
-
-       REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
-       REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
-                 ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
+       if (entry < ah->ah_caps.keycache_size) {
+               u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
+               if (val & AR_KEYTABLE_VALID)
+                       return true;
+       }
+       return false;
 }
 
-u64 ath9k_hw_gettsf64(struct ath_hal *ah)
+/******************************/
+/* Power Management (Chipset) */
+/******************************/
+
+static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
 {
-       u64 tsf;
+       REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+       if (setChip) {
+               REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
+                           AR_RTC_FORCE_WAKE_EN);
+               if (!AR_SREV_9100(ah))
+                       REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
 
-       tsf = REG_READ(ah, AR_TSF_U32);
-       tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
-       return tsf;
+               REG_CLR_BIT(ah, (u16) (AR_RTC_RESET),
+                           AR_RTC_RESET_EN);
+       }
 }
 
-void ath9k_hw_reset_tsf(struct ath_hal *ah)
+static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
 {
-       int count;
+       REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+       if (setChip) {
+               struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
 
-       count = 0;
-       while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
-               count++;
-               if (count > 10) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                        "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
-                                __func__);
-                       break;
+               if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+                       REG_WRITE(ah, AR_RTC_FORCE_WAKE,
+                                 AR_RTC_FORCE_WAKE_ON_INT);
+               } else {
+                       REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
+                                   AR_RTC_FORCE_WAKE_EN);
                }
-               udelay(10);
        }
-       REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
-}
-
-u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
-{
-       return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
 }
 
-void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
+static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
+                                    int setChip)
 {
-       REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
-}
+       u32 val;
+       int i;
 
-bool
-ath9k_hw_setantennaswitch(struct ath_hal *ah,
-                         enum ath9k_ant_setting settings,
-                         struct ath9k_channel *chan,
-                         u8 *tx_chainmask,
-                         u8 *rx_chainmask,
-                         u8 *antenna_cfgd)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       static u8 tx_chainmask_cfg, rx_chainmask_cfg;
+       if (setChip) {
+               if ((REG_READ(ah, AR_RTC_STATUS) &
+                    AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) {
+                       if (ath9k_hw_set_reset_reg(ah,
+                                          ATH9K_RESET_POWER_ON) != true) {
+                               return false;
+                       }
+               }
+               if (AR_SREV_9100(ah))
+                       REG_SET_BIT(ah, AR_RTC_RESET,
+                                   AR_RTC_RESET_EN);
 
-       if (AR_SREV_9280(ah)) {
-               if (!tx_chainmask_cfg) {
+               REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
+                           AR_RTC_FORCE_WAKE_EN);
+               udelay(50);
 
-                       tx_chainmask_cfg = *tx_chainmask;
-                       rx_chainmask_cfg = *rx_chainmask;
+               for (i = POWER_UP_TIME / 50; i > 0; i--) {
+                       val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
+                       if (val == AR_RTC_STATUS_ON)
+                               break;
+                       udelay(50);
+                       REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
+                                   AR_RTC_FORCE_WAKE_EN);
                }
-
-               switch (settings) {
-               case ATH9K_ANT_FIXED_A:
-                       *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
-                       *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
-                       *antenna_cfgd = true;
-                       break;
-               case ATH9K_ANT_FIXED_B:
-                       if (ah->ah_caps.tx_chainmask >
-                           ATH9K_ANTENNA1_CHAINMASK) {
-                               *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
-                       }
-                       *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
-                       *antenna_cfgd = true;
-                       break;
-               case ATH9K_ANT_VARIABLE:
-                       *tx_chainmask = tx_chainmask_cfg;
-                       *rx_chainmask = rx_chainmask_cfg;
-                       *antenna_cfgd = true;
-                       break;
-               default:
-                       break;
+               if (i == 0) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+                               "%s: Failed to wakeup in %uus\n",
+                               __func__, POWER_UP_TIME / 20);
+                       return false;
                }
-       } else {
-               ahp->ah_diversityControl = settings;
        }
 
-       return true;
-}
+       REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
 
-void ath9k_hw_setopmode(struct ath_hal *ah)
-{
-       ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
+       return true;
 }
 
-bool
-ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
-                      u32 capability, u32 *result)
+bool ath9k_hw_setpower(struct ath_hal *ah,
+                      enum ath9k_power_mode mode)
 {
        struct ath_hal_5416 *ahp = AH5416(ah);
-       const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+       static const char *modes[] = {
+               "AWAKE",
+               "FULL-SLEEP",
+               "NETWORK SLEEP",
+               "UNDEFINED"
+       };
+       int status = true, setChip = true;
 
-       switch (type) {
-       case ATH9K_CAP_CIPHER:
-               switch (capability) {
-               case ATH9K_CIPHER_AES_CCM:
-               case ATH9K_CIPHER_AES_OCB:
-               case ATH9K_CIPHER_TKIP:
-               case ATH9K_CIPHER_WEP:
-               case ATH9K_CIPHER_MIC:
-               case ATH9K_CIPHER_CLR:
-                       return true;
-               default:
-                       return false;
-               }
-       case ATH9K_CAP_TKIP_MIC:
-               switch (capability) {
-               case 0:
-                       return true;
-               case 1:
-                       return (ahp->ah_staId1Defaults &
-                               AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
-                       false;
-               }
-       case ATH9K_CAP_TKIP_SPLIT:
-               return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
-                       false : true;
-       case ATH9K_CAP_WME_TKIPMIC:
-               return 0;
-       case ATH9K_CAP_PHYCOUNTERS:
-               return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
-       case ATH9K_CAP_DIVERSITY:
-               return (REG_READ(ah, AR_PHY_CCK_DETECT) &
-                       AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
-                       true : false;
-       case ATH9K_CAP_PHYDIAG:
-               return true;
-       case ATH9K_CAP_MCAST_KEYSRCH:
-               switch (capability) {
-               case 0:
-                       return true;
-               case 1:
-                       if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
-                               return false;
-                       } else {
-                               return (ahp->ah_staId1Defaults &
-                                       AR_STA_ID1_MCAST_KSRCH) ? true :
-                                       false;
-                       }
-               }
-               return false;
-       case ATH9K_CAP_TSF_ADJUST:
-               return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
-                       true : false;
-       case ATH9K_CAP_RFSILENT:
-               if (capability == 3)
-                       return false;
-       case ATH9K_CAP_ANT_CFG_2GHZ:
-               *result = pCap->num_antcfg_2ghz;
-               return true;
-       case ATH9K_CAP_ANT_CFG_5GHZ:
-               *result = pCap->num_antcfg_5ghz;
-               return true;
-       case ATH9K_CAP_TXPOW:
-               switch (capability) {
-               case 0:
-                       return 0;
-               case 1:
-                       *result = ah->ah_powerLimit;
-                       return 0;
-               case 2:
-                       *result = ah->ah_maxPowerLevel;
-                       return 0;
-               case 3:
-                       *result = ah->ah_tpScale;
-                       return 0;
-               }
-               return false;
+       DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__,
+               modes[ahp->ah_powerMode], modes[mode],
+               setChip ? "set chip " : "");
+
+       switch (mode) {
+       case ATH9K_PM_AWAKE:
+               status = ath9k_hw_set_power_awake(ah, setChip);
+               break;
+       case ATH9K_PM_FULL_SLEEP:
+               ath9k_set_power_sleep(ah, setChip);
+               ahp->ah_chipFullSleep = true;
+               break;
+       case ATH9K_PM_NETWORK_SLEEP:
+               ath9k_set_power_network_sleep(ah, setChip);
+               break;
        default:
+               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+                       "%s: unknown power mode %u\n", __func__, mode);
                return false;
        }
+       ahp->ah_powerMode = mode;
+
+       return status;
 }
 
-int
-ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
+void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
 {
        struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ath9k_channel *chan = ah->ah_curchan;
-       const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-       u16 ant_config;
-       u32 halNumAntConfig;
+       u8 i;
+
+       if (ah->ah_isPciExpress != true)
+               return;
 
-       halNumAntConfig =
-               IS_CHAN_2GHZ(chan) ? pCap->num_antcfg_2ghz : pCap->
-               num_antcfg_5ghz;
+       if (ah->ah_config.pcie_powersave_enable == 2)
+               return;
 
-       if (cfg < halNumAntConfig) {
-               if (!ath9k_hw_get_eeprom_antenna_cfg(ahp, chan,
-                                                    cfg, &ant_config)) {
-                       REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
-                       return 0;
+       if (restore)
+               return;
+
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) {
+                       REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0),
+                                 INI_RA(&ahp->ah_iniPcieSerdes, i, 1));
                }
+               udelay(1000);
+       } else if (AR_SREV_9280(ah) &&
+                  (ah->ah_macRev == AR_SREV_REVISION_9280_10)) {
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+
+               REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
+
+               if (ah->ah_config.pcie_clock_req)
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
+               else
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
+
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
+
+               REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+
+               udelay(1000);
+       } else {
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
+               REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
        }
 
-       return -EINVAL;
+       REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+
+       if (ah->ah_config.pcie_waen) {
+               REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
+       } else {
+               if (AR_SREV_9280(ah))
+                       REG_WRITE(ah, AR_WA, 0x0040073f);
+               else
+                       REG_WRITE(ah, AR_WA, 0x0000073f);
+       }
 }
 
+/**********************/
+/* Interrupt Handling */
+/**********************/
+
 bool ath9k_hw_intrpend(struct ath_hal *ah)
 {
        u32 host_isr;
@@ -6791,6 +2763,7 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
        struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
        u32 sync_cause = 0;
        bool fatal_int = false;
+       struct ath_hal_5416 *ahp = AH5416(ah);
 
        if (!AR_SREV_9100(ah)) {
                if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
@@ -6800,9 +2773,8 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
                        }
                }
 
-               sync_cause =
-                       REG_READ(ah,
-                                AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
+               sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
+                       AR_INTR_SYNC_DEFAULT;
 
                *masked = 0;
 
@@ -6814,8 +2786,6 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
        }
 
        if (isr) {
-               struct ath_hal_5416 *ahp = AH5416(ah);
-
                if (isr & AR_ISR_BCNMISC) {
                        u32 isr2;
                        isr2 = REG_READ(ah, AR_ISR_S2);
@@ -6842,7 +2812,6 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
                *masked = isr & ATH9K_INT_COMMON;
 
                if (ahp->ah_intrMitigation) {
-
                        if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
                                *masked |= ATH9K_INT_RX;
                }
@@ -6867,8 +2836,8 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
 
                if (isr & AR_ISR_RXORN) {
                        DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-                                "%s: receive FIFO overrun interrupt\n",
-                                __func__);
+                               "%s: receive FIFO overrun interrupt\n",
+                               __func__);
                }
 
                if (!AR_SREV_9100(ah)) {
@@ -6881,8 +2850,10 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
 
                *masked |= mask2;
        }
+
        if (AR_SREV_9100(ah))
                return true;
+
        if (sync_cause) {
                fatal_int =
                        (sync_cause &
@@ -6892,32 +2863,33 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
                if (fatal_int) {
                        if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
                                DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                                        "%s: received PCI FATAL interrupt\n",
-                                        __func__);
+                                       "%s: received PCI FATAL interrupt\n",
+                                       __func__);
                        }
                        if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
                                DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                                        "%s: received PCI PERR interrupt\n",
-                                        __func__);
+                                       "%s: received PCI PERR interrupt\n",
+                                       __func__);
                        }
                }
                if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
                        DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-                                "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
-                                __func__);
+                               "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
+                               __func__);
                        REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
                        REG_WRITE(ah, AR_RC, 0);
                        *masked |= ATH9K_INT_FATAL;
                }
                if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
                        DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-                                "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
-                                __func__);
+                               "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
+                               __func__);
                }
 
                REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
                (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
        }
+
        return true;
 }
 
@@ -7035,9 +3007,11 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
        return omask;
 }
 
-void
-ath9k_hw_beaconinit(struct ath_hal *ah,
-                   u32 next_beacon, u32 beacon_period)
+/*******************/
+/* Beacon Handling */
+/*******************/
+
+void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period)
 {
        struct ath_hal_5416 *ahp = AH5416(ah);
        int flags = 0;
@@ -7089,9 +3063,8 @@ ath9k_hw_beaconinit(struct ath_hal *ah,
        REG_SET_BIT(ah, AR_TIMER_MODE, flags);
 }
 
-void
-ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
-                              const struct ath9k_beacon_state *bs)
+void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
+                                   const struct ath9k_beacon_state *bs)
 {
        u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
        struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
@@ -7125,1453 +3098,898 @@ ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
        DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next beacon %d\n", __func__,
                 nextTbtt);
        DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: beacon period %d\n", __func__,
-                beaconintval);
-       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__,
-                dtimperiod);
-
-       REG_WRITE(ah, AR_NEXT_DTIM,
-                 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
-       REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
-
-       REG_WRITE(ah, AR_SLEEP1,
-                 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
-                 | AR_SLEEP1_ASSUME_DTIM);
-
-       if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)
-               beacontimeout = (BEACON_TIMEOUT_VAL << 3);
-       else
-               beacontimeout = MIN_BEACON_TIMEOUT_VAL;
-
-       REG_WRITE(ah, AR_SLEEP2,
-                 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
-
-       REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
-       REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
-
-       REG_SET_BIT(ah, AR_TIMER_MODE,
-                   AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
-                   AR_DTIM_TIMER_EN);
-
-}
-
-bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
-{
-       if (entry < ah->ah_caps.keycache_size) {
-               u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
-               if (val & AR_KEYTABLE_VALID)
-                       return true;
-       }
-       return false;
-}
-
-bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
-{
-       u32 keyType;
-
-       if (entry >= ah->ah_caps.keycache_size) {
-               DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
-                        "%s: entry %u out of range\n", __func__, entry);
-               return false;
-       }
-       keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
-
-       REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
-       REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
-       REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
-       REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
-       REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
-       REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
-       REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
-       REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
-
-       if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
-               u16 micentry = entry + 64;
-
-               REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
-
-       }
-
-       if (ah->ah_curchan == NULL)
-               return true;
-
-       return true;
-}
-
-bool
-ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
-                  const u8 *mac)
-{
-       u32 macHi, macLo;
-
-       if (entry >= ah->ah_caps.keycache_size) {
-               DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
-                        "%s: entry %u out of range\n", __func__, entry);
-               return false;
-       }
-
-       if (mac != NULL) {
-               macHi = (mac[5] << 8) | mac[4];
-               macLo = (mac[3] << 24) | (mac[2] << 16)
-                       | (mac[1] << 8) | mac[0];
-               macLo >>= 1;
-               macLo |= (macHi & 1) << 31;
-               macHi >>= 1;
-       } else {
-               macLo = macHi = 0;
-       }
-       REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
-       REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
-
-       return true;
-}
-
-bool
-ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
-                           const struct ath9k_keyval *k,
-                           const u8 *mac, int xorKey)
-{
-       const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-       u32 key0, key1, key2, key3, key4;
-       u32 keyType;
-       u32 xorMask = xorKey ?
-               (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
-                | ATH9K_KEY_XOR) : 0;
-       struct ath_hal_5416 *ahp = AH5416(ah);
-
-       if (entry >= pCap->keycache_size) {
-               DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
-                        "%s: entry %u out of range\n", __func__, entry);
-               return false;
-       }
-       switch (k->kv_type) {
-       case ATH9K_CIPHER_AES_OCB:
-               keyType = AR_KEYTABLE_TYPE_AES;
-               break;
-       case ATH9K_CIPHER_AES_CCM:
-               if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
-                                "%s: AES-CCM not supported by "
-                                "mac rev 0x%x\n", __func__,
-                                ah->ah_macRev);
-                       return false;
-               }
-               keyType = AR_KEYTABLE_TYPE_CCM;
-               break;
-       case ATH9K_CIPHER_TKIP:
-               keyType = AR_KEYTABLE_TYPE_TKIP;
-               if (ATH9K_IS_MIC_ENABLED(ah)
-                   && entry + 64 >= pCap->keycache_size) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
-                                "%s: entry %u inappropriate for TKIP\n",
-                                __func__, entry);
-                       return false;
-               }
-               break;
-       case ATH9K_CIPHER_WEP:
-               if (k->kv_len < LEN_WEP40) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
-                                "%s: WEP key length %u too small\n",
-                                __func__, k->kv_len);
-                       return false;
-               }
-               if (k->kv_len <= LEN_WEP40)
-                       keyType = AR_KEYTABLE_TYPE_40;
-               else if (k->kv_len <= LEN_WEP104)
-                       keyType = AR_KEYTABLE_TYPE_104;
-               else
-                       keyType = AR_KEYTABLE_TYPE_128;
-               break;
-       case ATH9K_CIPHER_CLR:
-               keyType = AR_KEYTABLE_TYPE_CLR;
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
-                        "%s: cipher %u not supported\n", __func__,
-                        k->kv_type);
-               return false;
-       }
-
-       key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
-       key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
-       key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
-       key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
-       key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
-       if (k->kv_len <= LEN_WEP104)
-               key4 &= 0xff;
-
-       if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
-               u16 micentry = entry + 64;
-
-               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
-               REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
-               REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
-               REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
-               REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
-               (void) ath9k_hw_keysetmac(ah, entry, mac);
+                beaconintval);
+       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__,
+                dtimperiod);
 
-               if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
-                       u32 mic0, mic1, mic2, mic3, mic4;
+       REG_WRITE(ah, AR_NEXT_DTIM,
+                 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
+       REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
 
-                       mic0 = get_unaligned_le32(k->kv_mic + 0);
-                       mic2 = get_unaligned_le32(k->kv_mic + 4);
-                       mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
-                       mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
-                       mic4 = get_unaligned_le32(k->kv_txmic + 4);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
-                       REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
-                                 AR_KEYTABLE_TYPE_CLR);
+       REG_WRITE(ah, AR_SLEEP1,
+                 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
+                 | AR_SLEEP1_ASSUME_DTIM);
 
-               } else {
-                       u32 mic0, mic2;
+       if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)
+               beacontimeout = (BEACON_TIMEOUT_VAL << 3);
+       else
+               beacontimeout = MIN_BEACON_TIMEOUT_VAL;
 
-                       mic0 = get_unaligned_le32(k->kv_mic + 0);
-                       mic2 = get_unaligned_le32(k->kv_mic + 4);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
-                       REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
-                                 AR_KEYTABLE_TYPE_CLR);
-               }
-               REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
-               REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
-       } else {
-               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
-               REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
-               REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
-               REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
-               REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+       REG_WRITE(ah, AR_SLEEP2,
+                 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
 
-               (void) ath9k_hw_keysetmac(ah, entry, mac);
-       }
+       REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
+       REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
 
-       if (ah->ah_curchan == NULL)
-               return true;
+       REG_SET_BIT(ah, AR_TIMER_MODE,
+                   AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
+                   AR_DTIM_TIMER_EN);
 
-       return true;
 }
 
-bool
-ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       u32 txcfg, curLevel, newLevel;
-       enum ath9k_int omask;
+/***************/
+/* Rate tables */
+/***************/
 
-       if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
-               return false;
+static struct ath9k_rate_table ar5416_11a_table = {
+       8,
+       {0},
+       {
+               {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
+               {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
+               {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
+               {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
+               {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
+               {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
+               {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
+               {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4}
+       },
+};
 
-       omask = ath9k_hw_set_interrupts(ah,
-                                       ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
+static struct ath9k_rate_table ar5416_11b_table = {
+       4,
+       {0},
+       {
+               {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
+               {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
+               {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 1},
+               {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 1}
+       },
+};
 
-       txcfg = REG_READ(ah, AR_TXCFG);
-       curLevel = MS(txcfg, AR_FTRIG);
-       newLevel = curLevel;
-       if (bIncTrigLevel) {
-               if (curLevel < MAX_TX_FIFO_THRESHOLD)
-                       newLevel++;
-       } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
-               newLevel--;
-       if (newLevel != curLevel)
-               REG_WRITE(ah, AR_TXCFG,
-                         (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
+static struct ath9k_rate_table ar5416_11g_table = {
+       12,
+       {0},
+       {
+               {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
+               {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
+               {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
+               {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
 
-       ath9k_hw_set_interrupts(ah, omask);
+               {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
+               {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
+               {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
+               {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
+               {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
+               {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
+               {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
+               {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8}
+       },
+};
 
-       ah->ah_txTrigLevel = newLevel;
+static struct ath9k_rate_table ar5416_11ng_table = {
+       28,
+       {0},
+       {
+               {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
+               {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
+               {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
+               {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
 
-       return newLevel != curLevel;
-}
+               {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
+               {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
+               {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
+               {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
+               {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
+               {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
+               {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
+               {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8},
+               {true, PHY_HT, 6500, 0x80, 0x00, 0, 4},
+               {true, PHY_HT, 13000, 0x81, 0x00, 1, 6},
+               {true, PHY_HT, 19500, 0x82, 0x00, 2, 6},
+               {true, PHY_HT, 26000, 0x83, 0x00, 3, 8},
+               {true, PHY_HT, 39000, 0x84, 0x00, 4, 8},
+               {true, PHY_HT, 52000, 0x85, 0x00, 5, 8},
+               {true, PHY_HT, 58500, 0x86, 0x00, 6, 8},
+               {true, PHY_HT, 65000, 0x87, 0x00, 7, 8},
+               {true, PHY_HT, 13000, 0x88, 0x00, 8, 4},
+               {true, PHY_HT, 26000, 0x89, 0x00, 9, 6},
+               {true, PHY_HT, 39000, 0x8a, 0x00, 10, 6},
+               {true, PHY_HT, 52000, 0x8b, 0x00, 11, 8},
+               {true, PHY_HT, 78000, 0x8c, 0x00, 12, 8},
+               {true, PHY_HT, 104000, 0x8d, 0x00, 13, 8},
+               {true, PHY_HT, 117000, 0x8e, 0x00, 14, 8},
+               {true, PHY_HT, 130000, 0x8f, 0x00, 15, 8},
+       },
+};
+
+static struct ath9k_rate_table ar5416_11na_table = {
+       24,
+       {0},
+       {
+               {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
+               {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
+               {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
+               {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
+               {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
+               {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
+               {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
+               {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4},
+               {true, PHY_HT, 6500, 0x80, 0x00, 0, 0},
+               {true, PHY_HT, 13000, 0x81, 0x00, 1, 2},
+               {true, PHY_HT, 19500, 0x82, 0x00, 2, 2},
+               {true, PHY_HT, 26000, 0x83, 0x00, 3, 4},
+               {true, PHY_HT, 39000, 0x84, 0x00, 4, 4},
+               {true, PHY_HT, 52000, 0x85, 0x00, 5, 4},
+               {true, PHY_HT, 58500, 0x86, 0x00, 6, 4},
+               {true, PHY_HT, 65000, 0x87, 0x00, 7, 4},
+               {true, PHY_HT, 13000, 0x88, 0x00, 8, 0},
+               {true, PHY_HT, 26000, 0x89, 0x00, 9, 2},
+               {true, PHY_HT, 39000, 0x8a, 0x00, 10, 2},
+               {true, PHY_HT, 52000, 0x8b, 0x00, 11, 4},
+               {true, PHY_HT, 78000, 0x8c, 0x00, 12, 4},
+               {true, PHY_HT, 104000, 0x8d, 0x00, 13, 4},
+               {true, PHY_HT, 117000, 0x8e, 0x00, 14, 4},
+               {true, PHY_HT, 130000, 0x8f, 0x00, 15, 4},
+       },
+};
 
-bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
-                           const struct ath9k_tx_queue_info *qinfo)
+static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
+                                     struct ath9k_rate_table *rt)
 {
-       u32 cw;
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-       struct ath9k_tx_queue_info *qi;
+       int i;
 
-       if (q >= pCap->total_queues) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
-                        __func__, q);
-               return false;
-       }
+       if (rt->rateCodeToIndex[0] != 0)
+               return;
 
-       qi = &ahp->ah_txq[q];
-       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
-                        __func__);
-               return false;
+       for (i = 0; i < 256; i++)
+               rt->rateCodeToIndex[i] = (u8) -1;
+
+       for (i = 0; i < rt->rateCount; i++) {
+               u8 code = rt->info[i].rateCode;
+               u8 cix = rt->info[i].controlRate;
+
+               rt->rateCodeToIndex[code] = i;
+               rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
+
+               rt->info[i].lpAckDuration =
+                       ath9k_hw_computetxtime(ah, rt,
+                                              WLAN_CTRL_FRAME_SIZE,
+                                              cix,
+                                              false);
+               rt->info[i].spAckDuration =
+                       ath9k_hw_computetxtime(ah, rt,
+                                              WLAN_CTRL_FRAME_SIZE,
+                                              cix,
+                                              true);
        }
+}
 
-       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
+const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
+                                                    u32 mode)
+{
+       struct ath9k_rate_table *rt;
 
-       qi->tqi_ver = qinfo->tqi_ver;
-       qi->tqi_subtype = qinfo->tqi_subtype;
-       qi->tqi_qflags = qinfo->tqi_qflags;
-       qi->tqi_priority = qinfo->tqi_priority;
-       if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
-               qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
-       else
-               qi->tqi_aifs = INIT_AIFS;
-       if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
-               cw = min(qinfo->tqi_cwmin, 1024U);
-               qi->tqi_cwmin = 1;
-               while (qi->tqi_cwmin < cw)
-                       qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
-       } else
-               qi->tqi_cwmin = qinfo->tqi_cwmin;
-       if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
-               cw = min(qinfo->tqi_cwmax, 1024U);
-               qi->tqi_cwmax = 1;
-               while (qi->tqi_cwmax < cw)
-                       qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
-       } else
-               qi->tqi_cwmax = INIT_CWMAX;
-
-       if (qinfo->tqi_shretry != 0)
-               qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
-       else
-               qi->tqi_shretry = INIT_SH_RETRY;
-       if (qinfo->tqi_lgretry != 0)
-               qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
-       else
-               qi->tqi_lgretry = INIT_LG_RETRY;
-       qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
-       qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
-       qi->tqi_burstTime = qinfo->tqi_burstTime;
-       qi->tqi_readyTime = qinfo->tqi_readyTime;
-
-       switch (qinfo->tqi_subtype) {
-       case ATH9K_WME_UPSD:
-               if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
-                       qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
+       switch (mode) {
+       case ATH9K_MODE_11A:
+               rt = &ar5416_11a_table;
                break;
-       default:
+       case ATH9K_MODE_11B:
+               rt = &ar5416_11b_table;
+               break;
+       case ATH9K_MODE_11G:
+               rt = &ar5416_11g_table;
+               break;
+       case ATH9K_MODE_11NG_HT20:
+       case ATH9K_MODE_11NG_HT40PLUS:
+       case ATH9K_MODE_11NG_HT40MINUS:
+               rt = &ar5416_11ng_table;
+               break;
+       case ATH9K_MODE_11NA_HT20:
+       case ATH9K_MODE_11NA_HT40PLUS:
+       case ATH9K_MODE_11NA_HT40MINUS:
+               rt = &ar5416_11na_table;
                break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n",
+                       __func__, mode);
+               return NULL;
        }
-       return true;
+
+       ath9k_hw_setup_rate_table(ah, rt);
+
+       return rt;
 }
 
-bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
-                           struct ath9k_tx_queue_info *qinfo)
+/*******************/
+/* HW Capabilities */
+/*******************/
+
+bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
 {
        struct ath_hal_5416 *ahp = AH5416(ah);
        struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-       struct ath9k_tx_queue_info *qi;
+       u16 capField = 0, eeval;
 
-       if (q >= pCap->total_queues) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
-                        __func__, q);
-               return false;
-       }
+       eeval = ath9k_hw_get_eeprom(ah, EEP_REG_0);
 
-       qi = &ahp->ah_txq[q];
-       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
-                        __func__);
-               return false;
-       }
+       ah->ah_currentRD = eeval;
 
-       qinfo->tqi_qflags = qi->tqi_qflags;
-       qinfo->tqi_ver = qi->tqi_ver;
-       qinfo->tqi_subtype = qi->tqi_subtype;
-       qinfo->tqi_qflags = qi->tqi_qflags;
-       qinfo->tqi_priority = qi->tqi_priority;
-       qinfo->tqi_aifs = qi->tqi_aifs;
-       qinfo->tqi_cwmin = qi->tqi_cwmin;
-       qinfo->tqi_cwmax = qi->tqi_cwmax;
-       qinfo->tqi_shretry = qi->tqi_shretry;
-       qinfo->tqi_lgretry = qi->tqi_lgretry;
-       qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
-       qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
-       qinfo->tqi_burstTime = qi->tqi_burstTime;
-       qinfo->tqi_readyTime = qi->tqi_readyTime;
+       eeval = ath9k_hw_get_eeprom(ah, EEP_REG_1);
+       ah->ah_currentRDExt = eeval;
 
-       return true;
-}
+       capField = ath9k_hw_get_eeprom(ah, EEP_OP_CAP);
+
+       if (ah->ah_opmode != ATH9K_M_HOSTAP &&
+           ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) {
+               if (ah->ah_currentRD == 0x64 || ah->ah_currentRD == 0x65)
+                       ah->ah_currentRD += 5;
+               else if (ah->ah_currentRD == 0x41)
+                       ah->ah_currentRD = 0x43;
+               DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
+                       "%s: regdomain mapped to 0x%x\n", __func__,
+                       ah->ah_currentRD);
+       }
 
-int
-ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
-                     const struct ath9k_tx_queue_info *qinfo)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ath9k_tx_queue_info *qi;
-       struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-       int q;
+       eeval = ath9k_hw_get_eeprom(ah, EEP_OP_MODE);
+       bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
 
-       switch (type) {
-       case ATH9K_TX_QUEUE_BEACON:
-               q = pCap->total_queues - 1;
-               break;
-       case ATH9K_TX_QUEUE_CAB:
-               q = pCap->total_queues - 2;
-               break;
-       case ATH9K_TX_QUEUE_PSPOLL:
-               q = 1;
-               break;
-       case ATH9K_TX_QUEUE_UAPSD:
-               q = pCap->total_queues - 3;
-               break;
-       case ATH9K_TX_QUEUE_DATA:
-               for (q = 0; q < pCap->total_queues; q++)
-                       if (ahp->ah_txq[q].tqi_type ==
-                           ATH9K_TX_QUEUE_INACTIVE)
-                               break;
-               if (q == pCap->total_queues) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-                                "%s: no available tx queue\n", __func__);
-                       return -1;
+       if (eeval & AR5416_OPFLAGS_11A) {
+               set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
+               if (ah->ah_config.ht_enable) {
+                       if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
+                               set_bit(ATH9K_MODE_11NA_HT20,
+                                       pCap->wireless_modes);
+                       if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
+                               set_bit(ATH9K_MODE_11NA_HT40PLUS,
+                                       pCap->wireless_modes);
+                               set_bit(ATH9K_MODE_11NA_HT40MINUS,
+                                       pCap->wireless_modes);
+                       }
                }
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
-                        __func__, type);
-               return -1;
        }
 
-       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
-
-       qi = &ahp->ah_txq[q];
-       if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-                        "%s: tx queue %u already active\n", __func__, q);
-               return -1;
+       if (eeval & AR5416_OPFLAGS_11G) {
+               set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
+               set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
+               if (ah->ah_config.ht_enable) {
+                       if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
+                               set_bit(ATH9K_MODE_11NG_HT20,
+                                       pCap->wireless_modes);
+                       if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
+                               set_bit(ATH9K_MODE_11NG_HT40PLUS,
+                                       pCap->wireless_modes);
+                               set_bit(ATH9K_MODE_11NG_HT40MINUS,
+                                       pCap->wireless_modes);
+                       }
+               }
        }
-       memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
-       qi->tqi_type = type;
-       if (qinfo == NULL) {
-               qi->tqi_qflags =
-                       TXQ_FLAG_TXOKINT_ENABLE
-                       | TXQ_FLAG_TXERRINT_ENABLE
-                       | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
-               qi->tqi_aifs = INIT_AIFS;
-               qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
-               qi->tqi_cwmax = INIT_CWMAX;
-               qi->tqi_shretry = INIT_SH_RETRY;
-               qi->tqi_lgretry = INIT_LG_RETRY;
-               qi->tqi_physCompBuf = 0;
+
+       pCap->tx_chainmask = ath9k_hw_get_eeprom(ah, EEP_TX_MASK);
+       if ((ah->ah_isPciExpress)
+           || (eeval & AR5416_OPFLAGS_11A)) {
+               pCap->rx_chainmask =
+                       ath9k_hw_get_eeprom(ah, EEP_RX_MASK);
        } else {
-               qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
-               (void) ath9k_hw_set_txq_props(ah, q, qinfo);
+               pCap->rx_chainmask =
+                       (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
        }
 
-       return q;
-}
-
-static void
-ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
-                           struct ath9k_tx_queue_info *qi)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-
-       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-                "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
-                __func__, ahp->ah_txOkInterruptMask,
-                ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
-                ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask);
-
-       REG_WRITE(ah, AR_IMR_S0,
-                 SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
-                 | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
-       REG_WRITE(ah, AR_IMR_S1,
-                 SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
-                 | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
-       REG_RMW_FIELD(ah, AR_IMR_S2,
-                     AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
-}
+       if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0)))
+               ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA;
 
-bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-       struct ath9k_tx_queue_info *qi;
+       pCap->low_2ghz_chan = 2312;
+       pCap->high_2ghz_chan = 2732;
 
-       if (q >= pCap->total_queues) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
-                        __func__, q);
-               return false;
-       }
-       qi = &ahp->ah_txq[q];
-       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
-                        __func__, q);
-               return false;
-       }
+       pCap->low_5ghz_chan = 4920;
+       pCap->high_5ghz_chan = 6100;
 
-       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
-               __func__, q);
+       pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP;
+       pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP;
+       pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM;
 
-       qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
-       ahp->ah_txOkInterruptMask &= ~(1 << q);
-       ahp->ah_txErrInterruptMask &= ~(1 << q);
-       ahp->ah_txDescInterruptMask &= ~(1 << q);
-       ahp->ah_txEolInterruptMask &= ~(1 << q);
-       ahp->ah_txUrnInterruptMask &= ~(1 << q);
-       ath9k_hw_set_txq_interrupts(ah, qi);
+       pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP;
+       pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
+       pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
 
-       return true;
-}
+       pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
 
-bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-       struct ath9k_channel *chan = ah->ah_curchan;
-       struct ath9k_tx_queue_info *qi;
-       u32 cwMin, chanCwMin, value;
+       if (ah->ah_config.ht_enable)
+               pCap->hw_caps |= ATH9K_HW_CAP_HT;
+       else
+               pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
 
-       if (q >= pCap->total_queues) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
-                        __func__, q);
-               return false;
-       }
-       qi = &ahp->ah_txq[q];
-       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
-                        __func__, q);
-               return true;
-       }
+       pCap->hw_caps |= ATH9K_HW_CAP_GTT;
+       pCap->hw_caps |= ATH9K_HW_CAP_VEOL;
+       pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK;
+       pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH;
 
-       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
+       if (capField & AR_EEPROM_EEPCAP_MAXQCU)
+               pCap->total_queues =
+                       MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
+       else
+               pCap->total_queues = ATH9K_NUM_TX_QUEUES;
 
-       if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
-               if (chan && IS_CHAN_B(chan))
-                       chanCwMin = INIT_CWMIN_11B;
-               else
-                       chanCwMin = INIT_CWMIN;
-
-               for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
-       } else
-               cwMin = qi->tqi_cwmin;
-
-       REG_WRITE(ah, AR_DLCL_IFS(q), SM(cwMin, AR_D_LCL_IFS_CWMIN)
-                 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
-                 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
-
-       REG_WRITE(ah, AR_DRETRY_LIMIT(q),
-                 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
-                 | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
-                 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
-
-       REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
-       REG_WRITE(ah, AR_DMISC(q),
-                 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
-
-       if (qi->tqi_cbrPeriod) {
-               REG_WRITE(ah, AR_QCBRCFG(q),
-                         SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL)
-                         | SM(qi->tqi_cbrOverflowLimit,
-                              AR_Q_CBRCFG_OVF_THRESH));
-               REG_WRITE(ah, AR_QMISC(q),
-                         REG_READ(ah,
-                                  AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | (qi->
-                                       tqi_cbrOverflowLimit
-                                       ?
-                                       AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN
-                                       :
-                                       0));
-       }
-       if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
-               REG_WRITE(ah, AR_QRDYTIMECFG(q),
-                         SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
-                         AR_Q_RDYTIMECFG_EN);
-       }
+       if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
+               pCap->keycache_size =
+                       1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
+       else
+               pCap->keycache_size = AR_KEYTABLE_SIZE;
 
-       REG_WRITE(ah, AR_DCHNTIME(q),
-                 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
-                 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
+       pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
+       pCap->num_mr_retries = 4;
+       pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
 
-       if (qi->tqi_burstTime
-           && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
-               REG_WRITE(ah, AR_QMISC(q),
-                         REG_READ(ah,
-                                  AR_QMISC(q)) |
-                         AR_Q_MISC_RDYTIME_EXP_POLICY);
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               pCap->num_gpio_pins = AR928X_NUM_GPIO;
+       else
+               pCap->num_gpio_pins = AR_NUM_GPIO;
 
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               pCap->hw_caps |= ATH9K_HW_CAP_WOW;
+               pCap->hw_caps |= ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
+       } else {
+               pCap->hw_caps &= ~ATH9K_HW_CAP_WOW;
+               pCap->hw_caps &= ~ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
        }
 
-       if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
-               REG_WRITE(ah, AR_DMISC(q),
-                         REG_READ(ah, AR_DMISC(q)) |
-                         AR_D_MISC_POST_FR_BKOFF_DIS);
-       }
-       if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
-               REG_WRITE(ah, AR_DMISC(q),
-                         REG_READ(ah, AR_DMISC(q)) |
-                         AR_D_MISC_FRAG_BKOFF_EN);
-       }
-       switch (qi->tqi_type) {
-       case ATH9K_TX_QUEUE_BEACON:
-               REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
-                         | AR_Q_MISC_FSP_DBA_GATED
-                         | AR_Q_MISC_BEACON_USE
-                         | AR_Q_MISC_CBR_INCR_DIS1);
-
-               REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
-                         | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
-                            AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
-                         | AR_D_MISC_BEACON_USE
-                         | AR_D_MISC_POST_FR_BKOFF_DIS);
-               break;
-       case ATH9K_TX_QUEUE_CAB:
-               REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
-                         | AR_Q_MISC_FSP_DBA_GATED
-                         | AR_Q_MISC_CBR_INCR_DIS1
-                         | AR_Q_MISC_CBR_INCR_DIS0);
-               value = (qi->tqi_readyTime
-                        - (ah->ah_config.sw_beacon_response_time -
-                           ah->ah_config.dma_beacon_response_time)
-                        -
-                        ah->ah_config.additional_swba_backoff) *
-                       1024;
-               REG_WRITE(ah, AR_QRDYTIMECFG(q),
-                         value | AR_Q_RDYTIMECFG_EN);
-               REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
-                         | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
-                            AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
-               break;
-       case ATH9K_TX_QUEUE_PSPOLL:
-               REG_WRITE(ah, AR_QMISC(q),
-                         REG_READ(ah,
-                                  AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
-               break;
-       case ATH9K_TX_QUEUE_UAPSD:
-               REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
-                         | AR_D_MISC_POST_FR_BKOFF_DIS);
-               break;
-       default:
-               break;
+       if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
+               pCap->hw_caps |= ATH9K_HW_CAP_CST;
+               pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
+       } else {
+               pCap->rts_aggr_limit = (8 * 1024);
        }
 
-       if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
-               REG_WRITE(ah, AR_DMISC(q),
-                         REG_READ(ah, AR_DMISC(q)) |
-                         SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
-                            AR_D_MISC_ARB_LOCKOUT_CNTRL) |
-                         AR_D_MISC_POST_FR_BKOFF_DIS);
+       pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
+
+#ifdef CONFIG_RFKILL
+       ah->ah_rfsilent = ath9k_hw_get_eeprom(ah, EEP_RF_SILENT);
+       if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) {
+               ah->ah_rfkill_gpio =
+                       MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL);
+               ah->ah_rfkill_polarity =
+                       MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY);
+
+               pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
        }
+#endif
 
-       if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
-               ahp->ah_txOkInterruptMask |= 1 << q;
-       else
-               ahp->ah_txOkInterruptMask &= ~(1 << q);
-       if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
-               ahp->ah_txErrInterruptMask |= 1 << q;
-       else
-               ahp->ah_txErrInterruptMask &= ~(1 << q);
-       if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
-               ahp->ah_txDescInterruptMask |= 1 << q;
-       else
-               ahp->ah_txDescInterruptMask &= ~(1 << q);
-       if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
-               ahp->ah_txEolInterruptMask |= 1 << q;
-       else
-               ahp->ah_txEolInterruptMask &= ~(1 << q);
-       if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
-               ahp->ah_txUrnInterruptMask |= 1 << q;
+       if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) ||
+           (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) ||
+           (ah->ah_macVersion == AR_SREV_VERSION_9160) ||
+           (ah->ah_macVersion == AR_SREV_VERSION_9100) ||
+           (ah->ah_macVersion == AR_SREV_VERSION_9280))
+               pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
        else
-               ahp->ah_txUrnInterruptMask &= ~(1 << q);
-       ath9k_hw_set_txq_interrupts(ah, qi);
-
-       return true;
-}
+               pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
 
-void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
-{
-       struct ath_hal_5416 *ahp = AH5416(ah);
-       *txqs &= ahp->ah_intrTxqs;
-       ahp->ah_intrTxqs &= ~(*txqs);
-}
+       if (AR_SREV_9280(ah))
+               pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
+       else
+               pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
 
-bool
-ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
-                   u32 segLen, bool firstSeg,
-                   bool lastSeg, const struct ath_desc *ds0)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       if (firstSeg) {
-               ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
-       } else if (lastSeg) {
-               ads->ds_ctl0 = 0;
-               ads->ds_ctl1 = segLen;
-               ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
-               ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
+       if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) {
+               pCap->reg_cap =
+                       AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
+                       AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
+                       AR_EEPROM_EEREGCAP_EN_KK_U2 |
+                       AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
        } else {
-               ads->ds_ctl0 = 0;
-               ads->ds_ctl1 = segLen | AR_TxMore;
-               ads->ds_ctl2 = 0;
-               ads->ds_ctl3 = 0;
+               pCap->reg_cap =
+                       AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
+                       AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
        }
-       ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
-       ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
-       ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
-       ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
-       ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
-       return true;
-}
 
-void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
+       pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
+
+       pCap->num_antcfg_5ghz =
+               ath9k_hw_get_num_ant_config(ah, IEEE80211_BAND_5GHZ);
+       pCap->num_antcfg_2ghz =
+               ath9k_hw_get_num_ant_config(ah, IEEE80211_BAND_2GHZ);
 
-       ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
-       ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
-       ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
-       ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
-       ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
+       return true;
 }
 
-int
-ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
+bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
+                           u32 capability, u32 *result)
 {
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       if ((ads->ds_txstatus9 & AR_TxDone) == 0)
-               return -EINPROGRESS;
-
-       ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
-       ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
-       ds->ds_txstat.ts_status = 0;
-       ds->ds_txstat.ts_flags = 0;
-
-       if (ads->ds_txstatus1 & AR_ExcessiveRetries)
-               ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
-       if (ads->ds_txstatus1 & AR_Filtered)
-               ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
-       if (ads->ds_txstatus1 & AR_FIFOUnderrun)
-               ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
-       if (ads->ds_txstatus9 & AR_TxOpExceeded)
-               ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
-       if (ads->ds_txstatus1 & AR_TxTimerExpired)
-               ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
-
-       if (ads->ds_txstatus1 & AR_DescCfgErr)
-               ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
-       if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
-               ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
-               ath9k_hw_updatetxtriglevel(ah, true);
-       }
-       if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
-               ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
-               ath9k_hw_updatetxtriglevel(ah, true);
-       }
-       if (ads->ds_txstatus0 & AR_TxBaStatus) {
-               ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
-               ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
-               ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
-       }
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
 
-       ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
-       switch (ds->ds_txstat.ts_rateindex) {
-       case 0:
-               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
-               break;
-       case 1:
-               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
-               break;
-       case 2:
-               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
-               break;
-       case 3:
-               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
-               break;
+       switch (type) {
+       case ATH9K_CAP_CIPHER:
+               switch (capability) {
+               case ATH9K_CIPHER_AES_CCM:
+               case ATH9K_CIPHER_AES_OCB:
+               case ATH9K_CIPHER_TKIP:
+               case ATH9K_CIPHER_WEP:
+               case ATH9K_CIPHER_MIC:
+               case ATH9K_CIPHER_CLR:
+                       return true;
+               default:
+                       return false;
+               }
+       case ATH9K_CAP_TKIP_MIC:
+               switch (capability) {
+               case 0:
+                       return true;
+               case 1:
+                       return (ahp->ah_staId1Defaults &
+                               AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
+                       false;
+               }
+       case ATH9K_CAP_TKIP_SPLIT:
+               return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
+                       false : true;
+       case ATH9K_CAP_WME_TKIPMIC:
+               return 0;
+       case ATH9K_CAP_PHYCOUNTERS:
+               return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
+       case ATH9K_CAP_DIVERSITY:
+               return (REG_READ(ah, AR_PHY_CCK_DETECT) &
+                       AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
+                       true : false;
+       case ATH9K_CAP_PHYDIAG:
+               return true;
+       case ATH9K_CAP_MCAST_KEYSRCH:
+               switch (capability) {
+               case 0:
+                       return true;
+               case 1:
+                       if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
+                               return false;
+                       } else {
+                               return (ahp->ah_staId1Defaults &
+                                       AR_STA_ID1_MCAST_KSRCH) ? true :
+                                       false;
+                       }
+               }
+               return false;
+       case ATH9K_CAP_TSF_ADJUST:
+               return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
+                       true : false;
+       case ATH9K_CAP_RFSILENT:
+               if (capability == 3)
+                       return false;
+       case ATH9K_CAP_ANT_CFG_2GHZ:
+               *result = pCap->num_antcfg_2ghz;
+               return true;
+       case ATH9K_CAP_ANT_CFG_5GHZ:
+               *result = pCap->num_antcfg_5ghz;
+               return true;
+       case ATH9K_CAP_TXPOW:
+               switch (capability) {
+               case 0:
+                       return 0;
+               case 1:
+                       *result = ah->ah_powerLimit;
+                       return 0;
+               case 2:
+                       *result = ah->ah_maxPowerLevel;
+                       return 0;
+               case 3:
+                       *result = ah->ah_tpScale;
+                       return 0;
+               }
+               return false;
+       default:
+               return false;
        }
-
-       ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
-       ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
-       ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
-       ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
-       ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
-       ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
-       ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
-       ds->ds_txstat.evm0 = ads->AR_TxEVM0;
-       ds->ds_txstat.evm1 = ads->AR_TxEVM1;
-       ds->ds_txstat.evm2 = ads->AR_TxEVM2;
-       ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
-       ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
-       ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
-       ds->ds_txstat.ts_antenna = 1;
-
-       return 0;
 }
 
-void
-ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
-                      u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
-                      u32 keyIx, enum ath9k_key_type keyType, u32 flags)
+bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type,
+                           u32 capability, u32 setting, int *status)
 {
-       struct ar5416_desc *ads = AR5416DESC(ds);
        struct ath_hal_5416 *ahp = AH5416(ah);
+       u32 v;
 
-       txPower += ahp->ah_txPowerIndexOffset;
-       if (txPower > 63)
-               txPower = 63;
-
-       ads->ds_ctl0 = (pktLen & AR_FrameLen)
-               | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
-               | SM(txPower, AR_XmitPower)
-               | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
-               | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
-               | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
-               | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
-
-       ads->ds_ctl1 =
-               (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
-               | SM(type, AR_FrameType)
-               | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
-               | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
-               | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
-
-       ads->ds_ctl6 = SM(keyType, AR_EncrType);
-
-       if (AR_SREV_9285(ah)) {
-
-               ads->ds_ctl8 = 0;
-               ads->ds_ctl9 = 0;
-               ads->ds_ctl10 = 0;
-               ads->ds_ctl11 = 0;
+       switch (type) {
+       case ATH9K_CAP_TKIP_MIC:
+               if (setting)
+                       ahp->ah_staId1Defaults |=
+                               AR_STA_ID1_CRPT_MIC_ENABLE;
+               else
+                       ahp->ah_staId1Defaults &=
+                               ~AR_STA_ID1_CRPT_MIC_ENABLE;
+               return true;
+       case ATH9K_CAP_DIVERSITY:
+               v = REG_READ(ah, AR_PHY_CCK_DETECT);
+               if (setting)
+                       v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+               else
+                       v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+               REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
+               return true;
+       case ATH9K_CAP_MCAST_KEYSRCH:
+               if (setting)
+                       ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
+               else
+                       ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
+               return true;
+       case ATH9K_CAP_TSF_ADJUST:
+               if (setting)
+                       ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
+               else
+                       ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
+               return true;
+       default:
+               return false;
        }
 }
 
-void
-ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
-                            struct ath_desc *lastds,
-                            u32 durUpdateEn, u32 rtsctsRate,
-                            u32 rtsctsDuration,
-                            struct ath9k_11n_rate_series series[],
-                            u32 nseries, u32 flags)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-       struct ar5416_desc *last_ads = AR5416DESC(lastds);
-       u32 ds_ctl0;
+/****************************/
+/* GPIO / RFKILL / Antennae */
+/****************************/
 
-       (void) nseries;
-       (void) rtsctsDuration;
+static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
+                                        u32 gpio, u32 type)
+{
+       int addr;
+       u32 gpio_shift, tmp;
 
-       if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
-               ds_ctl0 = ads->ds_ctl0;
+       if (gpio > 11)
+               addr = AR_GPIO_OUTPUT_MUX3;
+       else if (gpio > 5)
+               addr = AR_GPIO_OUTPUT_MUX2;
+       else
+               addr = AR_GPIO_OUTPUT_MUX1;
 
-               if (flags & ATH9K_TXDESC_RTSENA) {
-                       ds_ctl0 &= ~AR_CTSEnable;
-                       ds_ctl0 |= AR_RTSEnable;
-               } else {
-                       ds_ctl0 &= ~AR_RTSEnable;
-                       ds_ctl0 |= AR_CTSEnable;
-               }
+       gpio_shift = (gpio % 6) * 5;
 
-               ads->ds_ctl0 = ds_ctl0;
+       if (AR_SREV_9280_20_OR_LATER(ah)
+           || (addr != AR_GPIO_OUTPUT_MUX1)) {
+               REG_RMW(ah, addr, (type << gpio_shift),
+                       (0x1f << gpio_shift));
        } else {
-               ads->ds_ctl0 =
-                       (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
+               tmp = REG_READ(ah, addr);
+               tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
+               tmp &= ~(0x1f << gpio_shift);
+               tmp |= (type << gpio_shift);
+               REG_WRITE(ah, addr, tmp);
        }
-
-       ads->ds_ctl2 = set11nTries(series, 0)
-               | set11nTries(series, 1)
-               | set11nTries(series, 2)
-               | set11nTries(series, 3)
-               | (durUpdateEn ? AR_DurUpdateEna : 0)
-               | SM(0, AR_BurstDur);
-
-       ads->ds_ctl3 = set11nRate(series, 0)
-               | set11nRate(series, 1)
-               | set11nRate(series, 2)
-               | set11nRate(series, 3);
-
-       ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
-               | set11nPktDurRTSCTS(series, 1);
-
-       ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
-               | set11nPktDurRTSCTS(series, 3);
-
-       ads->ds_ctl7 = set11nRateFlags(series, 0)
-               | set11nRateFlags(series, 1)
-               | set11nRateFlags(series, 2)
-               | set11nRateFlags(series, 3)
-               | SM(rtsctsRate, AR_RTSCTSRate);
-       last_ads->ds_ctl2 = ads->ds_ctl2;
-       last_ads->ds_ctl3 = ads->ds_ctl3;
 }
 
-void
-ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
-                          u32 aggrLen)
+void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio)
 {
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
-
-       ads->ds_ctl6 &= ~AR_AggrLen;
-       ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
-}
+       u32 gpio_shift;
 
-void
-ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
-                           u32 numDelims)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-       unsigned int ctl6;
+       ASSERT(gpio < ah->ah_caps.num_gpio_pins);
 
-       ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
+       gpio_shift = gpio << 1;
 
-       ctl6 = ads->ds_ctl6;
-       ctl6 &= ~AR_PadDelim;
-       ctl6 |= SM(numDelims, AR_PadDelim);
-       ads->ds_ctl6 = ctl6;
+       REG_RMW(ah,
+               AR_GPIO_OE_OUT,
+               (AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
+               (AR_GPIO_OE_OUT_DRV << gpio_shift));
 }
 
-void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
+u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
 {
-       struct ar5416_desc *ads = AR5416DESC(ds);
+       if (gpio >= ah->ah_caps.num_gpio_pins)
+               return 0xffffffff;
 
-       ads->ds_ctl1 |= AR_IsAggr;
-       ads->ds_ctl1 &= ~AR_MoreAggr;
-       ads->ds_ctl6 &= ~AR_PadDelim;
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               return (MS
+                       (REG_READ(ah, AR_GPIO_IN_OUT),
+                        AR928X_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0;
+       } else {
+               return (MS(REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL) &
+                       AR_GPIO_BIT(gpio)) != 0;
+       }
 }
 
-void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
+void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
+                        u32 ah_signal_type)
 {
-       struct ar5416_desc *ads = AR5416DESC(ds);
+       u32 gpio_shift;
 
-       ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
-}
+       ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
 
-void
-ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
-                             u32 burstDuration)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
+       gpio_shift = 2 * gpio;
 
-       ads->ds_ctl2 &= ~AR_BurstDur;
-       ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
+       REG_RMW(ah,
+               AR_GPIO_OE_OUT,
+               (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
+               (AR_GPIO_OE_OUT_DRV << gpio_shift));
 }
 
-void
-ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
-                               u32 vmf)
+void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val)
 {
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       if (vmf)
-               ads->ds_ctl0 |= AR_VirtMoreFrag;
-       else
-               ads->ds_ctl0 &= ~AR_VirtMoreFrag;
+       REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
+               AR_GPIO_BIT(gpio));
 }
 
-void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
+#ifdef CONFIG_RFKILL
+void ath9k_enable_rfkill(struct ath_hal *ah)
 {
-       REG_WRITE(ah, AR_RXDP, rxdp);
-}
+       REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+                   AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
 
-void ath9k_hw_rxena(struct ath_hal *ah)
-{
-       REG_WRITE(ah, AR_CR, AR_CR_RXE);
+       REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
+                   AR_GPIO_INPUT_MUX2_RFSILENT);
+
+       ath9k_hw_cfg_gpio_input(ah, ah->ah_rfkill_gpio);
+       REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
 }
+#endif
 
-bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
+int ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
 {
-       if (set) {
-
-               REG_SET_BIT(ah, AR_DIAG_SW,
-                           (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
-
-               if (!ath9k_hw_wait
-                   (ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
-                       u32 reg;
-
-                       REG_CLR_BIT(ah, AR_DIAG_SW,
-                                   (AR_DIAG_RX_DIS |
-                                    AR_DIAG_RX_ABORT));
+       struct ath9k_channel *chan = ah->ah_curchan;
+       const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+       u16 ant_config;
+       u32 halNumAntConfig;
 
-                       reg = REG_READ(ah, AR_OBS_BUS_1);
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
-                               __func__, reg);
+       halNumAntConfig = IS_CHAN_2GHZ(chan) ?
+               pCap->num_antcfg_2ghz : pCap->num_antcfg_5ghz;
 
-                       return false;
+       if (cfg < halNumAntConfig) {
+               if (!ath9k_hw_get_eeprom_antenna_cfg(ah, chan,
+                                                    cfg, &ant_config)) {
+                       REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
+                       return 0;
                }
-       } else {
-               REG_CLR_BIT(ah, AR_DIAG_SW,
-                           (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
        }
 
-       return true;
-}
-
-void
-ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
-                       u32 filter1)
-{
-       REG_WRITE(ah, AR_MCAST_FIL0, filter0);
-       REG_WRITE(ah, AR_MCAST_FIL1, filter1);
+       return -EINVAL;
 }
 
-bool
-ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
-                    u32 size, u32 flags)
+u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
 {
-       struct ar5416_desc *ads = AR5416DESC(ds);
-       struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-
-       ads->ds_ctl1 = size & AR_BufLen;
-       if (flags & ATH9K_RXDESC_INTREQ)
-               ads->ds_ctl1 |= AR_RxIntrReq;
-
-       ads->ds_rxstatus8 &= ~AR_RxDone;
-       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
-               memset(&(ads->u), 0, sizeof(ads->u));
-       return true;
+       return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
 }
 
-int
-ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
-                   u32 pa, struct ath_desc *nds, u64 tsf)
+void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
 {
-       struct ar5416_desc ads;
-       struct ar5416_desc *adsp = AR5416DESC(ds);
-
-       if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
-               return -EINPROGRESS;
-
-       ads.u.rx = adsp->u.rx;
-
-       ds->ds_rxstat.rs_status = 0;
-       ds->ds_rxstat.rs_flags = 0;
-
-       ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
-       ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
-
-       ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
-       ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
-       ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
-       ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
-       ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
-       ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
-       ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
-       if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
-               ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
-       else
-               ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
-
-       ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
-       ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
-
-       ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
-       ds->ds_rxstat.rs_moreaggr =
-               (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
-       ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
-       ds->ds_rxstat.rs_flags =
-               (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
-       ds->ds_rxstat.rs_flags |=
-               (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
-
-       if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
-               ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
-       if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
-               ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
-       if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
-               ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
-
-       if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
-
-               if (ads.ds_rxstatus8 & AR_CRCErr)
-                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
-               else if (ads.ds_rxstatus8 & AR_PHYErr) {
-                       u32 phyerr;
-
-                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
-                       phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
-                       ds->ds_rxstat.rs_phyerr = phyerr;
-               } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
-                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
-               else if (ads.ds_rxstatus8 & AR_MichaelErr)
-                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
-       }
-
-       return 0;
+       REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
 }
 
-static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
-                                     struct ath9k_rate_table *rt)
+bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
+                              enum ath9k_ant_setting settings,
+                              struct ath9k_channel *chan,
+                              u8 *tx_chainmask,
+                              u8 *rx_chainmask,
+                              u8 *antenna_cfgd)
 {
-       int i;
-
-       if (rt->rateCodeToIndex[0] != 0)
-               return;
-       for (i = 0; i < 256; i++)
-               rt->rateCodeToIndex[i] = (u8) -1;
-       for (i = 0; i < rt->rateCount; i++) {
-               u8 code = rt->info[i].rateCode;
-               u8 cix = rt->info[i].controlRate;
-
-               rt->rateCodeToIndex[code] = i;
-               rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       static u8 tx_chainmask_cfg, rx_chainmask_cfg;
 
-               rt->info[i].lpAckDuration =
-                       ath9k_hw_computetxtime(ah, rt,
-                                              WLAN_CTRL_FRAME_SIZE,
-                                              cix,
-                                              false);
-               rt->info[i].spAckDuration =
-                       ath9k_hw_computetxtime(ah, rt,
-                                              WLAN_CTRL_FRAME_SIZE,
-                                              cix,
-                                              true);
-       }
-}
+       if (AR_SREV_9280(ah)) {
+               if (!tx_chainmask_cfg) {
 
-const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
-                                                  u32 mode)
-{
-       struct ath9k_rate_table *rt;
-       switch (mode) {
-       case ATH9K_MODE_11A:
-               rt = &ar5416_11a_table;
-               break;
-       case ATH9K_MODE_11B:
-               rt = &ar5416_11b_table;
-               break;
-       case ATH9K_MODE_11G:
-               rt = &ar5416_11g_table;
-               break;
-       case ATH9K_MODE_11NG_HT20:
-       case ATH9K_MODE_11NG_HT40PLUS:
-       case ATH9K_MODE_11NG_HT40MINUS:
-               rt = &ar5416_11ng_table;
-               break;
-       case ATH9K_MODE_11NA_HT20:
-       case ATH9K_MODE_11NA_HT40PLUS:
-       case ATH9K_MODE_11NA_HT40MINUS:
-               rt = &ar5416_11na_table;
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n",
-                        __func__, mode);
-               return NULL;
-       }
-       ath9k_hw_setup_rate_table(ah, rt);
-       return rt;
-}
+                       tx_chainmask_cfg = *tx_chainmask;
+                       rx_chainmask_cfg = *rx_chainmask;
+               }
 
-static const char *ath9k_hw_devname(u16 devid)
-{
-       switch (devid) {
-       case AR5416_DEVID_PCI:
-       case AR5416_DEVID_PCIE:
-               return "Atheros 5416";
-       case AR9160_DEVID_PCI:
-               return "Atheros 9160";
-       case AR9280_DEVID_PCI:
-       case AR9280_DEVID_PCIE:
-               return "Atheros 9280";
+               switch (settings) {
+               case ATH9K_ANT_FIXED_A:
+                       *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
+                       *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
+                       *antenna_cfgd = true;
+                       break;
+               case ATH9K_ANT_FIXED_B:
+                       if (ah->ah_caps.tx_chainmask >
+                           ATH9K_ANTENNA1_CHAINMASK) {
+                               *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
+                       }
+                       *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
+                       *antenna_cfgd = true;
+                       break;
+               case ATH9K_ANT_VARIABLE:
+                       *tx_chainmask = tx_chainmask_cfg;
+                       *rx_chainmask = rx_chainmask_cfg;
+                       *antenna_cfgd = true;
+                       break;
+               default:
+                       break;
+               }
+       } else {
+               ahp->ah_diversityControl = settings;
        }
-       return NULL;
-}
 
-const char *ath9k_hw_probe(u16 vendorid, u16 devid)
-{
-       return vendorid == ATHEROS_VENDOR_ID ?
-               ath9k_hw_devname(devid) : NULL;
+       return true;
 }
 
-struct ath_hal *ath9k_hw_attach(u16 devid,
-                               struct ath_softc *sc,
-                               void __iomem *mem,
-                               int *error)
+/*********************/
+/* General Operation */
+/*********************/
+
+u32 ath9k_hw_getrxfilter(struct ath_hal *ah)
 {
-       struct ath_hal *ah = NULL;
+       u32 bits = REG_READ(ah, AR_RX_FILTER);
+       u32 phybits = REG_READ(ah, AR_PHY_ERR);
 
-       switch (devid) {
-       case AR5416_DEVID_PCI:
-       case AR5416_DEVID_PCIE:
-       case AR9160_DEVID_PCI:
-       case AR9280_DEVID_PCI:
-       case AR9280_DEVID_PCIE:
-               ah = ath9k_hw_do_attach(devid, sc, mem, error);
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                        "devid=0x%x not supported.\n", devid);
-               ah = NULL;
-               *error = -ENXIO;
-               break;
-       }
+       if (phybits & AR_PHY_ERR_RADAR)
+               bits |= ATH9K_RX_FILTER_PHYRADAR;
+       if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING))
+               bits |= ATH9K_RX_FILTER_PHYERR;
 
-       return ah;
+       return bits;
 }
 
-u16
-ath9k_hw_computetxtime(struct ath_hal *ah,
-                      const struct ath9k_rate_table *rates,
-                      u32 frameLen, u16 rateix,
-                      bool shortPreamble)
+void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits)
 {
-       u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
-       u32 kbps;
-
-       kbps = rates->info[rateix].rateKbps;
-
-       if (kbps == 0)
-               return 0;
-       switch (rates->info[rateix].phy) {
+       u32 phybits;
 
-       case PHY_CCK:
-               phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
-               if (shortPreamble && rates->info[rateix].shortPreamble)
-                       phyTime >>= 1;
-               numBits = frameLen << 3;
-               txTime = CCK_SIFS_TIME + phyTime
-                       + ((numBits * 1000) / kbps);
-               break;
-       case PHY_OFDM:
-               if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
-                       bitsPerSymbol =
-                               (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
+       REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff) | AR_RX_COMPR_BAR);
+       phybits = 0;
+       if (bits & ATH9K_RX_FILTER_PHYRADAR)
+               phybits |= AR_PHY_ERR_RADAR;
+       if (bits & ATH9K_RX_FILTER_PHYERR)
+               phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
+       REG_WRITE(ah, AR_PHY_ERR, phybits);
 
-                       numBits = OFDM_PLCP_BITS + (frameLen << 3);
-                       numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
-                       txTime = OFDM_SIFS_TIME_QUARTER
-                               + OFDM_PREAMBLE_TIME_QUARTER
-                               + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
-               } else if (ah->ah_curchan &&
-                          IS_CHAN_HALF_RATE(ah->ah_curchan)) {
-                       bitsPerSymbol =
-                               (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
+       if (phybits)
+               REG_WRITE(ah, AR_RXCFG,
+                         REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
+       else
+               REG_WRITE(ah, AR_RXCFG,
+                         REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
+}
 
-                       numBits = OFDM_PLCP_BITS + (frameLen << 3);
-                       numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
-                       txTime = OFDM_SIFS_TIME_HALF +
-                               OFDM_PREAMBLE_TIME_HALF
-                               + (numSymbols * OFDM_SYMBOL_TIME_HALF);
-               } else {
-                       bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
+bool ath9k_hw_phy_disable(struct ath_hal *ah)
+{
+       return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
+}
 
-                       numBits = OFDM_PLCP_BITS + (frameLen << 3);
-                       numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
-                       txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
-                               + (numSymbols * OFDM_SYMBOL_TIME);
-               }
-               break;
+bool ath9k_hw_disable(struct ath_hal *ah)
+{
+       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+               return false;
 
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
-                        "%s: unknown phy %u (rate ix %u)\n", __func__,
-                        rates->info[rateix].phy, rateix);
-               txTime = 0;
-               break;
-       }
-       return txTime;
+       return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
 }
 
-u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
+bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
 {
-       if (flags & CHANNEL_2GHZ) {
-               if (freq == 2484)
-                       return 14;
-               if (freq < 2484)
-                       return (freq - 2407) / 5;
-               else
-                       return 15 + ((freq - 2512) / 20);
-       } else if (flags & CHANNEL_5GHZ) {
-               if (ath9k_regd_is_public_safety_sku(ah) &&
-                   IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
-                       return ((freq * 10) +
-                               (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
-               } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
-                       return (freq - 4000) / 5;
-               } else {
-                       return (freq - 5000) / 5;
-               }
-       } else {
-               if (freq == 2484)
-                       return 14;
-               if (freq < 2484)
-                       return (freq - 2407) / 5;
-               if (freq < 5000) {
-                       if (ath9k_regd_is_public_safety_sku(ah)
-                           && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
-                               return ((freq * 10) +
-                                       (((freq % 5) ==
-                                         2) ? 5 : 0) - 49400) / 5;
-                       } else if (freq > 4900) {
-                               return (freq - 4000) / 5;
-                       } else {
-                               return 15 + ((freq - 2512) / 20);
-                       }
-               }
-               return (freq - 5000) / 5;
-       }
-}
+       struct ath9k_channel *chan = ah->ah_curchan;
 
-/* We can tune this as we go by monitoring really low values */
-#define ATH9K_NF_TOO_LOW       -60
+       ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
 
-/* AR5416 may return very high value (like -31 dBm), in those cases the nf
- * is incorrect and we should use the static NF value. Later we can try to
- * find out why they are reporting these values */
-static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf)
-{
-       if (nf > ATH9K_NF_TOO_LOW) {
-               DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
-                        "%s: noise floor value detected (%d) is "
-                       "lower than what we think is a "
-                       "reasonable value (%d)\n",
-                        __func__, nf, ATH9K_NF_TOO_LOW);
+       if (ath9k_hw_set_txpower(ah, chan,
+                                ath9k_regd_get_ctl(ah, chan),
+                                ath9k_regd_get_antenna_allowed(ah, chan),
+                                chan->maxRegTxPower * 2,
+                                min((u32) MAX_RATE_POWER,
+                                    (u32) ah->ah_powerLimit)) != 0)
                return false;
-       }
+
        return true;
 }
 
-s16
-ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
+void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
 {
-       struct ath9k_channel *ichan;
-       s16 nf;
-
-       ichan = ath9k_regd_check_channel(ah, chan);
-       if (ichan == NULL) {
-               DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
-                        "%s: invalid channel %u/0x%x; no mapping\n",
-                        __func__, chan->channel, chan->channelFlags);
-               return ATH_DEFAULT_NOISE_FLOOR;
-       }
-       if (ichan->rawNoiseFloor == 0) {
-               enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
-               nf = NOISE_FLOOR[mode];
-       } else
-               nf = ichan->rawNoiseFloor;
-
-       if (!ath9k_hw_nf_in_range(ah, nf))
-               nf = ATH_DEFAULT_NOISE_FLOOR;
+       struct ath_hal_5416 *ahp = AH5416(ah);
 
-       return nf;
+       memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
 }
 
-bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
+bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
 {
        struct ath_hal_5416 *ahp = AH5416(ah);
 
-       if (setting)
-               ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
-       else
-               ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
+       memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
+
        return true;
 }
 
-bool ath9k_hw_phycounters(struct ath_hal *ah)
+void ath9k_hw_setopmode(struct ath_hal *ah)
 {
-       struct ath_hal_5416 *ahp = AH5416(ah);
-
-       return ahp->ah_hasHwPhyCounters ? true : false;
+       ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
 }
 
-u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
+void ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0, u32 filter1)
 {
-       return REG_READ(ah, AR_QTXDP(q));
+       REG_WRITE(ah, AR_MCAST_FIL0, filter0);
+       REG_WRITE(ah, AR_MCAST_FIL1, filter1);
 }
 
-bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
-                      u32 txdp)
+void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
 {
-       REG_WRITE(ah, AR_QTXDP(q), txdp);
+       struct ath_hal_5416 *ahp = AH5416(ah);
 
-       return true;
+       memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
 }
 
-bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
+bool ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
 {
-       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
+       struct ath_hal_5416 *ahp = AH5416(ah);
+
+       memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
 
-       REG_WRITE(ah, AR_Q_TXE, 1 << q);
+       REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
+       REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
 
        return true;
 }
 
-u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
+void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, u16 assocId)
 {
-       u32 npend;
+       struct ath_hal_5416 *ahp = AH5416(ah);
 
-       npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
-       if (npend == 0) {
+       memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
+       ahp->ah_assocId = assocId;
 
-               if (REG_READ(ah, AR_Q_TXE) & (1 << q))
-                       npend = 1;
-       }
-       return npend;
+       REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
+       REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
+                 ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
 }
 
-bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
+u64 ath9k_hw_gettsf64(struct ath_hal *ah)
 {
-       u32 wait;
-
-       REG_WRITE(ah, AR_Q_TXD, 1 << q);
-
-       for (wait = 1000; wait != 0; wait--) {
-               if (ath9k_hw_numtxpending(ah, q) == 0)
-                       break;
-               udelay(100);
-       }
+       u64 tsf;
 
-       if (ath9k_hw_numtxpending(ah, q)) {
-               u32 tsfLow, j;
+       tsf = REG_READ(ah, AR_TSF_U32);
+       tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
 
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-                        "%s: Num of pending TX Frames %d on Q %d\n",
-                        __func__, ath9k_hw_numtxpending(ah, q), q);
+       return tsf;
+}
 
-               for (j = 0; j < 2; j++) {
-                       tsfLow = REG_READ(ah, AR_TSF_L32);
-                       REG_WRITE(ah, AR_QUIET2,
-                                 SM(10, AR_QUIET2_QUIET_DUR));
-                       REG_WRITE(ah, AR_QUIET_PERIOD, 100);
-                       REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
-                       REG_SET_BIT(ah, AR_TIMER_MODE,
-                                      AR_QUIET_TIMER_EN);
+void ath9k_hw_reset_tsf(struct ath_hal *ah)
+{
+       int count;
 
-                       if ((REG_READ(ah, AR_TSF_L32) >> 10) ==
-                           (tsfLow >> 10)) {
-                               break;
-                       }
-                       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-                               "%s: TSF have moved while trying to set "
-                               "quiet time TSF: 0x%08x\n",
-                               __func__, tsfLow);
+       count = 0;
+       while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
+               count++;
+               if (count > 10) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+                               "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
+                               __func__);
+                       break;
                }
+               udelay(10);
+       }
+       REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
+}
 
-               REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
 
-               udelay(200);
-               REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
+       if (setting)
+               ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
+       else
+               ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
 
-               wait = 1000;
+       return true;
+}
 
-               while (ath9k_hw_numtxpending(ah, q)) {
-                       if ((--wait) == 0) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
-                                       "%s: Failed to stop Tx DMA in 100 "
-                                       "msec after killing last frame\n",
-                                       __func__);
-                               break;
-                       }
-                       udelay(100);
-               }
+bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
 
-               REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+       if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad slot time %u\n",
+                        __func__, us);
+               ahp->ah_slottime = (u32) -1;
+               return false;
+       } else {
+               REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
+               ahp->ah_slottime = us;
+               return true;
        }
+}
+
+void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode)
+{
+       u32 macmode;
+
+       if (mode == ATH9K_HT_MACMODE_2040 &&
+           !ah->ah_config.cwm_ignore_extcca)
+               macmode = AR_2040_JOINED_RX_CLEAR;
+       else
+               macmode = 0;
 
-       REG_WRITE(ah, AR_Q_TXD, 0);
-       return wait != 0;
+       REG_WRITE(ah, AR_2040_MODE, macmode);
 }
index 2113818ee9348dffdd4cc2334c85abac662d4683..6a29f2d43c21ed4540cb99b2e615dcd7bebbd4b7 100644 (file)
@@ -923,7 +923,7 @@ struct ath_hal_5416 {
 #define OFDM_PLCP_BITS_QUARTER      22
 #define OFDM_SYMBOL_TIME_QUARTER    16
 
-u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
+u32 ath9k_hw_get_eeprom(struct ath_hal *ah,
                        enum eeprom_param param);
 
 #endif
diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath9k/mac.c
new file mode 100644 (file)
index 0000000..c344a81
--- /dev/null
@@ -0,0 +1,1031 @@
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "core.h"
+#include "hw.h"
+#include "reg.h"
+#include "phy.h"
+
+static void ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
+                                       struct ath9k_tx_queue_info *qi)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+
+       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
+               "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
+               __func__, ahp->ah_txOkInterruptMask,
+               ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
+               ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask);
+
+       REG_WRITE(ah, AR_IMR_S0,
+                 SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
+                 | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
+       REG_WRITE(ah, AR_IMR_S1,
+                 SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
+                 | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
+       REG_RMW_FIELD(ah, AR_IMR_S2,
+                     AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
+}
+
+void ath9k_hw_dmaRegDump(struct ath_hal *ah)
+{
+       u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
+       int qcuOffset = 0, dcuOffset = 0;
+       u32 *qcuBase = &val[0], *dcuBase = &val[4];
+       int i;
+
+       REG_WRITE(ah, AR_MACMISC,
+                 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
+                  (AR_MACMISC_MISC_OBS_BUS_1 <<
+                   AR_MACMISC_MISC_OBS_BUS_MSB_S)));
+
+       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "Raw DMA Debug values:\n");
+
+       for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
+               if (i % 4 == 0)
+                       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
+
+               val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
+               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "%d: %08x ", i, val[i]);
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n\n");
+       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+               "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
+
+       for (i = 0; i < ATH9K_NUM_QUEUES;
+            i++, qcuOffset += 4, dcuOffset += 5) {
+               if (i == 8) {
+                       qcuOffset = 0;
+                       qcuBase++;
+               }
+
+               if (i == 6) {
+                       dcuOffset = 0;
+                       dcuBase++;
+               }
+
+               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+                       "%2d          %2x      %1x     %2x           %2x\n",
+                       i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
+                       (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
+                       val[2] & (0x7 << (i * 3)) >> (i * 3),
+                       (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
+       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+               "qcu_stitch state:   %2x    qcu_fetch state:        %2x\n",
+               (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
+       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+               "qcu_complete state: %2x    dcu_complete state:     %2x\n",
+               (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
+       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+               "dcu_arb state:      %2x    dcu_fp state:           %2x\n",
+               (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
+       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+               "chan_idle_dur:     %3d    chan_idle_dur_valid:     %1d\n",
+               (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
+       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+               "txfifo_valid_0:      %1d    txfifo_valid_1:          %1d\n",
+               (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
+       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+               "txfifo_dcu_num_0:   %2d    txfifo_dcu_num_1:       %2d\n",
+               (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
+
+       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "pcu observe 0x%x \n",
+               REG_READ(ah, AR_OBS_BUS_1));
+       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+               "AR_CR 0x%x \n", REG_READ(ah, AR_CR));
+}
+
+u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
+{
+       return REG_READ(ah, AR_QTXDP(q));
+}
+
+bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp)
+{
+       REG_WRITE(ah, AR_QTXDP(q), txdp);
+
+       return true;
+}
+
+bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
+{
+       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
+
+       REG_WRITE(ah, AR_Q_TXE, 1 << q);
+
+       return true;
+}
+
+u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
+{
+       u32 npend;
+
+       npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
+       if (npend == 0) {
+
+               if (REG_READ(ah, AR_Q_TXE) & (1 << q))
+                       npend = 1;
+       }
+
+       return npend;
+}
+
+bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       u32 txcfg, curLevel, newLevel;
+       enum ath9k_int omask;
+
+       if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
+               return false;
+
+       omask = ath9k_hw_set_interrupts(ah, ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
+
+       txcfg = REG_READ(ah, AR_TXCFG);
+       curLevel = MS(txcfg, AR_FTRIG);
+       newLevel = curLevel;
+       if (bIncTrigLevel) {
+               if (curLevel < MAX_TX_FIFO_THRESHOLD)
+                       newLevel++;
+       } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
+               newLevel--;
+       if (newLevel != curLevel)
+               REG_WRITE(ah, AR_TXCFG,
+                         (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
+
+       ath9k_hw_set_interrupts(ah, omask);
+
+       ah->ah_txTrigLevel = newLevel;
+
+       return newLevel != curLevel;
+}
+
+bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
+{
+       u32 tsfLow, j, wait;
+
+       REG_WRITE(ah, AR_Q_TXD, 1 << q);
+
+       for (wait = 1000; wait != 0; wait--) {
+               if (ath9k_hw_numtxpending(ah, q) == 0)
+                       break;
+               udelay(100);
+       }
+
+       if (ath9k_hw_numtxpending(ah, q)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+                       "%s: Num of pending TX Frames %d on Q %d\n",
+                       __func__, ath9k_hw_numtxpending(ah, q), q);
+
+               for (j = 0; j < 2; j++) {
+                       tsfLow = REG_READ(ah, AR_TSF_L32);
+                       REG_WRITE(ah, AR_QUIET2,
+                                 SM(10, AR_QUIET2_QUIET_DUR));
+                       REG_WRITE(ah, AR_QUIET_PERIOD, 100);
+                       REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
+                       REG_SET_BIT(ah, AR_TIMER_MODE,
+                                      AR_QUIET_TIMER_EN);
+
+                       if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
+                               break;
+
+                       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+                               "%s: TSF have moved while trying to set "
+                               "quiet time TSF: 0x%08x\n",
+                               __func__, tsfLow);
+               }
+
+               REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+
+               udelay(200);
+               REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
+
+               wait = 1000;
+
+               while (ath9k_hw_numtxpending(ah, q)) {
+                       if ((--wait) == 0) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
+                                       "%s: Failed to stop Tx DMA in 100 "
+                                       "msec after killing last frame\n",
+                                       __func__);
+                               break;
+                       }
+                       udelay(100);
+               }
+
+               REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+       }
+
+       REG_WRITE(ah, AR_Q_TXD, 0);
+
+       return wait != 0;
+}
+
+bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
+                        u32 segLen, bool firstSeg,
+                        bool lastSeg, const struct ath_desc *ds0)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       if (firstSeg) {
+               ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
+       } else if (lastSeg) {
+               ads->ds_ctl0 = 0;
+               ads->ds_ctl1 = segLen;
+               ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
+               ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
+       } else {
+               ads->ds_ctl0 = 0;
+               ads->ds_ctl1 = segLen | AR_TxMore;
+               ads->ds_ctl2 = 0;
+               ads->ds_ctl3 = 0;
+       }
+       ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
+       ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
+       ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
+       ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
+       ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
+
+       return true;
+}
+
+void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
+       ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
+       ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
+       ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
+       ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
+}
+
+int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       if ((ads->ds_txstatus9 & AR_TxDone) == 0)
+               return -EINPROGRESS;
+
+       ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
+       ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
+       ds->ds_txstat.ts_status = 0;
+       ds->ds_txstat.ts_flags = 0;
+
+       if (ads->ds_txstatus1 & AR_ExcessiveRetries)
+               ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
+       if (ads->ds_txstatus1 & AR_Filtered)
+               ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
+       if (ads->ds_txstatus1 & AR_FIFOUnderrun)
+               ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
+       if (ads->ds_txstatus9 & AR_TxOpExceeded)
+               ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
+       if (ads->ds_txstatus1 & AR_TxTimerExpired)
+               ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
+
+       if (ads->ds_txstatus1 & AR_DescCfgErr)
+               ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
+       if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
+               ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
+               ath9k_hw_updatetxtriglevel(ah, true);
+       }
+       if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
+               ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
+               ath9k_hw_updatetxtriglevel(ah, true);
+       }
+       if (ads->ds_txstatus0 & AR_TxBaStatus) {
+               ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
+               ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
+               ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
+       }
+
+       ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
+       switch (ds->ds_txstat.ts_rateindex) {
+       case 0:
+               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
+               break;
+       case 1:
+               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
+               break;
+       case 2:
+               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
+               break;
+       case 3:
+               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
+               break;
+       }
+
+       ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
+       ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
+       ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
+       ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
+       ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
+       ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
+       ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
+       ds->ds_txstat.evm0 = ads->AR_TxEVM0;
+       ds->ds_txstat.evm1 = ads->AR_TxEVM1;
+       ds->ds_txstat.evm2 = ads->AR_TxEVM2;
+       ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
+       ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
+       ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
+       ds->ds_txstat.ts_antenna = 1;
+
+       return 0;
+}
+
+void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
+                           u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
+                           u32 keyIx, enum ath9k_key_type keyType, u32 flags)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+       struct ath_hal_5416 *ahp = AH5416(ah);
+
+       txPower += ahp->ah_txPowerIndexOffset;
+       if (txPower > 63)
+               txPower = 63;
+
+       ads->ds_ctl0 = (pktLen & AR_FrameLen)
+               | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
+               | SM(txPower, AR_XmitPower)
+               | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
+               | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
+               | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
+               | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
+
+       ads->ds_ctl1 =
+               (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
+               | SM(type, AR_FrameType)
+               | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
+               | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
+               | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
+
+       ads->ds_ctl6 = SM(keyType, AR_EncrType);
+
+       if (AR_SREV_9285(ah)) {
+               ads->ds_ctl8 = 0;
+               ads->ds_ctl9 = 0;
+               ads->ds_ctl10 = 0;
+               ads->ds_ctl11 = 0;
+       }
+}
+
+void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
+                                 struct ath_desc *lastds,
+                                 u32 durUpdateEn, u32 rtsctsRate,
+                                 u32 rtsctsDuration,
+                                 struct ath9k_11n_rate_series series[],
+                                 u32 nseries, u32 flags)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+       struct ar5416_desc *last_ads = AR5416DESC(lastds);
+       u32 ds_ctl0;
+
+       (void) nseries;
+       (void) rtsctsDuration;
+
+       if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
+               ds_ctl0 = ads->ds_ctl0;
+
+               if (flags & ATH9K_TXDESC_RTSENA) {
+                       ds_ctl0 &= ~AR_CTSEnable;
+                       ds_ctl0 |= AR_RTSEnable;
+               } else {
+                       ds_ctl0 &= ~AR_RTSEnable;
+                       ds_ctl0 |= AR_CTSEnable;
+               }
+
+               ads->ds_ctl0 = ds_ctl0;
+       } else {
+               ads->ds_ctl0 =
+                       (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
+       }
+
+       ads->ds_ctl2 = set11nTries(series, 0)
+               | set11nTries(series, 1)
+               | set11nTries(series, 2)
+               | set11nTries(series, 3)
+               | (durUpdateEn ? AR_DurUpdateEna : 0)
+               | SM(0, AR_BurstDur);
+
+       ads->ds_ctl3 = set11nRate(series, 0)
+               | set11nRate(series, 1)
+               | set11nRate(series, 2)
+               | set11nRate(series, 3);
+
+       ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
+               | set11nPktDurRTSCTS(series, 1);
+
+       ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
+               | set11nPktDurRTSCTS(series, 3);
+
+       ads->ds_ctl7 = set11nRateFlags(series, 0)
+               | set11nRateFlags(series, 1)
+               | set11nRateFlags(series, 2)
+               | set11nRateFlags(series, 3)
+               | SM(rtsctsRate, AR_RTSCTSRate);
+       last_ads->ds_ctl2 = ads->ds_ctl2;
+       last_ads->ds_ctl3 = ads->ds_ctl3;
+}
+
+void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
+                               u32 aggrLen)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
+       ads->ds_ctl6 &= ~AR_AggrLen;
+       ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
+}
+
+void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
+                                u32 numDelims)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+       unsigned int ctl6;
+
+       ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
+
+       ctl6 = ads->ds_ctl6;
+       ctl6 &= ~AR_PadDelim;
+       ctl6 |= SM(numDelims, AR_PadDelim);
+       ads->ds_ctl6 = ctl6;
+}
+
+void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_ctl1 |= AR_IsAggr;
+       ads->ds_ctl1 &= ~AR_MoreAggr;
+       ads->ds_ctl6 &= ~AR_PadDelim;
+}
+
+void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
+}
+
+void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
+                                  u32 burstDuration)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_ctl2 &= ~AR_BurstDur;
+       ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
+}
+
+void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
+                                    u32 vmf)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       if (vmf)
+               ads->ds_ctl0 |= AR_VirtMoreFrag;
+       else
+               ads->ds_ctl0 &= ~AR_VirtMoreFrag;
+}
+
+void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+
+       *txqs &= ahp->ah_intrTxqs;
+       ahp->ah_intrTxqs &= ~(*txqs);
+}
+
+bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
+                           const struct ath9k_tx_queue_info *qinfo)
+{
+       u32 cw;
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+       struct ath9k_tx_queue_info *qi;
+
+       if (q >= pCap->total_queues) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
+                        __func__, q);
+               return false;
+       }
+
+       qi = &ahp->ah_txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
+                        __func__);
+               return false;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
+
+       qi->tqi_ver = qinfo->tqi_ver;
+       qi->tqi_subtype = qinfo->tqi_subtype;
+       qi->tqi_qflags = qinfo->tqi_qflags;
+       qi->tqi_priority = qinfo->tqi_priority;
+       if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
+               qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
+       else
+               qi->tqi_aifs = INIT_AIFS;
+       if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
+               cw = min(qinfo->tqi_cwmin, 1024U);
+               qi->tqi_cwmin = 1;
+               while (qi->tqi_cwmin < cw)
+                       qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
+       } else
+               qi->tqi_cwmin = qinfo->tqi_cwmin;
+       if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
+               cw = min(qinfo->tqi_cwmax, 1024U);
+               qi->tqi_cwmax = 1;
+               while (qi->tqi_cwmax < cw)
+                       qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
+       } else
+               qi->tqi_cwmax = INIT_CWMAX;
+
+       if (qinfo->tqi_shretry != 0)
+               qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
+       else
+               qi->tqi_shretry = INIT_SH_RETRY;
+       if (qinfo->tqi_lgretry != 0)
+               qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
+       else
+               qi->tqi_lgretry = INIT_LG_RETRY;
+       qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
+       qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
+       qi->tqi_burstTime = qinfo->tqi_burstTime;
+       qi->tqi_readyTime = qinfo->tqi_readyTime;
+
+       switch (qinfo->tqi_subtype) {
+       case ATH9K_WME_UPSD:
+               if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
+                       qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
+               break;
+       default:
+               break;
+       }
+
+       return true;
+}
+
+bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
+                           struct ath9k_tx_queue_info *qinfo)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+       struct ath9k_tx_queue_info *qi;
+
+       if (q >= pCap->total_queues) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
+                        __func__, q);
+               return false;
+       }
+
+       qi = &ahp->ah_txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
+                        __func__);
+               return false;
+       }
+
+       qinfo->tqi_qflags = qi->tqi_qflags;
+       qinfo->tqi_ver = qi->tqi_ver;
+       qinfo->tqi_subtype = qi->tqi_subtype;
+       qinfo->tqi_qflags = qi->tqi_qflags;
+       qinfo->tqi_priority = qi->tqi_priority;
+       qinfo->tqi_aifs = qi->tqi_aifs;
+       qinfo->tqi_cwmin = qi->tqi_cwmin;
+       qinfo->tqi_cwmax = qi->tqi_cwmax;
+       qinfo->tqi_shretry = qi->tqi_shretry;
+       qinfo->tqi_lgretry = qi->tqi_lgretry;
+       qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
+       qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
+       qinfo->tqi_burstTime = qi->tqi_burstTime;
+       qinfo->tqi_readyTime = qi->tqi_readyTime;
+
+       return true;
+}
+
+int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
+                         const struct ath9k_tx_queue_info *qinfo)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ath9k_tx_queue_info *qi;
+       struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+       int q;
+
+       switch (type) {
+       case ATH9K_TX_QUEUE_BEACON:
+               q = pCap->total_queues - 1;
+               break;
+       case ATH9K_TX_QUEUE_CAB:
+               q = pCap->total_queues - 2;
+               break;
+       case ATH9K_TX_QUEUE_PSPOLL:
+               q = 1;
+               break;
+       case ATH9K_TX_QUEUE_UAPSD:
+               q = pCap->total_queues - 3;
+               break;
+       case ATH9K_TX_QUEUE_DATA:
+               for (q = 0; q < pCap->total_queues; q++)
+                       if (ahp->ah_txq[q].tqi_type ==
+                           ATH9K_TX_QUEUE_INACTIVE)
+                               break;
+               if (q == pCap->total_queues) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+                               "%s: no available tx queue\n", __func__);
+                       return -1;
+               }
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
+                       __func__, type);
+               return -1;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
+
+       qi = &ahp->ah_txq[q];
+       if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+                       "%s: tx queue %u already active\n", __func__, q);
+               return -1;
+       }
+       memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
+       qi->tqi_type = type;
+       if (qinfo == NULL) {
+               qi->tqi_qflags =
+                       TXQ_FLAG_TXOKINT_ENABLE
+                       | TXQ_FLAG_TXERRINT_ENABLE
+                       | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
+               qi->tqi_aifs = INIT_AIFS;
+               qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
+               qi->tqi_cwmax = INIT_CWMAX;
+               qi->tqi_shretry = INIT_SH_RETRY;
+               qi->tqi_lgretry = INIT_LG_RETRY;
+               qi->tqi_physCompBuf = 0;
+       } else {
+               qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
+               (void) ath9k_hw_set_txq_props(ah, q, qinfo);
+       }
+
+       return q;
+}
+
+bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+       struct ath9k_tx_queue_info *qi;
+
+       if (q >= pCap->total_queues) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
+                        __func__, q);
+               return false;
+       }
+       qi = &ahp->ah_txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
+                        __func__, q);
+               return false;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
+               __func__, q);
+
+       qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
+       ahp->ah_txOkInterruptMask &= ~(1 << q);
+       ahp->ah_txErrInterruptMask &= ~(1 << q);
+       ahp->ah_txDescInterruptMask &= ~(1 << q);
+       ahp->ah_txEolInterruptMask &= ~(1 << q);
+       ahp->ah_txUrnInterruptMask &= ~(1 << q);
+       ath9k_hw_set_txq_interrupts(ah, qi);
+
+       return true;
+}
+
+bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
+{
+       struct ath_hal_5416 *ahp = AH5416(ah);
+       struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+       struct ath9k_channel *chan = ah->ah_curchan;
+       struct ath9k_tx_queue_info *qi;
+       u32 cwMin, chanCwMin, value;
+
+       if (q >= pCap->total_queues) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
+                        __func__, q);
+               return false;
+       }
+
+       qi = &ahp->ah_txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
+                        __func__, q);
+               return true;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
+
+       if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
+               if (chan && IS_CHAN_B(chan))
+                       chanCwMin = INIT_CWMIN_11B;
+               else
+                       chanCwMin = INIT_CWMIN;
+
+               for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
+       } else
+               cwMin = qi->tqi_cwmin;
+
+       REG_WRITE(ah, AR_DLCL_IFS(q),
+                 SM(cwMin, AR_D_LCL_IFS_CWMIN) |
+                 SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) |
+                 SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
+
+       REG_WRITE(ah, AR_DRETRY_LIMIT(q),
+                 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) |
+                 SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) |
+                 SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
+
+       REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
+       REG_WRITE(ah, AR_DMISC(q),
+                 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
+
+       if (qi->tqi_cbrPeriod) {
+               REG_WRITE(ah, AR_QCBRCFG(q),
+                         SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
+                         SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
+               REG_WRITE(ah, AR_QMISC(q),
+                         REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR |
+                         (qi->tqi_cbrOverflowLimit ?
+                          AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
+       }
+       if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
+               REG_WRITE(ah, AR_QRDYTIMECFG(q),
+                         SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
+                         AR_Q_RDYTIMECFG_EN);
+       }
+
+       REG_WRITE(ah, AR_DCHNTIME(q),
+                 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
+                 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
+
+       if (qi->tqi_burstTime
+           && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
+               REG_WRITE(ah, AR_QMISC(q),
+                         REG_READ(ah, AR_QMISC(q)) |
+                         AR_Q_MISC_RDYTIME_EXP_POLICY);
+
+       }
+
+       if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
+               REG_WRITE(ah, AR_DMISC(q),
+                         REG_READ(ah, AR_DMISC(q)) |
+                         AR_D_MISC_POST_FR_BKOFF_DIS);
+       }
+       if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
+               REG_WRITE(ah, AR_DMISC(q),
+                         REG_READ(ah, AR_DMISC(q)) |
+                         AR_D_MISC_FRAG_BKOFF_EN);
+       }
+       switch (qi->tqi_type) {
+       case ATH9K_TX_QUEUE_BEACON:
+               REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
+                         | AR_Q_MISC_FSP_DBA_GATED
+                         | AR_Q_MISC_BEACON_USE
+                         | AR_Q_MISC_CBR_INCR_DIS1);
+
+               REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
+                         | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
+                            AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
+                         | AR_D_MISC_BEACON_USE
+                         | AR_D_MISC_POST_FR_BKOFF_DIS);
+               break;
+       case ATH9K_TX_QUEUE_CAB:
+               REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
+                         | AR_Q_MISC_FSP_DBA_GATED
+                         | AR_Q_MISC_CBR_INCR_DIS1
+                         | AR_Q_MISC_CBR_INCR_DIS0);
+               value = (qi->tqi_readyTime -
+                        (ah->ah_config.sw_beacon_response_time -
+                         ah->ah_config.dma_beacon_response_time) -
+                        ah->ah_config.additional_swba_backoff) * 1024;
+               REG_WRITE(ah, AR_QRDYTIMECFG(q),
+                         value | AR_Q_RDYTIMECFG_EN);
+               REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
+                         | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
+                            AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
+               break;
+       case ATH9K_TX_QUEUE_PSPOLL:
+               REG_WRITE(ah, AR_QMISC(q),
+                         REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
+               break;
+       case ATH9K_TX_QUEUE_UAPSD:
+               REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) |
+                         AR_D_MISC_POST_FR_BKOFF_DIS);
+               break;
+       default:
+               break;
+       }
+
+       if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
+               REG_WRITE(ah, AR_DMISC(q),
+                         REG_READ(ah, AR_DMISC(q)) |
+                         SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
+                            AR_D_MISC_ARB_LOCKOUT_CNTRL) |
+                         AR_D_MISC_POST_FR_BKOFF_DIS);
+       }
+
+       if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
+               ahp->ah_txOkInterruptMask |= 1 << q;
+       else
+               ahp->ah_txOkInterruptMask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
+               ahp->ah_txErrInterruptMask |= 1 << q;
+       else
+               ahp->ah_txErrInterruptMask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
+               ahp->ah_txDescInterruptMask |= 1 << q;
+       else
+               ahp->ah_txDescInterruptMask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
+               ahp->ah_txEolInterruptMask |= 1 << q;
+       else
+               ahp->ah_txEolInterruptMask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
+               ahp->ah_txUrnInterruptMask |= 1 << q;
+       else
+               ahp->ah_txUrnInterruptMask &= ~(1 << q);
+       ath9k_hw_set_txq_interrupts(ah, qi);
+
+       return true;
+}
+
+int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
+                       u32 pa, struct ath_desc *nds, u64 tsf)
+{
+       struct ar5416_desc ads;
+       struct ar5416_desc *adsp = AR5416DESC(ds);
+       u32 phyerr;
+
+       if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
+               return -EINPROGRESS;
+
+       ads.u.rx = adsp->u.rx;
+
+       ds->ds_rxstat.rs_status = 0;
+       ds->ds_rxstat.rs_flags = 0;
+
+       ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
+       ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
+
+       ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
+       ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
+       ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
+       ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
+       ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
+       ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
+       ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
+       if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
+               ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
+       else
+               ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
+
+       ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
+       ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
+
+       ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
+       ds->ds_rxstat.rs_moreaggr =
+               (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
+       ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
+       ds->ds_rxstat.rs_flags =
+               (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
+       ds->ds_rxstat.rs_flags |=
+               (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
+
+       if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
+               ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
+       if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
+               ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
+       if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
+               ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
+
+       if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
+               if (ads.ds_rxstatus8 & AR_CRCErr)
+                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
+               else if (ads.ds_rxstatus8 & AR_PHYErr) {
+                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
+                       phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
+                       ds->ds_rxstat.rs_phyerr = phyerr;
+               } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
+                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
+               else if (ads.ds_rxstatus8 & AR_MichaelErr)
+                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
+       }
+
+       return 0;
+}
+
+bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
+                         u32 size, u32 flags)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+       struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+
+       ads->ds_ctl1 = size & AR_BufLen;
+       if (flags & ATH9K_RXDESC_INTREQ)
+               ads->ds_ctl1 |= AR_RxIntrReq;
+
+       ads->ds_rxstatus8 &= ~AR_RxDone;
+       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
+               memset(&(ads->u), 0, sizeof(ads->u));
+
+       return true;
+}
+
+bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
+{
+       u32 reg;
+
+       if (set) {
+               REG_SET_BIT(ah, AR_DIAG_SW,
+                           (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+
+               if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
+                       REG_CLR_BIT(ah, AR_DIAG_SW,
+                                   (AR_DIAG_RX_DIS |
+                                    AR_DIAG_RX_ABORT));
+
+                       reg = REG_READ(ah, AR_OBS_BUS_1);
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
+                               __func__, reg);
+
+                       return false;
+               }
+       } else {
+               REG_CLR_BIT(ah, AR_DIAG_SW,
+                           (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+       }
+
+       return true;
+}
+
+void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
+{
+       REG_WRITE(ah, AR_RXDP, rxdp);
+}
+
+void ath9k_hw_rxena(struct ath_hal *ah)
+{
+       REG_WRITE(ah, AR_CR, AR_CR_RXE);
+}
+
+void ath9k_hw_startpcureceive(struct ath_hal *ah)
+{
+       REG_CLR_BIT(ah, AR_DIAG_SW,
+                   (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+
+       ath9k_enable_mib_counters(ah);
+
+       ath9k_ani_reset(ah);
+}
+
+void ath9k_hw_stoppcurecv(struct ath_hal *ah)
+{
+       REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
+
+       ath9k_hw_disable_mib_counters(ah);
+}
+
+bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
+{
+       REG_WRITE(ah, AR_CR, AR_CR_RXD);
+
+       if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+                       "%s: dma failed to stop in 10ms\n"
+                       "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
+                       __func__,
+                       REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
+               return false;
+       } else {
+               return true;
+       }
+}
index f05f584ab7bc960f9e8ba5ea29207ec63582bd2c..f830fe1e4adcd1427c49371bad06356fdf30606a 100644 (file)
@@ -21,8 +21,6 @@
 
 #define ATH_PCI_VERSION "0.1"
 
-#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR      13
-
 static char *dev_info = "ath9k";
 
 MODULE_AUTHOR("Atheros Communications");
@@ -39,6 +37,8 @@ static struct pci_device_id ath_pci_id_table[] __devinitdata = {
        { 0 }
 };
 
+static void ath_detach(struct ath_softc *sc);
+
 static int ath_get_channel(struct ath_softc *sc,
                           struct ieee80211_channel *chan)
 {
@@ -61,24 +61,24 @@ static u32 ath_get_extchanmode(struct ath_softc *sc,
 
        switch (chan->band) {
        case IEEE80211_BAND_2GHZ:
-               if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE) &&
+               if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE) &&
                    (tx_chan_width == ATH9K_HT_MACMODE_20))
                        chanmode = CHANNEL_G_HT20;
-               if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE) &&
+               if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) &&
                    (tx_chan_width == ATH9K_HT_MACMODE_2040))
                        chanmode = CHANNEL_G_HT40PLUS;
-               if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW) &&
+               if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) &&
                    (tx_chan_width == ATH9K_HT_MACMODE_2040))
                        chanmode = CHANNEL_G_HT40MINUS;
                break;
        case IEEE80211_BAND_5GHZ:
-               if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE) &&
+               if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE) &&
                    (tx_chan_width == ATH9K_HT_MACMODE_20))
                        chanmode = CHANNEL_A_HT20;
-               if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE) &&
+               if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) &&
                    (tx_chan_width == ATH9K_HT_MACMODE_2040))
                        chanmode = CHANNEL_A_HT40PLUS;
-               if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW) &&
+               if ((ext_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW) &&
                    (tx_chan_width == ATH9K_HT_MACMODE_2040))
                        chanmode = CHANNEL_A_HT40MINUS;
                break;
@@ -164,7 +164,7 @@ static int ath_key_config(struct ath_softc *sc,
        if (!sc->sc_vaps[0])
                return -EIO;
 
-       vif = sc->sc_vaps[0]->av_if_data;
+       vif = sc->sc_vaps[0];
        opmode = vif->type;
 
        /*
@@ -215,24 +215,24 @@ static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
        ath_key_reset(sc, key->keyidx, freeslot);
 }
 
-static void setup_ht_cap(struct ieee80211_ht_info *ht_info)
+static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info)
 {
 #define        ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3       /* 2 ^ 16 */
 #define        ATH9K_HT_CAP_MPDUDENSITY_8 0x6          /* 8 usec */
 
-       ht_info->ht_supported = 1;
-       ht_info->cap = (u16)IEEE80211_HT_CAP_SUP_WIDTH
-                       |(u16)IEEE80211_HT_CAP_SM_PS
-                       |(u16)IEEE80211_HT_CAP_SGI_40
-                       |(u16)IEEE80211_HT_CAP_DSSSCCK40;
+       ht_info->ht_supported = true;
+       ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+                      IEEE80211_HT_CAP_SM_PS |
+                      IEEE80211_HT_CAP_SGI_40 |
+                      IEEE80211_HT_CAP_DSSSCCK40;
 
        ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536;
        ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8;
-       /* setup supported mcs set */
-       memset(ht_info->supp_mcs_set, 0, 16);
-       ht_info->supp_mcs_set[0] = 0xff;
-       ht_info->supp_mcs_set[1] = 0xff;
-       ht_info->supp_mcs_set[12] = IEEE80211_HT_CAP_MCS_TX_DEFINED;
+       /* set up supported mcs set */
+       memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
+       ht_info->mcs.rx_mask[0] = 0xff;
+       ht_info->mcs.rx_mask[1] = 0xff;
+       ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
 }
 
 static int ath_rate2idx(struct ath_softc *sc, int rate)
@@ -279,8 +279,15 @@ static void ath9k_rx_prepare(struct ath_softc *sc,
        rx_status->rate_idx = ath_rate2idx(sc, (status->rateKbps / 100));
        rx_status->antenna = status->antenna;
 
-       /* XXX Fix me, 64 cannot be the max rssi value, rigure it out */
-       rx_status->qual = status->rssi * 100 / 64;
+       /* at 45 you will be able to use MCS 15 reliably. A more elaborate
+        * scheme can be used here but it requires tables of SNR/throughput for
+        * each possible mode used. */
+       rx_status->qual = status->rssi * 100 / 45;
+
+       /* rssi can be more than 45 though, anything above that
+        * should be considered at 100% */
+       if (rx_status->qual > 100)
+               rx_status->qual = 100;
 
        if (status->flags & ATH_RX_MIC_ERROR)
                rx_status->flag |= RX_FLAG_MMIC_ERROR;
@@ -290,92 +297,37 @@ static void ath9k_rx_prepare(struct ath_softc *sc,
        rx_status->flag |= RX_FLAG_TSFT;
 }
 
-static u8 parse_mpdudensity(u8 mpdudensity)
-{
-       /*
-        * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
-        *   0 for no restriction
-        *   1 for 1/4 us
-        *   2 for 1/2 us
-        *   3 for 1 us
-        *   4 for 2 us
-        *   5 for 4 us
-        *   6 for 8 us
-        *   7 for 16 us
-        */
-       switch (mpdudensity) {
-       case 0:
-               return 0;
-       case 1:
-       case 2:
-       case 3:
-               /* Our lower layer calculations limit our precision to
-                  1 microsecond */
-               return 1;
-       case 4:
-               return 2;
-       case 5:
-               return 4;
-       case 6:
-               return 8;
-       case 7:
-               return 16;
-       default:
-               return 0;
-       }
-}
-
 static void ath9k_ht_conf(struct ath_softc *sc,
                          struct ieee80211_bss_conf *bss_conf)
 {
-#define IEEE80211_HT_CAP_40MHZ_INTOLERANT BIT(14)
        struct ath_ht_info *ht_info = &sc->sc_ht_info;
 
-       if (bss_conf->assoc_ht) {
-               ht_info->ext_chan_offset =
-                       bss_conf->ht_bss_conf->bss_cap &
-                               IEEE80211_HT_IE_CHA_SEC_OFFSET;
+       if (sc->hw->conf.ht.enabled) {
+               ht_info->ext_chan_offset = bss_conf->ht.secondary_channel_offset;
 
-               if (!(bss_conf->ht_conf->cap &
-                       IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
-                           (bss_conf->ht_bss_conf->bss_cap &
-                               IEEE80211_HT_IE_CHA_WIDTH))
+               if (bss_conf->ht.width_40_ok)
                        ht_info->tx_chan_width = ATH9K_HT_MACMODE_2040;
                else
                        ht_info->tx_chan_width = ATH9K_HT_MACMODE_20;
 
                ath9k_hw_set11nmac2040(sc->sc_ah, ht_info->tx_chan_width);
-               ht_info->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
-                                       bss_conf->ht_conf->ampdu_factor);
-               ht_info->mpdudensity =
-                       parse_mpdudensity(bss_conf->ht_conf->ampdu_density);
-
        }
-
-#undef IEEE80211_HT_CAP_40MHZ_INTOLERANT
 }
 
 static void ath9k_bss_assoc_info(struct ath_softc *sc,
+                                struct ieee80211_vif *vif,
                                 struct ieee80211_bss_conf *bss_conf)
 {
        struct ieee80211_hw *hw = sc->hw;
        struct ieee80211_channel *curchan = hw->conf.channel;
-       struct ath_vap *avp;
+       struct ath_vap *avp = (void *)vif->drv_priv;
        int pos;
-       DECLARE_MAC_BUF(mac);
 
        if (bss_conf->assoc) {
                DPRINTF(sc, ATH_DBG_CONFIG, "%s: Bss Info ASSOC %d\n",
                        __func__,
                        bss_conf->aid);
 
-               avp = sc->sc_vaps[0];
-               if (avp == NULL) {
-                       DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
-                               __func__);
-                       return;
-               }
-
                /* New association, store aid */
                if (avp->av_opmode == ATH9K_M_STA) {
                        sc->sc_curaid = bss_conf->aid;
@@ -394,12 +346,12 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
                sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
 
                /* Update chainmask */
-               ath_update_chainmask(sc, bss_conf->assoc_ht);
+               ath_update_chainmask(sc, hw->conf.ht.enabled);
 
                DPRINTF(sc, ATH_DBG_CONFIG,
-                       "%s: bssid %s aid 0x%x\n",
+                       "%s: bssid %pM aid 0x%x\n",
                        __func__,
-                       print_mac(mac, sc->sc_curbssid), sc->sc_curaid);
+                       sc->sc_curbssid, sc->sc_curaid);
 
                DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n",
                        __func__,
@@ -412,7 +364,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
                        return;
                }
 
-               if (hw->conf.ht_conf.ht_supported)
+               if (hw->conf.ht.enabled)
                        sc->sc_ah->ah_channels[pos].chanmode =
                                ath_get_extchanmode(sc, curchan);
                else
@@ -456,7 +408,7 @@ void ath_get_beaconconfig(struct ath_softc *sc,
 }
 
 void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
-                    struct ath_xmit_status *tx_status, struct ath_node *an)
+                    struct ath_xmit_status *tx_status)
 {
        struct ieee80211_hw *hw = sc->hw;
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -464,12 +416,13 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
        DPRINTF(sc, ATH_DBG_XMIT,
                "%s: TX complete: skb: %p\n", __func__, skb);
 
+       ieee80211_tx_info_clear_status(tx_info);
        if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
                tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
-               /* free driver's private data area of tx_info */
-               if (tx_info->driver_data[0] != NULL)
-                       kfree(tx_info->driver_data[0]);
-                       tx_info->driver_data[0] = NULL;
+               /* free driver's private data area of tx_info, XXX: HACK! */
+               if (tx_info->control.vif != NULL)
+                       kfree(tx_info->control.vif);
+                       tx_info->control.vif = NULL;
        }
 
        if (tx_status->flags & ATH_TX_BAR) {
@@ -477,21 +430,14 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
                tx_status->flags &= ~ATH_TX_BAR;
        }
 
-       if (tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY)) {
-               if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
-                       /* Frame was not ACKed, but an ACK was expected */
-                       tx_info->status.excessive_retries = 1;
-               }
-       } else {
+       if (!(tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
                /* Frame was ACKed */
                tx_info->flags |= IEEE80211_TX_STAT_ACK;
        }
 
-       tx_info->status.retry_count = tx_status->retries;
+       tx_info->status.rates[0].count = tx_status->retries + 1;
 
        ieee80211_tx_status(hw, skb);
-       if (an)
-               ath_node_put(sc, an, ATH9K_BH_STATUS_CHANGE);
 }
 
 int _ath_rx_indicate(struct ath_softc *sc,
@@ -500,12 +446,10 @@ int _ath_rx_indicate(struct ath_softc *sc,
                     u16 keyix)
 {
        struct ieee80211_hw *hw = sc->hw;
-       struct ath_node *an = NULL;
        struct ieee80211_rx_status rx_status;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
        int padsize;
-       enum ATH_RX_TYPE st;
 
        /* see if any padding is done by the hw and remove it */
        if (hdrlen & 3) {
@@ -529,34 +473,6 @@ int _ath_rx_indicate(struct ath_softc *sc,
                        rx_status.flag |= RX_FLAG_DECRYPTED;
        }
 
-       spin_lock_bh(&sc->node_lock);
-       an = ath_node_find(sc, hdr->addr2);
-       spin_unlock_bh(&sc->node_lock);
-
-       if (an) {
-               ath_rx_input(sc, an,
-                            hw->conf.ht_conf.ht_supported,
-                            skb, status, &st);
-       }
-       if (!an || (st != ATH_RX_CONSUMED))
-               __ieee80211_rx(hw, skb, &rx_status);
-
-       return 0;
-}
-
-int ath_rx_subframe(struct ath_node *an,
-                   struct sk_buff *skb,
-                   struct ath_recv_status *status)
-{
-       struct ath_softc *sc = an->an_sc;
-       struct ieee80211_hw *hw = sc->hw;
-       struct ieee80211_rx_status rx_status;
-
-       /* Prepare rx status */
-       ath9k_rx_prepare(sc, skb, status, &rx_status);
-       if (!(status->flags & ATH_RX_DECRYPT_ERROR))
-               rx_status.flag |= RX_FLAG_DECRYPTED;
-
        __ieee80211_rx(hw, skb, &rx_status);
 
        return 0;
@@ -678,6 +594,7 @@ fail:
 }
 
 #ifdef CONFIG_RFKILL
+
 /*******************/
 /*     Rfkill     */
 /*******************/
@@ -878,43 +795,72 @@ static void ath_deinit_rfkill(struct ath_softc *sc)
                sc->rf_kill.rfkill = NULL;
        }
 }
+
+static int ath_start_rfkill_poll(struct ath_softc *sc)
+{
+       if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+               queue_delayed_work(sc->hw->workqueue,
+                                  &sc->rf_kill.rfkill_poll, 0);
+
+       if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) {
+               if (rfkill_register(sc->rf_kill.rfkill)) {
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "Unable to register rfkill\n");
+                       rfkill_free(sc->rf_kill.rfkill);
+
+                       /* Deinitialize the device */
+                       if (sc->pdev->irq)
+                               free_irq(sc->pdev->irq, sc);
+                       ath_detach(sc);
+                       pci_iounmap(sc->pdev, sc->mem);
+                       pci_release_region(sc->pdev, 0);
+                       pci_disable_device(sc->pdev);
+                       ieee80211_free_hw(sc->hw);
+                       return -EIO;
+               } else {
+                       sc->sc_flags |= SC_OP_RFKILL_REGISTERED;
+               }
+       }
+
+       return 0;
+}
 #endif /* CONFIG_RFKILL */
 
-static int ath_detach(struct ath_softc *sc)
+static void ath_detach(struct ath_softc *sc)
 {
        struct ieee80211_hw *hw = sc->hw;
+       int i = 0;
 
        DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__);
 
-       /* Deinit LED control */
+       ieee80211_unregister_hw(hw);
+
        ath_deinit_leds(sc);
 
 #ifdef CONFIG_RFKILL
-       /* deinit rfkill */
        ath_deinit_rfkill(sc);
 #endif
-
-       /* Unregister hw */
-
-       ieee80211_unregister_hw(hw);
-
-       /* unregister Rate control */
        ath_rate_control_unregister();
-
-       /* tx/rx cleanup */
+       ath_rate_detach(sc->sc_rc);
 
        ath_rx_cleanup(sc);
        ath_tx_cleanup(sc);
 
-       /* Deinit */
+       tasklet_kill(&sc->intr_tq);
+       tasklet_kill(&sc->bcon_tasklet);
 
-       ath_deinit(sc);
+       if (!(sc->sc_flags & SC_OP_INVALID))
+               ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
 
-       return 0;
+       /* cleanup tx queues */
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+               if (ATH_TXQ_SETUP(sc, i))
+                       ath_tx_cleanupq(sc, &sc->sc_txq[i]);
+
+       ath9k_hw_detach(sc->sc_ah);
 }
 
-static int ath_attach(u16 devid,
-                     struct ath_softc *sc)
+static int ath_attach(u16 devid, struct ath_softc *sc)
 {
        struct ieee80211_hw *hw = sc->hw;
        int error = 0;
@@ -925,50 +871,23 @@ static int ath_attach(u16 devid,
        if (error != 0)
                return error;
 
-       /* Init nodes */
-
-       INIT_LIST_HEAD(&sc->node_list);
-       spin_lock_init(&sc->node_lock);
-
        /* get mac address from hardware and set in mac80211 */
 
        SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr);
 
-       /* setup channels and rates */
-
-       sc->sbands[IEEE80211_BAND_2GHZ].channels =
-               sc->channels[IEEE80211_BAND_2GHZ];
-       sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
-               sc->rates[IEEE80211_BAND_2GHZ];
-       sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
-
-       if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
-               /* Setup HT capabilities for 2.4Ghz*/
-               setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_info);
-
-       hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
-               &sc->sbands[IEEE80211_BAND_2GHZ];
-
-       if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) {
-               sc->sbands[IEEE80211_BAND_5GHZ].channels =
-                       sc->channels[IEEE80211_BAND_5GHZ];
-               sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
-                       sc->rates[IEEE80211_BAND_5GHZ];
-               sc->sbands[IEEE80211_BAND_5GHZ].band =
-                       IEEE80211_BAND_5GHZ;
-
-               if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
-                       /* Setup HT capabilities for 5Ghz*/
-                       setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_info);
-
-               hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
-                       &sc->sbands[IEEE80211_BAND_5GHZ];
-       }
+       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+               IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+               IEEE80211_HW_SIGNAL_DBM |
+               IEEE80211_HW_AMPDU_AGGREGATION;
 
-       /* FIXME: Have to figure out proper hw init values later */
+       hw->wiphy->interface_modes =
+               BIT(NL80211_IFTYPE_AP) |
+               BIT(NL80211_IFTYPE_STATION) |
+               BIT(NL80211_IFTYPE_ADHOC);
 
        hw->queues = 4;
-       hw->ampdu_queues = 1;
+       hw->sta_data_size = sizeof(struct ath_node);
+       hw->vif_data_size = sizeof(struct ath_vap);
 
        /* Register rate control */
        hw->rate_control_algorithm = "ath9k_rate_control";
@@ -981,6 +900,17 @@ static int ath_attach(u16 devid,
                goto bad;
        }
 
+       if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) {
+               setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
+               if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes))
+                       setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
+       }
+
+       hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &sc->sbands[IEEE80211_BAND_2GHZ];
+       if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes))
+               hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+                       &sc->sbands[IEEE80211_BAND_5GHZ];
+
        error = ieee80211_register_hw(hw);
        if (error != 0) {
                ath_rate_control_unregister();
@@ -1026,62 +956,44 @@ static int ath9k_start(struct ieee80211_hw *hw)
        DPRINTF(sc, ATH_DBG_CONFIG, "%s: Starting driver with "
                "initial channel: %d MHz\n", __func__, curchan->center_freq);
 
+       memset(&sc->sc_ht_info, 0, sizeof(struct ath_ht_info));
+
        /* setup initial channel */
 
        pos = ath_get_channel(sc, curchan);
        if (pos == -1) {
                DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__);
-               return -EINVAL;
+               error = -EINVAL;
+               goto exit;
        }
 
        sc->sc_ah->ah_channels[pos].chanmode =
                (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A;
 
-       /* open ath_dev */
        error = ath_open(sc, &sc->sc_ah->ah_channels[pos]);
        if (error) {
                DPRINTF(sc, ATH_DBG_FATAL,
                        "%s: Unable to complete ath_open\n", __func__);
-               return error;
+               goto exit;
        }
 
 #ifdef CONFIG_RFKILL
-       /* Start rfkill polling */
-       if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-               queue_delayed_work(sc->hw->workqueue,
-                                  &sc->rf_kill.rfkill_poll, 0);
-
-       if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) {
-               if (rfkill_register(sc->rf_kill.rfkill)) {
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                                       "Unable to register rfkill\n");
-                       rfkill_free(sc->rf_kill.rfkill);
-
-                       /* Deinitialize the device */
-                       if (sc->pdev->irq)
-                               free_irq(sc->pdev->irq, sc);
-                       ath_detach(sc);
-                       pci_iounmap(sc->pdev, sc->mem);
-                       pci_release_region(sc->pdev, 0);
-                       pci_disable_device(sc->pdev);
-                       ieee80211_free_hw(hw);
-                       return -EIO;
-               } else {
-                       sc->sc_flags |= SC_OP_RFKILL_REGISTERED;
-               }
-       }
+       error = ath_start_rfkill_poll(sc);
 #endif
 
-       ieee80211_wake_queues(hw);
-       return 0;
+exit:
+       return error;
 }
 
 static int ath9k_tx(struct ieee80211_hw *hw,
                    struct sk_buff *skb)
 {
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ath_softc *sc = hw->priv;
+       struct ath_tx_control txctl;
        int hdrlen, padsize;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+       memset(&txctl, 0, sizeof(struct ath_tx_control));
 
        /*
         * As a temporary workaround, assign seq# here; this will likely need
@@ -1106,45 +1018,47 @@ static int ath9k_tx(struct ieee80211_hw *hw,
                memmove(skb->data, skb->data + padsize, hdrlen);
        }
 
+       /* Check if a tx queue is available */
+
+       txctl.txq = ath_test_get_txq(sc, skb);
+       if (!txctl.txq)
+               goto exit;
+
        DPRINTF(sc, ATH_DBG_XMIT, "%s: transmitting packet, skb: %p\n",
                __func__,
                skb);
 
-       if (ath_tx_start(sc, skb) != 0) {
+       if (ath_tx_start(sc, skb, &txctl) != 0) {
                DPRINTF(sc, ATH_DBG_XMIT, "%s: TX failed\n", __func__);
-               dev_kfree_skb_any(skb);
-               /* FIXME: Check for proper return value from ATH_DEV */
-               return 0;
+               goto exit;
        }
 
+       return 0;
+exit:
+       dev_kfree_skb_any(skb);
        return 0;
 }
 
 static void ath9k_stop(struct ieee80211_hw *hw)
 {
        struct ath_softc *sc = hw->priv;
-       int error;
 
-       DPRINTF(sc, ATH_DBG_CONFIG, "%s: Driver halt\n", __func__);
-
-       error = ath_suspend(sc);
-       if (error)
-               DPRINTF(sc, ATH_DBG_CONFIG,
-                       "%s: Device is no longer present\n", __func__);
+       if (sc->sc_flags & SC_OP_INVALID) {
+               DPRINTF(sc, ATH_DBG_ANY, "%s: Device not present\n", __func__);
+               return;
+       }
 
-       ieee80211_stop_queues(hw);
+       ath_stop(sc);
 
-#ifdef CONFIG_RFKILL
-       if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-               cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
-#endif
+       DPRINTF(sc, ATH_DBG_CONFIG, "%s: Driver halt\n", __func__);
 }
 
 static int ath9k_add_interface(struct ieee80211_hw *hw,
                               struct ieee80211_if_init_conf *conf)
 {
        struct ath_softc *sc = hw->priv;
-       int error, ic_opmode = 0;
+       struct ath_vap *avp = (void *)conf->vif->drv_priv;
+       int ic_opmode = 0;
 
        /* Support only vap for now */
 
@@ -1172,13 +1086,22 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
                __func__,
                ic_opmode);
 
-       error = ath_vap_attach(sc, 0, conf->vif, ic_opmode);
-       if (error) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "%s: Unable to attach vap, error: %d\n",
-                       __func__, error);
-               return error;
-       }
+       /* Set the VAP opmode */
+       avp->av_opmode = ic_opmode;
+       avp->av_bslot = -1;
+
+       if (ic_opmode == ATH9K_M_HOSTAP)
+               ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
+
+       sc->sc_vaps[0] = conf->vif;
+       sc->sc_nvaps++;
+
+       /* Set the device opmode */
+       sc->sc_ah->ah_opmode = ic_opmode;
+
+       /* default VAP configuration */
+       avp->av_config.av_fixed_rateset = IEEE80211_FIXED_RATE_NONE;
+       avp->av_config.av_fixed_retryset = 0x03030303;
 
        if (conf->type == NL80211_IFTYPE_AP) {
                /* TODO: is this a suitable place to start ANI for AP mode? */
@@ -1194,27 +1117,16 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
                                   struct ieee80211_if_init_conf *conf)
 {
        struct ath_softc *sc = hw->priv;
-       struct ath_vap *avp;
-       int error;
+       struct ath_vap *avp = (void *)conf->vif->drv_priv;
 
        DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach VAP\n", __func__);
 
-       avp = sc->sc_vaps[0];
-       if (avp == NULL) {
-               DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
-                       __func__);
-               return;
-       }
-
 #ifdef CONFIG_SLOW_ANT_DIV
        ath_slow_ant_div_stop(&sc->sc_antdiv);
 #endif
        /* Stop ANI */
        del_timer_sync(&sc->sc_ani.timer);
 
-       /* Update ratectrl */
-       ath_rate_newstate(sc, avp);
-
        /* Reclaim beacon resources */
        if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP ||
            sc->sc_ah->ah_opmode == ATH9K_M_IBSS) {
@@ -1222,29 +1134,26 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
                ath_beacon_return(sc, avp);
        }
 
-       /* Set interrupt mask */
-       sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask & ~ATH9K_INT_GLOBAL);
        sc->sc_flags &= ~SC_OP_BEACONS;
 
-       error = ath_vap_detach(sc, 0);
-       if (error)
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "%s: Unable to detach vap, error: %d\n",
-                       __func__, error);
+       sc->sc_vaps[0] = NULL;
+       sc->sc_nvaps--;
 }
 
-static int ath9k_config(struct ieee80211_hw *hw,
-                       struct ieee80211_conf *conf)
+static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct ath_softc *sc = hw->priv;
        struct ieee80211_channel *curchan = hw->conf.channel;
+       struct ieee80211_conf *conf = &hw->conf;
        int pos;
 
        DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n",
                __func__,
                curchan->center_freq);
 
+       /* Update chainmask */
+       ath_update_chainmask(sc, conf->ht.enabled);
+
        pos = ath_get_channel(sc, curchan);
        if (pos == -1) {
                DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__);
@@ -1255,11 +1164,12 @@ static int ath9k_config(struct ieee80211_hw *hw,
                (curchan->band == IEEE80211_BAND_2GHZ) ?
                CHANNEL_G : CHANNEL_A;
 
-       if (sc->sc_curaid && hw->conf.ht_conf.ht_supported)
+       if (sc->sc_curaid && hw->conf.ht.enabled)
                sc->sc_ah->ah_channels[pos].chanmode =
                        ath_get_extchanmode(sc, curchan);
 
-       sc->sc_config.txpowlimit = 2 * conf->power_level;
+       if (changed & IEEE80211_CONF_CHANGE_POWER)
+               sc->sc_config.txpowlimit = 2 * conf->power_level;
 
        /* set h/w channel */
        if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0)
@@ -1275,17 +1185,9 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
 {
        struct ath_softc *sc = hw->priv;
        struct ath_hal *ah = sc->sc_ah;
-       struct ath_vap *avp;
+       struct ath_vap *avp = (void *)vif->drv_priv;
        u32 rfilt = 0;
        int error, i;
-       DECLARE_MAC_BUF(mac);
-
-       avp = sc->sc_vaps[0];
-       if (avp == NULL) {
-               DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
-                       __func__);
-               return -EINVAL;
-       }
 
        /* TODO: Need to decide which hw opmode to use for multi-interface
         * cases */
@@ -1315,27 +1217,10 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
                        /* Set aggregation protection mode parameters */
                        sc->sc_config.ath_aggr_prot = 0;
 
-                       /*
-                        * Reset our TSF so that its value is lower than the
-                        * beacon that we are trying to catch.
-                        * Only then hw will update its TSF register with the
-                        * new beacon. Reset the TSF before setting the BSSID
-                        * to avoid allowing in any frames that would update
-                        * our TSF only to have us clear it
-                        * immediately thereafter.
-                        */
-                       ath9k_hw_reset_tsf(sc->sc_ah);
-
-                       /* Disable BMISS interrupt when we're not associated */
-                       ath9k_hw_set_interrupts(sc->sc_ah,
-                                       sc->sc_imask &
-                                       ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS));
-                       sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
-
                        DPRINTF(sc, ATH_DBG_CONFIG,
-                               "%s: RX filter 0x%x bssid %s aid 0x%x\n",
+                               "%s: RX filter 0x%x bssid %pM aid 0x%x\n",
                                __func__, rfilt,
-                               print_mac(mac, sc->sc_curbssid), sc->sc_curaid);
+                               sc->sc_curbssid, sc->sc_curaid);
 
                        /* need to reconfigure the beacon */
                        sc->sc_flags &= ~SC_OP_BEACONS ;
@@ -1367,7 +1252,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
        }
 
        /* Check for WLAN_CAPABILITY_PRIVACY ? */
-       if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
+       if ((avp->av_opmode != ATH9K_M_STA)) {
                for (i = 0; i < IEEE80211_WEP_NKID; i++)
                        if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
                                ath9k_hw_keysetmac(sc->sc_ah,
@@ -1422,37 +1307,13 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw,
                             struct ieee80211_sta *sta)
 {
        struct ath_softc *sc = hw->priv;
-       struct ath_node *an;
-       unsigned long flags;
-       DECLARE_MAC_BUF(mac);
-
-       spin_lock_irqsave(&sc->node_lock, flags);
-       an = ath_node_find(sc, sta->addr);
-       spin_unlock_irqrestore(&sc->node_lock, flags);
 
        switch (cmd) {
        case STA_NOTIFY_ADD:
-               spin_lock_irqsave(&sc->node_lock, flags);
-               if (!an) {
-                       ath_node_attach(sc, sta->addr, 0);
-                       DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach a node: %s\n",
-                               __func__, print_mac(mac, sta->addr));
-               } else {
-                       ath_node_get(sc, sta->addr);
-               }
-               spin_unlock_irqrestore(&sc->node_lock, flags);
+               ath_node_attach(sc, sta);
                break;
        case STA_NOTIFY_REMOVE:
-               if (!an)
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "%s: Removal of a non-existent node\n",
-                               __func__);
-               else {
-                       ath_node_put(sc, an, ATH9K_BH_STATUS_INTACT);
-                       DPRINTF(sc, ATH_DBG_CONFIG, "%s: Put a node: %s\n",
-                               __func__,
-                               print_mac(mac, sta->addr));
-               }
+               ath_node_detach(sc, sta);
                break;
        default:
                break;
@@ -1558,9 +1419,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
        }
 
        if (changed & BSS_CHANGED_HT) {
-               DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed HT %d\n",
-                       __func__,
-                       bss_conf->assoc_ht);
+               DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed HT\n",
+                       __func__);
                ath9k_ht_conf(sc, bss_conf);
        }
 
@@ -1568,7 +1428,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
                DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed ASSOC %d\n",
                        __func__,
                        bss_conf->assoc);
-               ath9k_bss_assoc_info(sc, bss_conf);
+               ath9k_bss_assoc_info(sc, vif, bss_conf);
        }
 }
 
@@ -1601,21 +1461,13 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
 
        switch (action) {
        case IEEE80211_AMPDU_RX_START:
-               ret = ath_rx_aggr_start(sc, sta->addr, tid, ssn);
-               if (ret < 0)
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "%s: Unable to start RX aggregation\n",
-                               __func__);
+               if (!(sc->sc_flags & SC_OP_RXAGGR))
+                       ret = -ENOTSUPP;
                break;
        case IEEE80211_AMPDU_RX_STOP:
-               ret = ath_rx_aggr_stop(sc, sta->addr, tid);
-               if (ret < 0)
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "%s: Unable to stop RX aggregation\n",
-                               __func__);
                break;
        case IEEE80211_AMPDU_TX_START:
-               ret = ath_tx_aggr_start(sc, sta->addr, tid, ssn);
+               ret = ath_tx_aggr_start(sc, sta, tid, ssn);
                if (ret < 0)
                        DPRINTF(sc, ATH_DBG_FATAL,
                                "%s: Unable to start TX aggregation\n",
@@ -1624,7 +1476,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
                        ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
                break;
        case IEEE80211_AMPDU_TX_STOP:
-               ret = ath_tx_aggr_stop(sc, sta->addr, tid);
+               ret = ath_tx_aggr_stop(sc, sta, tid);
                if (ret < 0)
                        DPRINTF(sc, ATH_DBG_FATAL,
                                "%s: Unable to stop TX aggregation\n",
@@ -1632,6 +1484,9 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
 
                ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
                break;
+       case IEEE80211_AMPDU_TX_RESUME:
+               ath_tx_aggr_resume(sc, sta, tid);
+               break;
        default:
                DPRINTF(sc, ATH_DBG_FATAL,
                        "%s: Unknown AMPDU action\n", __func__);
@@ -1654,21 +1509,12 @@ static struct ieee80211_ops ath9k_ops = {
        .config             = ath9k_config,
        .config_interface   = ath9k_config_interface,
        .configure_filter   = ath9k_configure_filter,
-       .get_stats          = NULL,
        .sta_notify         = ath9k_sta_notify,
        .conf_tx            = ath9k_conf_tx,
-       .get_tx_stats       = NULL,
        .bss_info_changed   = ath9k_bss_info_changed,
-       .set_tim            = NULL,
        .set_key            = ath9k_set_key,
-       .hw_scan            = NULL,
-       .get_tkip_seq       = NULL,
-       .set_rts_threshold  = NULL,
-       .set_frag_threshold = NULL,
-       .set_retry_limit    = NULL,
        .get_tsf            = ath9k_get_tsf,
        .reset_tsf          = ath9k_reset_tsf,
-       .tx_last_beacon     = NULL,
        .ampdu_action       = ath9k_ampdu_action,
        .set_frag_threshold = ath9k_no_fragmentation,
 };
@@ -1746,16 +1592,6 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                goto bad2;
        }
 
-       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
-               IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-               IEEE80211_HW_SIGNAL_DBM |
-               IEEE80211_HW_NOISE_DBM;
-
-       hw->wiphy->interface_modes =
-               BIT(NL80211_IFTYPE_AP) |
-               BIT(NL80211_IFTYPE_STATION) |
-               BIT(NL80211_IFTYPE_ADHOC);
-
        SET_IEEE80211_DEV(hw, &pdev->dev);
        pci_set_drvdata(pdev, hw);
 
@@ -1803,17 +1639,10 @@ 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) {
-               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);
-
+       if (pdev->irq)
+               free_irq(pdev->irq, sc);
        pci_iounmap(pdev, sc->mem);
        pci_release_region(pdev, 0);
        pci_disable_device(pdev);
index eb9121fdfd385389087807526edcc28924e12942..4f1c8bf8342b7aea430dcfc7ef3da59048f4908c 100644 (file)
@@ -215,7 +215,7 @@ ath9k_hw_set_rf_regs(struct ath_hal *ah, struct ath9k_channel *chan,
        if (AR_SREV_9280_10_OR_LATER(ah))
                return true;
 
-       eepMinorRev = ath9k_hw_get_eeprom(ahp, EEP_MINOR_REV);
+       eepMinorRev = ath9k_hw_get_eeprom(ah, EEP_MINOR_REV);
 
        RF_BANK_SETUP(ahp->ah_analogBank0Data, &ahp->ah_iniBank0, 1);
 
@@ -235,15 +235,15 @@ ath9k_hw_set_rf_regs(struct ath_hal *ah, struct ath9k_channel *chan,
 
        if (eepMinorRev >= 2) {
                if (IS_CHAN_2GHZ(chan)) {
-                       ob2GHz = ath9k_hw_get_eeprom(ahp, EEP_OB_2);
-                       db2GHz = ath9k_hw_get_eeprom(ahp, EEP_DB_2);
+                       ob2GHz = ath9k_hw_get_eeprom(ah, EEP_OB_2);
+                       db2GHz = ath9k_hw_get_eeprom(ah, EEP_DB_2);
                        ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
                                                   ob2GHz, 3, 197, 0);
                        ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
                                                   db2GHz, 3, 194, 0);
                } else {
-                       ob5GHz = ath9k_hw_get_eeprom(ahp, EEP_OB_5);
-                       db5GHz = ath9k_hw_get_eeprom(ahp, EEP_DB_5);
+                       ob5GHz = ath9k_hw_get_eeprom(ah, EEP_OB_5);
+                       db5GHz = ath9k_hw_get_eeprom(ah, EEP_DB_5);
                        ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
                                                   ob5GHz, 3, 203, 0);
                        ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
index cca2fc5b07654b3e17107b4acaf2b7893e328d53..aa6bfd717c2055693ebd2635ef95aca5dcae7639 100644 (file)
@@ -816,7 +816,7 @@ void ath_rate_detach(struct ath_rate_softc *asc)
 }
 
 u8 ath_rate_findrateix(struct ath_softc *sc,
-                            u8 dot11rate)
+                      u8 dot11rate)
 {
        const struct ath_rate_table *ratetable;
        struct ath_rate_softc *rsc = sc->sc_rc;
@@ -1838,7 +1838,7 @@ void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv)
        struct ath_softc *sc = hw->priv;
        u32 capflag = 0;
 
-       if (hw->conf.ht_conf.ht_supported) {
+       if (hw->conf.ht.enabled) {
                capflag |= ATH_RC_HT_FLAG | ATH_RC_DS_FLAG;
                if (sc->sc_ht_info.tx_chan_width == ATH9K_HT_MACMODE_2040)
                        capflag |= ATH_RC_CW40_FLAG;
@@ -1864,73 +1864,26 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
 
        hdr = (struct ieee80211_hdr *)skb->data;
        fc = hdr->frame_control;
-       tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
+       /* XXX: UGLY HACK!! */
+       tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif;
 
-       spin_lock_bh(&sc->node_lock);
-       an = ath_node_find(sc, hdr->addr1);
-       spin_unlock_bh(&sc->node_lock);
+       an = (struct ath_node *)sta->drv_priv;
 
-       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;
-               }
+       if (tx_info_priv == NULL)
                return;
-       }
-       if (tx_info->driver_data[0] != NULL) {
-               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 ieee80211_supported_band *sband,
-                            struct ieee80211_sta *sta,
-                            struct ath_node *an,
-                            u8 tidno)
-{
-       struct ath_atx_tid *txtid;
-       u16 buffersize = 0;
-       int state;
-       struct sta_info *si;
 
-       if (!(sc->sc_flags & SC_OP_TXAGGR))
-               return;
-
-       txtid = ATH_AN_2_TID(an, tidno);
-       if (!txtid->paused)
-               return;
+       if (an && priv_sta && ieee80211_is_data(fc))
+               ath_rate_tx_complete(sc, an, priv_sta, tx_info_priv);
 
-       /*
-        * 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 = si->ampdu_mlme.tid_state_tx[tidno];
-
-       if (state & HT_ADDBA_RECEIVED_MSK) {
-               txtid->addba_exchangecomplete = 1;
-               txtid->addba_exchangeinprogress = 0;
-               txtid->baw_size = buffersize;
-
-               DPRINTF(sc, ATH_DBG_AGGR,
-                       "%s: Resuming tid, buffersize: %d\n",
-                       __func__,
-                       buffersize);
-
-               ath_tx_resume_tid(sc, txtid);
-       }
+       kfree(tx_info_priv);
+       tx_info->control.vif = NULL;
 }
 
-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)
+static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
+                        struct ieee80211_tx_rate_control *txrc)
 {
+       struct ieee80211_supported_band *sband = txrc->sband;
+       struct sk_buff *skb = txrc->skb;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct ath_softc *sc = priv;
        struct ieee80211_hw *hw = sc->hw;
@@ -1938,25 +1891,24 @@ static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband,
        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;
+       int is_probe = FALSE;
        s8 lowest_idx;
        __le16 fc = hdr->frame_control;
        u8 *qc, tid;
-       DECLARE_MAC_BUF(mac);
 
        DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
 
-       /* allocate driver private area of tx_info */
-       tx_info->driver_data[0] = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
-       ASSERT(tx_info->driver_data[0] != NULL);
-       tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
+       /* allocate driver private area of tx_info, XXX: UGLY HACK! */
+       tx_info->control.vif = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
+       tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif;
+       ASSERT(tx_info_priv != NULL);
 
        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) ||
            is_multicast_ether_addr(hdr->addr1) || !sta) {
-               sel->rate_idx = lowest_idx;
+               tx_info->control.rates[0].idx = lowest_idx;
                return;
        }
 
@@ -1967,8 +1919,10 @@ static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband,
                          tx_info_priv->rcs,
                          &is_probe,
                          false);
+#if 0
        if (is_probe)
                sel->probe_idx = ath_rc_priv->tx_ratectrl.probe_rate;
+#endif
 
        /* Ratecontrol sometimes returns invalid rate index */
        if (tx_info_priv->rcs[0].rix != 0xff)
@@ -1976,43 +1930,18 @@ static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband,
        else
                tx_info_priv->rcs[0].rix = ath_rc_priv->prev_data_rix;
 
-       sel->rate_idx = tx_info_priv->rcs[0].rix;
+       tx_info->control.rates[0].idx = tx_info_priv->rcs[0].rix;
 
        /* Check if aggregation has to be enabled for this tid */
 
-       if (hw->conf.ht_conf.ht_supported) {
+       if (hw->conf.ht.enabled) {
                if (ieee80211_is_data_qos(fc)) {
                        qc = ieee80211_get_qos_ctl(hdr);
                        tid = qc[0] & 0xf;
+                       an = (struct ath_node *)sta->drv_priv;
 
-                       spin_lock_bh(&sc->node_lock);
-                       an = ath_node_find(sc, hdr->addr1);
-                       spin_unlock_bh(&sc->node_lock);
-
-                       if (!an) {
-                               DPRINTF(sc, ATH_DBG_AGGR,
-                                       "%s: Node not found to "
-                                       "init/chk TX aggr\n", __func__);
-                               return;
-                       }
-
-                       chk = ath_tx_aggr_check(sc, an, tid);
-                       if (chk == AGGR_REQUIRED) {
-                               ret = ieee80211_start_tx_ba_session(hw,
-                                       hdr->addr1, tid);
-                               if (ret)
-                                       DPRINTF(sc, ATH_DBG_AGGR,
-                                               "%s: Unable to start tx "
-                                               "aggr for: %s\n",
-                                               __func__,
-                                               print_mac(mac, hdr->addr1));
-                               else
-                                       DPRINTF(sc, ATH_DBG_AGGR,
-                                               "%s: Started tx aggr for: %s\n",
-                                               __func__,
-                                               print_mac(mac, hdr->addr1));
-                       } else if (chk == AGGR_EXCHANGE_PROGRESS)
-                               ath_tx_aggr_resp(sc, sband, sta, an, tid);
+                       if(ath_tx_aggr_check(sc, an, tid))
+                               ieee80211_start_tx_ba_session(hw, hdr->addr1, tid);
                }
        }
 }
@@ -2027,9 +1956,9 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
        DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
 
        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 (sc->hw->conf.ht_conf.supp_mcs_set[i/8] & (1<<(i%8)))
+       if (sta->ht_cap.ht_supported) {
+               for (i = 0; i < 77; i++) {
+                       if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
                                ath_rc_priv->neg_ht_rates.rs_rates[j++] = i;
                        if (j == ATH_RATE_MAX)
                                break;
@@ -2039,11 +1968,6 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
        ath_rc_node_update(sc->hw, priv_sta);
 }
 
-static void ath_rate_clear(void *priv)
-{
-       return;
-}
-
 static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
 {
        struct ath_softc *sc = hw->priv;
@@ -2059,12 +1983,18 @@ static void ath_rate_free(void *priv)
 
 static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
 {
+       struct ieee80211_vif *vif;
        struct ath_softc *sc = priv;
-       struct ath_vap *avp = sc->sc_vaps[0];
+       struct ath_vap *avp;
        struct ath_rate_node *rate_priv;
 
        DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
 
+       vif = sc->sc_vaps[0];
+       ASSERT(vif);
+
+       avp = (void *)vif->drv_priv;
+
        rate_priv = ath_rate_node_alloc(avp, sc->sc_rc, gfp);
        if (!rate_priv) {
                DPRINTF(sc, ATH_DBG_FATAL,
@@ -2093,7 +2023,6 @@ static struct rate_control_ops ath_rate_ops = {
        .tx_status = ath_tx_status,
        .get_rate = ath_get_rate,
        .rate_init = ath_rate_init,
-       .clear = ath_rate_clear,
        .alloc = ath_rate_alloc,
        .free = ath_rate_free,
        .alloc_sta = ath_rate_alloc_sta,
index b95b41508b986000174519cc451458962f4962c3..6671097fad7220a4e63e904045bec46ca333c6fe 100644 (file)
@@ -59,7 +59,6 @@ struct ath_softc;
 #define FALSE 0
 
 #define ATH_RATE_MAX   30
-#define MCS_SET_SIZE   128
 
 enum ieee80211_fixed_rate_mode {
        IEEE80211_FIXED_RATE_NONE  = 0,
index 4983402af559871f8ed526480794235dfc37959e..2ecb0a010ce2bcd738395ce0ac1c836e7d53f6a3 100644 (file)
@@ -64,328 +64,6 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
        ath9k_hw_rxena(ah);
 }
 
-/* Process received BAR frame */
-
-static int ath_bar_rx(struct ath_softc *sc,
-                     struct ath_node *an,
-                     struct sk_buff *skb)
-{
-       struct ieee80211_bar *bar;
-       struct ath_arx_tid *rxtid;
-       struct sk_buff *tskb;
-       struct ath_recv_status *rx_status;
-       int tidno, index, cindex;
-       u16 seqno;
-
-       /* look at BAR contents  */
-
-       bar = (struct ieee80211_bar *)skb->data;
-       tidno = (le16_to_cpu(bar->control) & IEEE80211_BAR_CTL_TID_M)
-               >> IEEE80211_BAR_CTL_TID_S;
-       seqno = le16_to_cpu(bar->start_seq_num) >> IEEE80211_SEQ_SEQ_SHIFT;
-
-       /* process BAR - indicate all pending RX frames till the BAR seqno */
-
-       rxtid = &an->an_aggr.rx.tid[tidno];
-
-       spin_lock_bh(&rxtid->tidlock);
-
-       /* get relative index */
-
-       index = ATH_BA_INDEX(rxtid->seq_next, seqno);
-
-       /* drop BAR if old sequence (index is too large) */
-
-       if ((index > rxtid->baw_size) &&
-           (index > (IEEE80211_SEQ_MAX - (rxtid->baw_size << 2))))
-               /* discard frame, ieee layer may not treat frame as a dup */
-               goto unlock_and_free;
-
-       /* complete receive processing for all pending frames upto BAR seqno */
-
-       cindex = (rxtid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
-       while ((rxtid->baw_head != rxtid->baw_tail) &&
-              (rxtid->baw_head != cindex)) {
-               tskb = rxtid->rxbuf[rxtid->baw_head].rx_wbuf;
-               rx_status = &rxtid->rxbuf[rxtid->baw_head].rx_status;
-               rxtid->rxbuf[rxtid->baw_head].rx_wbuf = NULL;
-
-               if (tskb != NULL)
-                       ath_rx_subframe(an, tskb, rx_status);
-
-               INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
-               INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
-       }
-
-       /* ... and indicate rest of the frames in-order */
-
-       while (rxtid->baw_head != rxtid->baw_tail &&
-              rxtid->rxbuf[rxtid->baw_head].rx_wbuf != NULL) {
-               tskb = rxtid->rxbuf[rxtid->baw_head].rx_wbuf;
-               rx_status = &rxtid->rxbuf[rxtid->baw_head].rx_status;
-               rxtid->rxbuf[rxtid->baw_head].rx_wbuf = NULL;
-
-               ath_rx_subframe(an, tskb, rx_status);
-
-               INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
-               INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
-       }
-
-unlock_and_free:
-       spin_unlock_bh(&rxtid->tidlock);
-       /* free bar itself */
-       dev_kfree_skb(skb);
-       return IEEE80211_FTYPE_CTL;
-}
-
-/* Function to handle a subframe of aggregation when HT is enabled */
-
-static int ath_ampdu_input(struct ath_softc *sc,
-                          struct ath_node *an,
-                          struct sk_buff *skb,
-                          struct ath_recv_status *rx_status)
-{
-       struct ieee80211_hdr *hdr;
-       struct ath_arx_tid *rxtid;
-       struct ath_rxbuf *rxbuf;
-       u8 type, subtype;
-       u16 rxseq;
-       int tid = 0, index, cindex, rxdiff;
-       __le16 fc;
-       u8 *qc;
-
-       hdr = (struct ieee80211_hdr *)skb->data;
-       fc = hdr->frame_control;
-
-       /* collect stats of frames with non-zero version */
-
-       if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_VERS) != 0) {
-               dev_kfree_skb(skb);
-               return -1;
-       }
-
-       type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE;
-       subtype = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE;
-
-       if (ieee80211_is_back_req(fc))
-               return ath_bar_rx(sc, an, skb);
-
-       /* special aggregate processing only for qos unicast data frames */
-
-       if (!ieee80211_is_data(fc) ||
-           !ieee80211_is_data_qos(fc) ||
-           is_multicast_ether_addr(hdr->addr1))
-               return ath_rx_subframe(an, skb, rx_status);
-
-       /* lookup rx tid state */
-
-       if (ieee80211_is_data_qos(fc)) {
-               qc = ieee80211_get_qos_ctl(hdr);
-               tid = qc[0] & 0xf;
-       }
-
-       if (sc->sc_ah->ah_opmode == ATH9K_M_STA) {
-               /* Drop the frame not belonging to me. */
-               if (memcmp(hdr->addr1, sc->sc_myaddr, ETH_ALEN)) {
-                       dev_kfree_skb(skb);
-                       return -1;
-               }
-       }
-
-       rxtid = &an->an_aggr.rx.tid[tid];
-
-       spin_lock(&rxtid->tidlock);
-
-       rxdiff = (rxtid->baw_tail - rxtid->baw_head) &
-               (ATH_TID_MAX_BUFS - 1);
-
-       /*
-        * If the ADDBA exchange has not been completed by the source,
-        * process via legacy path (i.e. no reordering buffer is needed)
-        */
-       if (!rxtid->addba_exchangecomplete) {
-               spin_unlock(&rxtid->tidlock);
-               return ath_rx_subframe(an, skb, rx_status);
-       }
-
-       /* extract sequence number from recvd frame */
-
-       rxseq = le16_to_cpu(hdr->seq_ctrl) >> IEEE80211_SEQ_SEQ_SHIFT;
-
-       if (rxtid->seq_reset) {
-               rxtid->seq_reset = 0;
-               rxtid->seq_next = rxseq;
-       }
-
-       index = ATH_BA_INDEX(rxtid->seq_next, rxseq);
-
-       /* drop frame if old sequence (index is too large) */
-
-       if (index > (IEEE80211_SEQ_MAX - (rxtid->baw_size << 2))) {
-               /* discard frame, ieee layer may not treat frame as a dup */
-               spin_unlock(&rxtid->tidlock);
-               dev_kfree_skb(skb);
-               return IEEE80211_FTYPE_DATA;
-       }
-
-       /* sequence number is beyond block-ack window */
-
-       if (index >= rxtid->baw_size) {
-
-               /* complete receive processing for all pending frames */
-
-               while (index >= rxtid->baw_size) {
-
-                       rxbuf = rxtid->rxbuf + rxtid->baw_head;
-
-                       if (rxbuf->rx_wbuf != NULL) {
-                               ath_rx_subframe(an, rxbuf->rx_wbuf,
-                                               &rxbuf->rx_status);
-                               rxbuf->rx_wbuf = NULL;
-                       }
-
-                       INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
-                       INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
-
-                       index--;
-               }
-       }
-
-       /* add buffer to the recv ba window */
-
-       cindex = (rxtid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
-       rxbuf = rxtid->rxbuf + cindex;
-
-       if (rxbuf->rx_wbuf != NULL) {
-               spin_unlock(&rxtid->tidlock);
-               /* duplicate frame */
-               dev_kfree_skb(skb);
-               return IEEE80211_FTYPE_DATA;
-       }
-
-       rxbuf->rx_wbuf = skb;
-       rxbuf->rx_time = get_timestamp();
-       rxbuf->rx_status = *rx_status;
-
-       /* advance tail if sequence received is newer
-        * than any received so far */
-
-       if (index >= rxdiff) {
-               rxtid->baw_tail = cindex;
-               INCR(rxtid->baw_tail, ATH_TID_MAX_BUFS);
-       }
-
-       /* indicate all in-order received frames */
-
-       while (rxtid->baw_head != rxtid->baw_tail) {
-               rxbuf = rxtid->rxbuf + rxtid->baw_head;
-               if (!rxbuf->rx_wbuf)
-                       break;
-
-               ath_rx_subframe(an, rxbuf->rx_wbuf, &rxbuf->rx_status);
-               rxbuf->rx_wbuf = NULL;
-
-               INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
-               INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
-       }
-
-       /*
-        * start a timer to flush all received frames if there are pending
-        * receive frames
-        */
-       if (rxtid->baw_head != rxtid->baw_tail)
-               mod_timer(&rxtid->timer, ATH_RX_TIMEOUT);
-       else
-               del_timer_sync(&rxtid->timer);
-
-       spin_unlock(&rxtid->tidlock);
-       return IEEE80211_FTYPE_DATA;
-}
-
-/* Timer to flush all received sub-frames */
-
-static void ath_rx_timer(unsigned long data)
-{
-       struct ath_arx_tid *rxtid = (struct ath_arx_tid *)data;
-       struct ath_node *an = rxtid->an;
-       struct ath_rxbuf *rxbuf;
-       int nosched;
-
-       spin_lock_bh(&rxtid->tidlock);
-       while (rxtid->baw_head != rxtid->baw_tail) {
-               rxbuf = rxtid->rxbuf + rxtid->baw_head;
-               if (!rxbuf->rx_wbuf) {
-                       INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
-                       INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
-                       continue;
-               }
-
-               /*
-                * Stop if the next one is a very recent frame.
-                *
-                * Call get_timestamp in every iteration to protect against the
-                * case in which a new frame is received while we are executing
-                * this function. Using a timestamp obtained before entering
-                * the loop could lead to a very large time interval
-                * (a negative value typecast to unsigned), breaking the
-                * function's logic.
-                */
-               if ((get_timestamp() - rxbuf->rx_time) <
-                       (ATH_RX_TIMEOUT * HZ / 1000))
-                       break;
-
-               ath_rx_subframe(an, rxbuf->rx_wbuf,
-                               &rxbuf->rx_status);
-               rxbuf->rx_wbuf = NULL;
-
-               INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
-               INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
-       }
-
-       /*
-        * start a timer to flush all received frames if there are pending
-        * receive frames
-        */
-       if (rxtid->baw_head != rxtid->baw_tail)
-               nosched = 0;
-       else
-               nosched = 1; /* no need to re-arm the timer again */
-
-       spin_unlock_bh(&rxtid->tidlock);
-}
-
-/* Free all pending sub-frames in the re-ordering buffer */
-
-static void ath_rx_flush_tid(struct ath_softc *sc,
-       struct ath_arx_tid *rxtid, int drop)
-{
-       struct ath_rxbuf *rxbuf;
-       unsigned long flag;
-
-       spin_lock_irqsave(&rxtid->tidlock, flag);
-       while (rxtid->baw_head != rxtid->baw_tail) {
-               rxbuf = rxtid->rxbuf + rxtid->baw_head;
-               if (!rxbuf->rx_wbuf) {
-                       INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
-                       INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
-                       continue;
-               }
-
-               if (drop)
-                       dev_kfree_skb(rxbuf->rx_wbuf);
-               else
-                       ath_rx_subframe(rxtid->an,
-                                       rxbuf->rx_wbuf,
-                                       &rxbuf->rx_status);
-
-               rxbuf->rx_wbuf = NULL;
-
-               INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
-               INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
-       }
-       spin_unlock_irqrestore(&rxtid->tidlock, flag);
-}
-
 static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc,
        u32 len)
 {
@@ -716,24 +394,6 @@ void ath_flushrecv(struct ath_softc *sc)
        spin_unlock_bh(&sc->sc_rxflushlock);
 }
 
-/* Process an individual frame */
-
-int ath_rx_input(struct ath_softc *sc,
-                struct ath_node *an,
-                int is_ampdu,
-                struct sk_buff *skb,
-                struct ath_recv_status *rx_status,
-                enum ATH_RX_TYPE *status)
-{
-       if (is_ampdu && (sc->sc_flags & SC_OP_RXAGGR)) {
-               *status = ATH_RX_CONSUMED;
-               return ath_ampdu_input(sc, an, skb, rx_status);
-       } else {
-               *status = ATH_RX_NON_CONSUMED;
-               return -1;
-       }
-}
-
 /* Process receive queue, as well as LED, etc. */
 
 int ath_rx_tasklet(struct ath_softc *sc, int flush)
@@ -1092,200 +752,3 @@ rx_next:
        return 0;
 #undef PA2DESC
 }
-
-/* Process ADDBA request in per-TID data structure */
-
-int ath_rx_aggr_start(struct ath_softc *sc,
-                     const u8 *addr,
-                     u16 tid,
-                     u16 *ssn)
-{
-       struct ath_arx_tid *rxtid;
-       struct ath_node *an;
-       struct ieee80211_hw *hw = sc->hw;
-       struct ieee80211_supported_band *sband;
-       u16 buffersize = 0;
-
-       spin_lock_bh(&sc->node_lock);
-       an = ath_node_find(sc, (u8 *) addr);
-       spin_unlock_bh(&sc->node_lock);
-
-       if (!an) {
-               DPRINTF(sc, ATH_DBG_AGGR,
-                       "%s: Node not found to initialize RX aggregation\n",
-                       __func__);
-               return -1;
-       }
-
-       sband = hw->wiphy->bands[hw->conf.channel->band];
-       buffersize = IEEE80211_MIN_AMPDU_BUF <<
-               sband->ht_info.ampdu_factor; /* FIXME */
-
-       rxtid = &an->an_aggr.rx.tid[tid];
-
-       spin_lock_bh(&rxtid->tidlock);
-       if (sc->sc_flags & SC_OP_RXAGGR) {
-               /* Allow aggregation reception
-                * Adjust rx BA window size. Peer might indicate a
-                * zero buffer size for a _dont_care_ condition.
-                */
-               if (buffersize)
-                       rxtid->baw_size = min(buffersize, rxtid->baw_size);
-
-               /* set rx sequence number */
-               rxtid->seq_next = *ssn;
-
-               /* Allocate the receive buffers for this TID */
-               DPRINTF(sc, ATH_DBG_AGGR,
-                       "%s: Allcating rxbuffer for TID %d\n", __func__, tid);
-
-               if (rxtid->rxbuf == NULL) {
-                       /*
-                       * If the rxbuff is not NULL at this point, we *probably*
-                       * already allocated the buffer on a previous ADDBA,
-                       * and this is a subsequent ADDBA that got through.
-                       * Don't allocate, but use the value in the pointer,
-                       * we zero it out when we de-allocate.
-                       */
-                       rxtid->rxbuf = kmalloc(ATH_TID_MAX_BUFS *
-                               sizeof(struct ath_rxbuf), GFP_ATOMIC);
-               }
-               if (rxtid->rxbuf == NULL) {
-                       DPRINTF(sc, ATH_DBG_AGGR,
-                               "%s: Unable to allocate RX buffer, "
-                               "refusing ADDBA\n", __func__);
-               } else {
-                       /* Ensure the memory is zeroed out (all internal
-                        * pointers are null) */
-                       memset(rxtid->rxbuf, 0, ATH_TID_MAX_BUFS *
-                               sizeof(struct ath_rxbuf));
-                       DPRINTF(sc, ATH_DBG_AGGR,
-                               "%s: Allocated @%p\n", __func__, rxtid->rxbuf);
-
-                       /* Allow aggregation reception */
-                       rxtid->addba_exchangecomplete = 1;
-               }
-       }
-       spin_unlock_bh(&rxtid->tidlock);
-
-       return 0;
-}
-
-/* Process DELBA */
-
-int ath_rx_aggr_stop(struct ath_softc *sc,
-                    const u8 *addr,
-                    u16 tid)
-{
-       struct ath_node *an;
-
-       spin_lock_bh(&sc->node_lock);
-       an = ath_node_find(sc, (u8 *) addr);
-       spin_unlock_bh(&sc->node_lock);
-
-       if (!an) {
-               DPRINTF(sc, ATH_DBG_AGGR,
-                       "%s: RX aggr stop for non-existent node\n", __func__);
-               return -1;
-       }
-
-       ath_rx_aggr_teardown(sc, an, tid);
-       return 0;
-}
-
-/* Rx aggregation tear down */
-
-void ath_rx_aggr_teardown(struct ath_softc *sc,
-       struct ath_node *an, u8 tid)
-{
-       struct ath_arx_tid *rxtid = &an->an_aggr.rx.tid[tid];
-
-       if (!rxtid->addba_exchangecomplete)
-               return;
-
-       del_timer_sync(&rxtid->timer);
-       ath_rx_flush_tid(sc, rxtid, 0);
-       rxtid->addba_exchangecomplete = 0;
-
-       /* De-allocate the receive buffer array allocated when addba started */
-
-       if (rxtid->rxbuf) {
-               DPRINTF(sc, ATH_DBG_AGGR,
-                       "%s: Deallocating TID %d rxbuff @%p\n",
-                       __func__, tid, rxtid->rxbuf);
-               kfree(rxtid->rxbuf);
-
-               /* Set pointer to null to avoid reuse*/
-               rxtid->rxbuf = NULL;
-       }
-}
-
-/* Initialize per-node receive state */
-
-void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an)
-{
-       if (sc->sc_flags & SC_OP_RXAGGR) {
-               struct ath_arx_tid *rxtid;
-               int tidno;
-
-               /* Init per tid rx state */
-               for (tidno = 0, rxtid = &an->an_aggr.rx.tid[tidno];
-                               tidno < WME_NUM_TID;
-                               tidno++, rxtid++) {
-                       rxtid->an        = an;
-                       rxtid->seq_reset = 1;
-                       rxtid->seq_next  = 0;
-                       rxtid->baw_size  = WME_MAX_BA;
-                       rxtid->baw_head  = rxtid->baw_tail = 0;
-
-                       /*
-                        * Ensure the buffer pointer is null at this point
-                        * (needs to be allocated when addba is received)
-                       */
-
-                       rxtid->rxbuf     = NULL;
-                       setup_timer(&rxtid->timer, ath_rx_timer,
-                               (unsigned long)rxtid);
-                       spin_lock_init(&rxtid->tidlock);
-
-                       /* ADDBA state */
-                       rxtid->addba_exchangecomplete = 0;
-               }
-       }
-}
-
-void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
-{
-       if (sc->sc_flags & SC_OP_RXAGGR) {
-               struct ath_arx_tid *rxtid;
-               int tidno, i;
-
-               /* Init per tid rx state */
-               for (tidno = 0, rxtid = &an->an_aggr.rx.tid[tidno];
-                               tidno < WME_NUM_TID;
-                               tidno++, rxtid++) {
-
-                       if (!rxtid->addba_exchangecomplete)
-                               continue;
-
-                       /* must cancel timer first */
-                       del_timer_sync(&rxtid->timer);
-
-                       /* drop any pending sub-frames */
-                       ath_rx_flush_tid(sc, rxtid, 1);
-
-                       for (i = 0; i < ATH_TID_MAX_BUFS; i++)
-                               ASSERT(rxtid->rxbuf[i].rx_wbuf == NULL);
-
-                       rxtid->addba_exchangecomplete = 0;
-               }
-       }
-
-}
-
-/* Cleanup per-node receive state */
-
-void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an)
-{
-       ath_rx_node_cleanup(sc, an);
-}
index 3a4757942b3fa80f5454bebffd468b4dc0103e76..8937728b03018a30a204913f49ba85c92e06c88b 100644 (file)
@@ -65,11 +65,12 @@ static u32 bits_per_symbol[][2] = {
  * NB: must be called with txq lock held
  */
 
-static void ath_tx_txqaddbuf(struct ath_softc *sc,
-               struct ath_txq *txq, struct list_head *head)
+static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
+                            struct list_head *head)
 {
        struct ath_hal *ah = sc->sc_ah;
        struct ath_buf *bf;
+
        /*
         * Insert the frame on the outbound list and
         * pass it on to the hardware.
@@ -124,27 +125,29 @@ static int ath_tx_findindex(const struct ath9k_rate_table *rt, int rate)
 
 /* Check if it's okay to send out aggregates */
 
-static int ath_aggr_query(struct ath_softc *sc,
-       struct ath_node *an, u8 tidno)
+static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno)
 {
        struct ath_atx_tid *tid;
        tid = ATH_AN_2_TID(an, tidno);
 
-       if (tid->addba_exchangecomplete || tid->addba_exchangeinprogress)
+       if (tid->state & AGGR_ADDBA_COMPLETE ||
+           tid->state & AGGR_ADDBA_PROGRESS)
                return 1;
        else
                return 0;
 }
 
-static enum ath9k_pkt_type get_hal_packet_type(struct ieee80211_hdr *hdr)
+/* Calculate Atheros packet type from IEEE80211 packet header */
+
+static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
 {
+       struct ieee80211_hdr *hdr;
        enum ath9k_pkt_type htype;
        __le16 fc;
 
+       hdr = (struct ieee80211_hdr *)skb->data;
        fc = hdr->frame_control;
 
-       /* Calculate Atheros packet type from IEEE80211 packet header */
-
        if (ieee80211_is_beacon(fc))
                htype = ATH9K_PKT_TYPE_BEACON;
        else if (ieee80211_is_probe_resp(fc))
@@ -159,232 +162,176 @@ static enum ath9k_pkt_type get_hal_packet_type(struct ieee80211_hdr *hdr)
        return htype;
 }
 
-static void fill_min_rates(struct sk_buff *skb, struct ath_tx_control *txctl)
+static bool check_min_rate(struct sk_buff *skb)
 {
        struct ieee80211_hdr *hdr;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ath_tx_info_priv *tx_info_priv;
+       bool use_minrate = false;
        __le16 fc;
 
        hdr = (struct ieee80211_hdr *)skb->data;
        fc = hdr->frame_control;
-       tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
 
        if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) {
-               txctl->use_minrate = 1;
-               txctl->min_rate = tx_info_priv->min_rate;
+               use_minrate = true;
        } else if (ieee80211_is_data(fc)) {
                if (ieee80211_is_nullfunc(fc) ||
-                       /* Port Access Entity (IEEE 802.1X) */
-                       (skb->protocol == cpu_to_be16(0x888E))) {
-                       txctl->use_minrate = 1;
-                       txctl->min_rate = tx_info_priv->min_rate;
+                   /* Port Access Entity (IEEE 802.1X) */
+                   (skb->protocol == cpu_to_be16(ETH_P_PAE))) {
+                       use_minrate = true;
                }
-               if (is_multicast_ether_addr(hdr->addr1))
-                       txctl->mcast_rate = tx_info_priv->min_rate;
        }
 
+       return use_minrate;
 }
 
-/* This function will setup additional txctl information, mostly rate stuff */
-/* FIXME: seqno, ps */
-static int ath_tx_prepare(struct ath_softc *sc,
-                         struct sk_buff *skb,
-                         struct ath_tx_control *txctl)
+static int get_hw_crypto_keytype(struct sk_buff *skb)
 {
-       struct ieee80211_hw *hw = sc->hw;
-       struct ieee80211_hdr *hdr;
-       struct ath_rc_series *rcs;
-       struct ath_txq *txq = NULL;
-       const struct ath9k_rate_table *rt;
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ath_tx_info_priv *tx_info_priv;
-       int hdrlen;
-       u8 rix, antenna;
-       __le16 fc;
-       u8 *qc;
-
-       txctl->dev = sc;
-       hdr = (struct ieee80211_hdr *)skb->data;
-       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-       fc = hdr->frame_control;
-
-       rt = sc->sc_currates;
-       BUG_ON(!rt);
-
-       /* Fill misc fields */
-
-       spin_lock_bh(&sc->node_lock);
-       txctl->an = ath_node_get(sc, hdr->addr1);
-       /* create a temp node, if the node is not there already */
-       if (!txctl->an)
-               txctl->an = ath_node_attach(sc, hdr->addr1, 0);
-       spin_unlock_bh(&sc->node_lock);
-
-       if (ieee80211_is_data_qos(fc)) {
-               qc = ieee80211_get_qos_ctl(hdr);
-               txctl->tidno = qc[0] & 0xf;
-       }
-
-       txctl->if_id = 0;
-       txctl->frmlen = skb->len + FCS_LEN - (hdrlen & 3);
-       txctl->txpower = MAX_RATE_POWER; /* FIXME */
-
-       /* Fill Key related fields */
-
-       txctl->keytype = ATH9K_KEY_TYPE_CLEAR;
-       txctl->keyix = ATH9K_TXKEYIX_INVALID;
 
        if (tx_info->control.hw_key) {
-               txctl->keyix = tx_info->control.hw_key->hw_key_idx;
-               txctl->frmlen += tx_info->control.hw_key->icv_len;
-
                if (tx_info->control.hw_key->alg == ALG_WEP)
-                       txctl->keytype = ATH9K_KEY_TYPE_WEP;
+                       return ATH9K_KEY_TYPE_WEP;
                else if (tx_info->control.hw_key->alg == ALG_TKIP)
-                       txctl->keytype = ATH9K_KEY_TYPE_TKIP;
+                       return ATH9K_KEY_TYPE_TKIP;
                else if (tx_info->control.hw_key->alg == ALG_CCMP)
-                       txctl->keytype = ATH9K_KEY_TYPE_AES;
+                       return ATH9K_KEY_TYPE_AES;
        }
 
-       /* Fill packet type */
+       return ATH9K_KEY_TYPE_CLEAR;
+}
 
-       txctl->atype = get_hal_packet_type(hdr);
+static void setup_rate_retries(struct ath_softc *sc, struct sk_buff *skb)
+{
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ath_tx_info_priv *tx_info_priv;
+       struct ath_rc_series *rcs;
+       struct ieee80211_hdr *hdr;
+       const struct ath9k_rate_table *rt;
+       bool use_minrate;
+       __le16 fc;
+       u8 rix;
 
-       /* Fill qnum */
+       rt = sc->sc_currates;
+       BUG_ON(!rt);
 
-       if (unlikely(txctl->flags & ATH9K_TXDESC_CAB)) {
-               txctl->qnum = 0;
-               txq = sc->sc_cabq;
-       } else {
-               txctl->qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
-               txq = &sc->sc_txq[txctl->qnum];
-       }
-       spin_lock_bh(&txq->axq_lock);
+       hdr = (struct ieee80211_hdr *)skb->data;
+       fc = hdr->frame_control;
+       tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif; /* HACK */
+       rcs = tx_info_priv->rcs;
 
-       /* Try to avoid running out of descriptors */
-       if (txq->axq_depth >= (ATH_TXBUF - 20) &&
-           !(txctl->flags & ATH9K_TXDESC_CAB)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "%s: TX queue: %d is full, depth: %d\n",
-                       __func__,
-                       txctl->qnum,
-                       txq->axq_depth);
-               ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
-               txq->stopped = 1;
-               spin_unlock_bh(&txq->axq_lock);
-               return -1;
-       }
+       /* Check if min rates have to be used */
+       use_minrate = check_min_rate(skb);
 
-       spin_unlock_bh(&txq->axq_lock);
+       if (ieee80211_is_data(fc) && !use_minrate) {
+               if (is_multicast_ether_addr(hdr->addr1)) {
+                       rcs[0].rix =
+                               ath_tx_findindex(rt, tx_info_priv->min_rate);
+                       /* mcast packets are not re-tried */
+                       rcs[0].tries = 1;
+               }
+       } else {
+               /* for management and control frames,
+                  or for NULL and EAPOL frames */
+               if (use_minrate)
+                       rcs[0].rix = ath_rate_findrateix(sc, tx_info_priv->min_rate);
+               else
+                       rcs[0].rix = 0;
+               rcs[0].tries = ATH_MGT_TXMAXTRY;
+       }
 
-       /* Fill rate */
+       rix = rcs[0].rix;
 
-       fill_min_rates(skb, txctl);
+       if (ieee80211_has_morefrags(fc) ||
+           (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
+               rcs[1].tries = rcs[2].tries = rcs[3].tries = 0;
+               rcs[1].rix = rcs[2].rix = rcs[3].rix = 0;
+               /* reset tries but keep rate index */
+               rcs[0].tries = ATH_TXMAXTRY;
+       }
+}
 
-       /* Fill flags */
+/* Called only when tx aggregation is enabled and HT is supported */
 
-       txctl->flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
+static void assign_aggr_tid_seqno(struct sk_buff *skb,
+                                 struct ath_buf *bf)
+{
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_hdr *hdr;
+       struct ath_node *an;
+       struct ath_atx_tid *tid;
+       __le16 fc;
+       u8 *qc;
 
-       if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
-               txctl->flags |= ATH9K_TXDESC_NOACK;
-       if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
-               txctl->flags |= ATH9K_TXDESC_RTSENA;
+       if (!tx_info->control.sta)
+               return;
 
-       /*
-        * Setup for rate calculations.
-        */
-       tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
-       rcs = tx_info_priv->rcs;
+       an = (struct ath_node *)tx_info->control.sta->drv_priv;
+       hdr = (struct ieee80211_hdr *)skb->data;
+       fc = hdr->frame_control;
 
-       if (ieee80211_is_data(fc) && !txctl->use_minrate) {
+       /* Get tidno */
 
-               /* Enable HT only for DATA frames and not for EAPOL */
-               txctl->ht = (hw->conf.ht_conf.ht_supported &&
-                           (tx_info->flags & IEEE80211_TX_CTL_AMPDU));
+       if (ieee80211_is_data_qos(fc)) {
+               qc = ieee80211_get_qos_ctl(hdr);
+               bf->bf_tidno = qc[0] & 0xf;
+       }
 
-               if (is_multicast_ether_addr(hdr->addr1)) {
-                       rcs[0].rix = (u8)
-                               ath_tx_findindex(rt, txctl->mcast_rate);
+       /* Get seqno */
 
-                       /*
-                        * mcast packets are not re-tried.
-                        */
-                       rcs[0].tries = 1;
-               }
+       if (ieee80211_is_data(fc) && !check_min_rate(skb)) {
                /* For HT capable stations, we save tidno for later use.
                 * We also override seqno set by upper layer with the one
                 * in tx aggregation state.
                 *
-                * First, the fragmentation stat is determined.
                 * If fragmentation is on, the sequence number is
                 * not overridden, since it has been
                 * incremented by the fragmentation routine.
+                *
+                * FIXME: check if the fragmentation threshold exceeds
+                * IEEE80211 max.
                 */
-               if (likely(!(txctl->flags & ATH9K_TXDESC_FRAG_IS_ON)) &&
-                   txctl->ht && (sc->sc_flags & SC_OP_TXAGGR)) {
-                       struct ath_atx_tid *tid;
+               tid = ATH_AN_2_TID(an, bf->bf_tidno);
+               hdr->seq_ctrl = cpu_to_le16(tid->seq_next <<
+                                           IEEE80211_SEQ_SEQ_SHIFT);
+               bf->bf_seqno = tid->seq_next;
+               INCR(tid->seq_next, IEEE80211_SEQ_MAX);
+       }
+}
 
-                       tid = ATH_AN_2_TID(txctl->an, txctl->tidno);
+static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
+                         struct ath_txq *txq)
+{
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       int flags = 0;
 
-                       hdr->seq_ctrl = cpu_to_le16(tid->seq_next <<
-                               IEEE80211_SEQ_SEQ_SHIFT);
-                       txctl->seqno = tid->seq_next;
-                       INCR(tid->seq_next, IEEE80211_SEQ_MAX);
-               }
-       } else {
-               /* for management and control frames,
-                * or for NULL and EAPOL frames */
-               if (txctl->min_rate)
-                       rcs[0].rix = ath_rate_findrateix(sc, txctl->min_rate);
-               else
-                       rcs[0].rix = 0;
-               rcs[0].tries = ATH_MGT_TXMAXTRY;
-       }
-       rix = rcs[0].rix;
+       flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
+       flags |= ATH9K_TXDESC_INTREQ;
 
-       if (ieee80211_has_morefrags(fc) ||
-           (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
-               /*
-               **  Force hardware to use computed duration for next
-               **  fragment by disabling multi-rate retry, which
-               **  updates duration based on the multi-rate
-               **  duration table.
-               */
-               rcs[1].tries = rcs[2].tries = rcs[3].tries = 0;
-               rcs[1].rix = rcs[2].rix = rcs[3].rix = 0;
-               /* reset tries but keep rate index */
-               rcs[0].tries = ATH_TXMAXTRY;
-       }
+       if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
+               flags |= ATH9K_TXDESC_NOACK;
+       if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
+               flags |= ATH9K_TXDESC_RTSENA;
 
-       /*
-        * Determine if a tx interrupt should be generated for
-        * this descriptor.  We take a tx interrupt to reap
-        * descriptors when the h/w hits an EOL condition or
-        * when the descriptor is specifically marked to generate
-        * an interrupt.  We periodically mark descriptors in this
-        * way to insure timely replenishing of the supply needed
-        * for sending frames.  Defering interrupts reduces system
-        * load and potentially allows more concurrent work to be
-        * done but if done to aggressively can cause senders to
-        * backup.
-        *
-        * NB: use >= to deal with sc_txintrperiod changing
-        *     dynamically through sysctl.
-        */
-       spin_lock_bh(&txq->axq_lock);
-       if ((++txq->axq_intrcnt >= sc->sc_txintrperiod)) {
-               txctl->flags |= ATH9K_TXDESC_INTREQ;
-               txq->axq_intrcnt = 0;
-       }
-       spin_unlock_bh(&txq->axq_lock);
+       return flags;
+}
+
+static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
+{
+       struct ath_buf *bf = NULL;
+
+       spin_lock_bh(&sc->sc_txbuflock);
 
-       if (is_multicast_ether_addr(hdr->addr1)) {
-               antenna = sc->sc_mcastantenna + 1;
-               sc->sc_mcastantenna = (sc->sc_mcastantenna + 1) & 0x1;
+       if (unlikely(list_empty(&sc->sc_txbuf))) {
+               spin_unlock_bh(&sc->sc_txbuflock);
+               return NULL;
        }
 
-       return 0;
+       bf = list_first_entry(&sc->sc_txbuf, struct ath_buf, list);
+       list_del(&bf->list);
+
+       spin_unlock_bh(&sc->sc_txbuflock);
+
+       return bf;
 }
 
 /* To complete a chain of buffers associated a frame */
@@ -414,13 +361,14 @@ static void ath_tx_complete_buf(struct ath_softc *sc,
                if (bf_isxretried(bf))
                        tx_status.flags |= ATH_TX_XRETRY;
        }
+
        /* Unmap this frame */
        pci_unmap_single(sc->pdev,
                         bf->bf_dmacontext,
                         skb->len,
                         PCI_DMA_TODEVICE);
        /* complete this frame */
-       ath_tx_complete(sc, skb, &tx_status, bf->bf_node);
+       ath_tx_complete(sc, skb, &tx_status);
 
        /*
         * Return the list of ath_buf of this mpdu to free queue
@@ -505,11 +453,9 @@ unlock:
 
 /* Compute the number of bad frames */
 
-static int ath_tx_num_badfrms(struct ath_softc *sc,
-       struct ath_buf *bf, int txok)
+static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
+                             int txok)
 {
-       struct ath_node *an = bf->bf_node;
-       int isnodegone = (an->an_flags & ATH_NODE_CLEAN);
        struct ath_buf *bf_last = bf->bf_lastbf;
        struct ath_desc *ds = bf_last->bf_desc;
        u16 seq_st = 0;
@@ -518,7 +464,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc,
        int nbad = 0;
        int isaggr = 0;
 
-       if (isnodegone || ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
+       if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
                return 0;
 
        isaggr = bf_isaggr(bf);
@@ -553,8 +499,8 @@ static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
 
 /* Update block ack window */
 
-static void ath_tx_update_baw(struct ath_softc *sc,
-       struct ath_atx_tid *tid, int seqno)
+static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
+                             int seqno)
 {
        int index, cindex;
 
@@ -578,12 +524,8 @@ static void ath_tx_update_baw(struct ath_softc *sc,
  * half_gi - to use 4us v/s 3.6 us for symbol time
  */
 
-static u32 ath_pkt_duration(struct ath_softc *sc,
-                                 u8 rix,
-                                 struct ath_buf *bf,
-                                 int width,
-                                 int half_gi,
-                                 bool shortPreamble)
+static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
+                           int width, int half_gi, bool shortPreamble)
 {
        const struct ath9k_rate_table *rt = sc->sc_currates;
        u32 nbits, nsymbits, duration, nsymbols;
@@ -597,11 +539,8 @@ static u32 ath_pkt_duration(struct ath_softc *sc,
         * for legacy rates, use old function to compute packet duration
         */
        if (!IS_HT_RATE(rc))
-               return ath9k_hw_computetxtime(sc->sc_ah,
-                                            rt,
-                                            pktlen,
-                                            rix,
-                                            shortPreamble);
+               return ath9k_hw_computetxtime(sc->sc_ah, rt, pktlen, rix,
+                                             shortPreamble);
        /*
         * find number of symbols: PLCP + data
         */
@@ -619,6 +558,7 @@ static u32 ath_pkt_duration(struct ath_softc *sc,
         */
        streams = HT_RC_2_STREAMS(rc);
        duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
+
        return duration;
 }
 
@@ -631,11 +571,18 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
        struct ath_desc *ds = bf->bf_desc;
        struct ath_desc *lastds = bf->bf_lastbf->bf_desc;
        struct ath9k_11n_rate_series series[4];
-       int i, flags, rtsctsena = 0, dynamic_mimops = 0;
+       int i, flags, rtsctsena = 0;
        u32 ctsduration = 0;
        u8 rix = 0, cix, ctsrate = 0;
-       u32 aggr_limit_with_rts = ah->ah_caps.rts_aggr_limit;
-       struct ath_node *an = (struct ath_node *) bf->bf_node;
+       struct ath_node *an = NULL;
+       struct sk_buff *skb;
+       struct ieee80211_tx_info *tx_info;
+
+       skb = (struct sk_buff *)bf->bf_mpdu;
+       tx_info = IEEE80211_SKB_CB(skb);
+
+       if (tx_info->control.sta)
+               an = (struct ath_node *)tx_info->control.sta->drv_priv;
 
        /*
         * get the cix for the lowest valid rix.
@@ -674,24 +621,11 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
         * use RTS.
         */
        if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) && bf_isdata(bf)) {
-               BUG_ON(!an);
                /*
                 * 802.11g protection not needed, use our default behavior
                 */
                if (!rtsctsena)
                        flags = ATH9K_TXDESC_RTSENA;
-               /*
-                * For dynamic MIMO PS, RTS needs to precede the first aggregate
-                * and the second aggregate should have any protection at all.
-                */
-               if (an->an_smmode == ATH_SM_PWRSAV_DYNAMIC) {
-                       if (!bf_isaggrburst(bf)) {
-                               flags = ATH9K_TXDESC_RTSENA;
-                               dynamic_mimops = 1;
-                       } else {
-                               flags = 0;
-                       }
-               }
        }
 
        /*
@@ -707,7 +641,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
        /*
         *  For AR5416 - RTS cannot be followed by a frame larger than 8K.
         */
-       if (bf_isaggr(bf) && (bf->bf_al > aggr_limit_with_rts)) {
+       if (bf_isaggr(bf) && (bf->bf_al > ah->ah_caps.rts_aggr_limit)) {
                /*
                 * Ensure that in the case of SM Dynamic power save
                 * while we are bursting the second aggregate the
@@ -720,8 +654,8 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
         * CTS transmit rate is derived from the transmit rate
         * by looking in the h/w rate table.  We must also factor
         * in whether or not a short preamble is to be used.
+        * NB: cix is set above where RTS/CTS is enabled
         */
-       /* NB: cix is set above where RTS/CTS is enabled */
        BUG_ON(cix == 0xff);
        ctsrate = rt->info[cix].rateCode |
                (bf_isshpreamble(bf) ? rt->info[cix].shortPreamble : 0);
@@ -750,39 +684,18 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
                        ((bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG) ?
                                ATH9K_RATESERIES_HALFGI : 0);
 
-               series[i].PktDuration = ath_pkt_duration(
-                       sc, rix, bf,
-                       (bf->bf_rcs[i].flags & ATH_RC_CW40_FLAG) != 0,
-                       (bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG),
-                       bf_isshpreamble(bf));
+               series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
+                        (bf->bf_rcs[i].flags & ATH_RC_CW40_FLAG) != 0,
+                        (bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG),
+                        bf_isshpreamble(bf));
 
-               if ((an->an_smmode == ATH_SM_PWRSAV_STATIC) &&
-                   (bf->bf_rcs[i].flags & ATH_RC_DS_FLAG) == 0) {
-                       /*
-                        * When sending to an HT node that has enabled static
-                        * SM/MIMO power save, send at single stream rates but
-                        * use maximum allowed transmit chains per user,
-                        * hardware, regulatory, or country limits for
-                        * better range.
-                        */
+               if (bf_isht(bf) && an)
+                       series[i].ChSel = ath_chainmask_sel_logic(sc, an);
+               else
                        series[i].ChSel = sc->sc_tx_chainmask;
-               } else {
-                       if (bf_isht(bf))
-                               series[i].ChSel =
-                                       ath_chainmask_sel_logic(sc, an);
-                       else
-                               series[i].ChSel = sc->sc_tx_chainmask;
-               }
 
                if (rtsctsena)
                        series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
-
-               /*
-                * Set RTS for all rates if node is in dynamic powersave
-                * mode and we are using dual stream rates.
-                */
-               if (dynamic_mimops && (bf->bf_rcs[i].flags & ATH_RC_DS_FLAG))
-                       series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
        }
 
        /*
@@ -828,6 +741,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
                                     ctsrate,
                                     ctsduration,
                                     series, 4, flags);
+
        if (sc->sc_config.ath_aggr_prot && flags)
                ath9k_hw_set11n_burstduration(ah, ds, 8192);
 }
@@ -854,7 +768,9 @@ static int ath_tx_send_normal(struct ath_softc *sc,
 
        skb = (struct sk_buff *)bf->bf_mpdu;
        tx_info = IEEE80211_SKB_CB(skb);
-       tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
+
+       /* XXX: HACK! */
+       tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif;
        memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0]));
 
        /* update starting sequence number for subsequent ADDBA request */
@@ -906,8 +822,10 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
                                      struct list_head *bf_q,
                                      int txok)
 {
-       struct ath_node *an = bf->bf_node;
-       struct ath_atx_tid *tid = ATH_AN_2_TID(an, bf->bf_tidno);
+       struct ath_node *an = NULL;
+       struct sk_buff *skb;
+       struct ieee80211_tx_info *tx_info;
+       struct ath_atx_tid *tid = NULL;
        struct ath_buf *bf_last = bf->bf_lastbf;
        struct ath_desc *ds = bf_last->bf_desc;
        struct ath_buf *bf_next, *bf_lastq = NULL;
@@ -915,7 +833,14 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
        u16 seq_st = 0;
        u32 ba[WME_BA_BMP_SIZE >> 5];
        int isaggr, txfail, txpending, sendbar = 0, needreset = 0;
-       int isnodegone = (an->an_flags & ATH_NODE_CLEAN);
+
+       skb = (struct sk_buff *)bf->bf_mpdu;
+       tx_info = IEEE80211_SKB_CB(skb);
+
+       if (tx_info->control.sta) {
+               an = (struct ath_node *)tx_info->control.sta->drv_priv;
+               tid = ATH_AN_2_TID(an, bf->bf_tidno);
+       }
 
        isaggr = bf_isaggr(bf);
        if (isaggr) {
@@ -961,7 +886,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
                        /* transmit completion */
                } else {
 
-                       if (!tid->cleanup_inprogress && !isnodegone &&
+                       if (!(tid->state & AGGR_CLEANUP) &&
                            ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
                                if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
                                        ath_tx_set_retry(sc, bf);
@@ -1049,7 +974,6 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
 
                                /* copy descriptor content */
                                tbf->bf_mpdu = bf_last->bf_mpdu;
-                               tbf->bf_node = bf_last->bf_node;
                                tbf->bf_buf_addr = bf_last->bf_buf_addr;
                                *(tbf->bf_desc) = *(bf_last->bf_desc);
 
@@ -1090,25 +1014,16 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
                bf = bf_next;
        }
 
-       /*
-        * node is already gone. no more assocication
-        * with the node. the node might have been freed
-        * any  node acces can result in panic.note tid
-        * is part of the node.
-        */
-       if (isnodegone)
-               return;
-
-       if (tid->cleanup_inprogress) {
+       if (tid->state & AGGR_CLEANUP) {
                /* check to see if we're done with cleaning the h/w queue */
                spin_lock_bh(&txq->axq_lock);
 
                if (tid->baw_head == tid->baw_tail) {
-                       tid->addba_exchangecomplete = 0;
+                       tid->state &= ~AGGR_ADDBA_COMPLETE;
                        tid->addba_exchangeattempts = 0;
                        spin_unlock_bh(&txq->axq_lock);
 
-                       tid->cleanup_inprogress = false;
+                       tid->state &= ~AGGR_CLEANUP;
 
                        /* send buffered frames as singles */
                        ath_tx_flush_tid(sc, tid);
@@ -1158,7 +1073,6 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
        nacked = 0;
        for (;;) {
                spin_lock_bh(&txq->axq_lock);
-               txq->axq_intrcnt = 0; /* reset periodic desc intr count */
                if (list_empty(&txq->axq_q)) {
                        txq->axq_link = NULL;
                        txq->axq_linkbuf = NULL;
@@ -1248,8 +1162,9 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
                }
                skb = bf->bf_mpdu;
                tx_info = IEEE80211_SKB_CB(skb);
-               tx_info_priv = (struct ath_tx_info_priv *)
-                       tx_info->driver_data[0];
+
+               /* XXX: HACK! */
+               tx_info_priv = (struct ath_tx_info_priv *) tx_info->control.vif;
                if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
                        tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
                if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
@@ -1317,26 +1232,21 @@ static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq)
 static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
 {
        struct ath_hal *ah = sc->sc_ah;
-       int i;
-       int npend = 0;
+       int i, status, npend = 0;
 
-       /* XXX return value */
        if (!(sc->sc_flags & SC_OP_INVALID)) {
                for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
                        if (ATH_TXQ_SETUP(sc, i)) {
                                ath_tx_stopdma(sc, &sc->sc_txq[i]);
-
                                /* The TxDMA may not really be stopped.
                                 * Double check the hal tx pending count */
                                npend += ath9k_hw_numtxpending(ah,
-                                       sc->sc_txq[i].axq_qnum);
+                                                      sc->sc_txq[i].axq_qnum);
                        }
                }
        }
 
        if (npend) {
-               int status;
-
                /* TxDMA not stopped, reset the hal */
                DPRINTF(sc, ATH_DBG_XMIT,
                        "%s: Unable to stop TxDMA. Reset HAL!\n", __func__);
@@ -1392,7 +1302,6 @@ static void ath_tx_addto_baw(struct ath_softc *sc,
  */
 
 static int ath_tx_send_ampdu(struct ath_softc *sc,
-                            struct ath_txq *txq,
                             struct ath_atx_tid *tid,
                             struct list_head *bf_head,
                             struct ath_tx_control *txctl)
@@ -1406,8 +1315,6 @@ static int ath_tx_send_ampdu(struct ath_softc *sc,
 
        bf = list_first_entry(bf_head, struct ath_buf, list);
        bf->bf_state.bf_type |= BUF_AMPDU;
-       bf->bf_seqno = txctl->seqno; /* save seqno and tidno in buffer */
-       bf->bf_tidno = txctl->tidno;
 
        /*
         * Do not queue to h/w when any of the following conditions is true:
@@ -1418,19 +1325,20 @@ static int ath_tx_send_ampdu(struct ath_softc *sc,
         */
        if (!list_empty(&tid->buf_q) || tid->paused ||
            !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
-           txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
+           txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
                /*
                 * Add this frame to software queue for scheduling later
                 * for aggregation.
                 */
                list_splice_tail_init(bf_head, &tid->buf_q);
-               ath_tx_queue_tid(txq, tid);
+               ath_tx_queue_tid(txctl->txq, tid);
                return 0;
        }
 
        skb = (struct sk_buff *)bf->bf_mpdu;
        tx_info = IEEE80211_SKB_CB(skb);
-       tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
+       /* XXX: HACK! */
+       tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif;
        memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0]));
 
        /* Add sub-frame to BAW */
@@ -1440,7 +1348,8 @@ static int ath_tx_send_ampdu(struct ath_softc *sc,
        bf->bf_nframes = 1;
        bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */
        ath_buf_set_rate(sc, bf);
-       ath_tx_txqaddbuf(sc, txq, bf_head);
+       ath_tx_txqaddbuf(sc, txctl->txq, bf_head);
+
        return 0;
 }
 
@@ -1450,7 +1359,8 @@ static int ath_tx_send_ampdu(struct ath_softc *sc,
  */
 
 static u32 ath_lookup_rate(struct ath_softc *sc,
-                                struct ath_buf *bf)
+                          struct ath_buf *bf,
+                          struct ath_atx_tid *tid)
 {
        const struct ath9k_rate_table *rt = sc->sc_currates;
        struct sk_buff *skb;
@@ -1460,11 +1370,10 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
        u16 aggr_limit, legacy = 0, maxampdu;
        int i;
 
-
        skb = (struct sk_buff *)bf->bf_mpdu;
        tx_info = IEEE80211_SKB_CB(skb);
        tx_info_priv = (struct ath_tx_info_priv *)
-               tx_info->driver_data[0];
+               tx_info->control.vif; /* XXX: HACK! */
        memcpy(bf->bf_rcs,
                tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0]));
 
@@ -1504,7 +1413,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
         * The IE, however can hold upto 65536, which shows up here
         * as zero. Ignore 65536 since we  are constrained by hw.
         */
-       maxampdu = sc->sc_ht_info.maxampdu;
+       maxampdu = tid->an->maxampdu;
        if (maxampdu)
                aggr_limit = min(aggr_limit, maxampdu);
 
@@ -1518,6 +1427,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
  */
 
 static int ath_compute_num_delims(struct ath_softc *sc,
+                                 struct ath_atx_tid *tid,
                                  struct ath_buf *bf,
                                  u16 frmlen)
 {
@@ -1545,7 +1455,7 @@ static int ath_compute_num_delims(struct ath_softc *sc,
         * required minimum length for subframe. Take into account
         * whether high rate is 20 or 40Mhz and half or full GI.
         */
-       mpdudensity = sc->sc_ht_info.mpdudensity;
+       mpdudensity = tid->an->mpdudensity;
 
        /*
         * If there is no mpdu density restriction, no further calculation
@@ -1619,7 +1529,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
                }
 
                if (!rl) {
-                       aggr_limit = ath_lookup_rate(sc, bf);
+                       aggr_limit = ath_lookup_rate(sc, bf, tid);
                        rl = 1;
                        /*
                         * Is rate dual stream
@@ -1657,7 +1567,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
                 * Get the delimiters needed to meet the MPDU
                 * density for this node.
                 */
-               ndelim = ath_compute_num_delims(sc, bf_first, bf->bf_frmlen);
+               ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen);
 
                bpad = PADBYTES(al_delta) + (ndelim << 2);
 
@@ -1799,8 +1709,8 @@ static void ath_tx_sched_aggr(struct ath_softc *sc,
 
 static void ath_tid_drain(struct ath_softc *sc,
                          struct ath_txq *txq,
-                         struct ath_atx_tid *tid,
-                         bool bh_flag)
+                         struct ath_atx_tid *tid)
+
 {
        struct ath_buf *bf;
        struct list_head bf_head;
@@ -1821,18 +1731,12 @@ static void ath_tid_drain(struct ath_softc *sc,
                 * do not indicate packets while holding txq spinlock.
                 * unlock is intentional here
                 */
-               if (likely(bh_flag))
-                       spin_unlock_bh(&txq->axq_lock);
-               else
-                       spin_unlock(&txq->axq_lock);
+               spin_unlock(&txq->axq_lock);
 
                /* complete this sub-frame */
                ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
 
-               if (likely(bh_flag))
-                       spin_lock_bh(&txq->axq_lock);
-               else
-                       spin_lock(&txq->axq_lock);
+               spin_lock(&txq->axq_lock);
        }
 
        /*
@@ -1851,8 +1755,7 @@ static void ath_tid_drain(struct ath_softc *sc,
  */
 
 static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
-                                         struct ath_txq *txq,
-                                         bool bh_flag)
+                                         struct ath_txq *txq)
 {
        struct ath_atx_ac *ac, *ac_tmp;
        struct ath_atx_tid *tid, *tid_tmp;
@@ -1863,51 +1766,32 @@ static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
                list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) {
                        list_del(&tid->list);
                        tid->sched = false;
-                       ath_tid_drain(sc, txq, tid, bh_flag);
+                       ath_tid_drain(sc, txq, tid);
                }
        }
 }
 
-static int ath_tx_start_dma(struct ath_softc *sc,
-                           struct sk_buff *skb,
-                           struct scatterlist *sg,
-                           u32 n_sg,
-                           struct ath_tx_control *txctl)
+static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf,
+                               struct sk_buff *skb, struct scatterlist *sg,
+                               struct ath_tx_control *txctl)
 {
-       struct ath_node *an = txctl->an;
-       struct ath_buf *bf = NULL;
-       struct list_head bf_head;
-       struct ath_desc *ds;
-       struct ath_hal *ah = sc->sc_ah;
-       struct ath_txq *txq;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct ath_tx_info_priv *tx_info_priv;
        struct ath_rc_series *rcs;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct ieee80211_tx_info *tx_info =  IEEE80211_SKB_CB(skb);
-       __le16 fc = hdr->frame_control;
-
-       if (unlikely(txctl->flags & ATH9K_TXDESC_CAB))
-               txq = sc->sc_cabq;
-       else
-               txq = &sc->sc_txq[txctl->qnum];
+       int hdrlen;
+       __le16 fc;
 
-       /* For each sglist entry, allocate an ath_buf for DMA */
-       INIT_LIST_HEAD(&bf_head);
-       spin_lock_bh(&sc->sc_txbuflock);
-       if (unlikely(list_empty(&sc->sc_txbuf))) {
-               spin_unlock_bh(&sc->sc_txbuflock);
-               return -ENOMEM;
-       }
+       tx_info_priv = (struct ath_tx_info_priv *)tx_info->control.vif;
+       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+       fc = hdr->frame_control;
+       rcs = tx_info_priv->rcs;
 
-       bf = list_first_entry(&sc->sc_txbuf, struct ath_buf, list);
-       list_del(&bf->list);
-       spin_unlock_bh(&sc->sc_txbuflock);
+       ATH_TXBUF_RESET(bf);
 
-       list_add_tail(&bf->list, &bf_head);
+       /* Frame type */
 
-       /* set up this buffer */
-       ATH_TXBUF_RESET(bf);
-       bf->bf_frmlen = txctl->frmlen;
+       bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
 
        ieee80211_is_data(fc) ?
                (bf->bf_state.bf_type |= BUF_DATA) :
@@ -1921,120 +1805,142 @@ static int ath_tx_start_dma(struct ath_softc *sc,
        (sc->sc_flags & SC_OP_PREAMBLE_SHORT) ?
                (bf->bf_state.bf_type |= BUF_SHORT_PREAMBLE) :
                (bf->bf_state.bf_type &= ~BUF_SHORT_PREAMBLE);
+       (sc->hw->conf.ht.enabled &&
+        (tx_info->flags & IEEE80211_TX_CTL_AMPDU)) ?
+               (bf->bf_state.bf_type |= BUF_HT) :
+               (bf->bf_state.bf_type &= ~BUF_HT);
+
+       bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
+
+       /* Crypto */
+
+       bf->bf_keytype = get_hw_crypto_keytype(skb);
+
+       if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
+               bf->bf_frmlen += tx_info->control.hw_key->icv_len;
+               bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
+       } else {
+               bf->bf_keyix = ATH9K_TXKEYIX_INVALID;
+       }
+
+       /* Rate series */
+
+       setup_rate_retries(sc, skb);
 
-       bf->bf_flags = txctl->flags;
-       bf->bf_keytype = txctl->keytype;
-       tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
-       rcs = tx_info_priv->rcs;
        bf->bf_rcs[0] = rcs[0];
        bf->bf_rcs[1] = rcs[1];
        bf->bf_rcs[2] = rcs[2];
        bf->bf_rcs[3] = rcs[3];
-       bf->bf_node = an;
+
+       /* Assign seqno, tidno */
+
+       if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR))
+               assign_aggr_tid_seqno(skb, bf);
+
+       /* DMA setup */
+
        bf->bf_mpdu = skb;
-       bf->bf_buf_addr = sg_dma_address(sg);
+       bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data,
+                                          skb->len, PCI_DMA_TODEVICE);
+       bf->bf_buf_addr = bf->bf_dmacontext;
+}
+
+/* FIXME: tx power */
+static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
+                            struct scatterlist *sg, u32 n_sg,
+                            struct ath_tx_control *txctl)
+{
+       struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
+       struct ieee80211_tx_info *tx_info =  IEEE80211_SKB_CB(skb);
+       struct ath_node *an = NULL;
+       struct list_head bf_head;
+       struct ath_desc *ds;
+       struct ath_atx_tid *tid;
+       struct ath_hal *ah = sc->sc_ah;
+       int frm_type;
+
+       frm_type = get_hw_packet_type(skb);
+
+       INIT_LIST_HEAD(&bf_head);
+       list_add_tail(&bf->list, &bf_head);
 
        /* setup descriptor */
+
        ds = bf->bf_desc;
        ds->ds_link = 0;
        ds->ds_data = bf->bf_buf_addr;
 
-       /*
-        * Save the DMA context in the first ath_buf
-        */
-       bf->bf_dmacontext = txctl->dmacontext;
+       /* Formulate first tx descriptor with tx controls */
 
-       /*
-        * Formulate first tx descriptor with tx controls.
-        */
-       ath9k_hw_set11n_txdesc(ah,
-                              ds,
-                              bf->bf_frmlen, /* frame length */
-                              txctl->atype, /* Atheros packet type */
-                              min(txctl->txpower, (u16)60), /* txpower */
-                              txctl->keyix,            /* key cache index */
-                              txctl->keytype,          /* key type */
-                              txctl->flags);           /* flags */
-       ath9k_hw_filltxdesc(ah,
-                           ds,
-                           sg_dma_len(sg),     /* segment length */
-                           true,            /* first segment */
-                           (n_sg == 1) ? true : false, /* last segment */
-                           ds);                /* first descriptor */
+       ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
+                              bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
+
+       ath9k_hw_filltxdesc(ah, ds,
+                           sg_dma_len(sg),             /* segment length */
+                           true,                       /* first segment */
+                           (n_sg == 1) ? true : false, /* last segment */
+                           ds);                        /* first descriptor */
 
        bf->bf_lastfrm = bf;
-       (txctl->ht) ?
-               (bf->bf_state.bf_type |= BUF_HT) :
-               (bf->bf_state.bf_type &= ~BUF_HT);
 
-       spin_lock_bh(&txq->axq_lock);
+       spin_lock_bh(&txctl->txq->axq_lock);
+
+       if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) &&
+           tx_info->control.sta) {
+               an = (struct ath_node *)tx_info->control.sta->drv_priv;
+               tid = ATH_AN_2_TID(an, bf->bf_tidno);
 
-       if (txctl->ht && (sc->sc_flags & SC_OP_TXAGGR)) {
-               struct ath_atx_tid *tid = ATH_AN_2_TID(an, txctl->tidno);
-               if (ath_aggr_query(sc, an, txctl->tidno)) {
+               if (ath_aggr_query(sc, an, bf->bf_tidno)) {
                        /*
                         * Try aggregation if it's a unicast data frame
                         * and the destination is HT capable.
                         */
-                       ath_tx_send_ampdu(sc, txq, tid, &bf_head, txctl);
+                       ath_tx_send_ampdu(sc, tid, &bf_head, txctl);
                } else {
                        /*
-                        * Send this frame as regular when ADDBA exchange
-                        * is neither complete nor pending.
+                        * Send this frame as regular when ADDBA
+                        * exchange is neither complete nor pending.
                         */
-                       ath_tx_send_normal(sc, txq, tid, &bf_head);
+                       ath_tx_send_normal(sc, txctl->txq,
+                                          tid, &bf_head);
                }
        } else {
                bf->bf_lastbf = bf;
                bf->bf_nframes = 1;
-               ath_buf_set_rate(sc, bf);
-
-               if (ieee80211_is_back_req(fc)) {
-                       /* This is required for resuming tid
-                        * during BAR completion */
-                       bf->bf_tidno = txctl->tidno;
-               }
 
-               ath_tx_txqaddbuf(sc, txq, &bf_head);
+               ath_buf_set_rate(sc, bf);
+               ath_tx_txqaddbuf(sc, txctl->txq, &bf_head);
        }
-       spin_unlock_bh(&txq->axq_lock);
-       return 0;
+
+       spin_unlock_bh(&txctl->txq->axq_lock);
 }
 
-static void xmit_map_sg(struct ath_softc *sc,
-                       struct sk_buff *skb,
-                       struct ath_tx_control *txctl)
+int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
+                struct ath_tx_control *txctl)
 {
-       struct ath_xmit_status tx_status;
-       struct ath_atx_tid *tid;
+       struct ath_buf *bf;
        struct scatterlist sg;
 
-       txctl->dmacontext = pci_map_single(sc->pdev, skb->data,
-                                          skb->len, PCI_DMA_TODEVICE);
+       /* Check if a tx buffer is available */
+
+       bf = ath_tx_get_buffer(sc);
+       if (!bf) {
+               DPRINTF(sc, ATH_DBG_XMIT, "%s: TX buffers are full\n",
+                       __func__);
+               return -1;
+       }
+
+       ath_tx_setup_buffer(sc, bf, skb, &sg, txctl);
+
+       /* Setup S/G */
 
-       /* setup S/G list */
        memset(&sg, 0, sizeof(struct scatterlist));
-       sg_dma_address(&sg) = txctl->dmacontext;
+       sg_dma_address(&sg) = bf->bf_dmacontext;
        sg_dma_len(&sg) = skb->len;
 
-       if (ath_tx_start_dma(sc, skb, &sg, 1, txctl) != 0) {
-               /*
-                *  We have to do drop frame here.
-                */
-               pci_unmap_single(sc->pdev, txctl->dmacontext,
-                                skb->len, PCI_DMA_TODEVICE);
-
-               tx_status.retries = 0;
-               tx_status.flags = ATH_TX_ERROR;
+       ath_tx_start_dma(sc, bf, &sg, 1, txctl);
 
-               if (txctl->ht && (sc->sc_flags & SC_OP_TXAGGR)) {
-                       /* Reclaim the seqno. */
-                       tid = ATH_AN_2_TID((struct ath_node *)
-                               txctl->an, txctl->tidno);
-                       DECR(tid->seq_next, IEEE80211_SEQ_MAX);
-               }
-               ath_tx_complete(sc, skb, &tx_status, txctl->an);
-       }
+       return 0;
 }
 
 /* Initialize TX queue and h/w */
@@ -2151,7 +2057,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
                txq->axq_depth = 0;
                txq->axq_aggr_depth = 0;
                txq->axq_totalqueued = 0;
-               txq->axq_intrcnt = 0;
                txq->axq_linkbuf = NULL;
                sc->sc_txqsetup |= 1<<qnum;
        }
@@ -2221,6 +2126,34 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
        return qnum;
 }
 
+/* Get a transmit queue, if available */
+
+struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
+{
+       struct ath_txq *txq = NULL;
+       int qnum;
+
+       qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
+       txq = &sc->sc_txq[qnum];
+
+       spin_lock_bh(&txq->axq_lock);
+
+       /* Try to avoid running out of descriptors */
+       if (txq->axq_depth >= (ATH_TXBUF - 20)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "%s: TX queue: %d is full, depth: %d\n",
+                       __func__, qnum, txq->axq_depth);
+               ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb));
+               txq->stopped = 1;
+               spin_unlock_bh(&txq->axq_lock);
+               return NULL;
+       }
+
+       spin_unlock_bh(&txq->axq_lock);
+
+       return txq;
+}
+
 /* Update parameters for a transmit queue */
 
 int ath_txq_update(struct ath_softc *sc, int qnum,
@@ -2284,27 +2217,6 @@ int ath_cabq_update(struct ath_softc *sc)
        return 0;
 }
 
-int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb)
-{
-       struct ath_tx_control txctl;
-       int error = 0;
-
-       memset(&txctl, 0, sizeof(struct ath_tx_control));
-       error = ath_tx_prepare(sc, skb, &txctl);
-       if (error == 0)
-               /*
-                * Start DMA mapping.
-                * ath_tx_start_dma() will be called either synchronously
-                * or asynchrounsly once DMA is complete.
-                */
-               xmit_map_sg(sc, skb, &txctl);
-       else
-               ath_node_put(sc, txctl.an, ATH9K_BH_STATUS_CHANGE);
-
-       /* failed packets will be dropped by the caller */
-       return error;
-}
-
 /* Deferred processing of transmit interrupt */
 
 void ath_tx_tasklet(struct ath_softc *sc)
@@ -2378,8 +2290,7 @@ void ath_tx_draintxq(struct ath_softc *sc,
        if (sc->sc_flags & SC_OP_TXAGGR) {
                if (!retry_tx) {
                        spin_lock_bh(&txq->axq_lock);
-                       ath_txq_drain_pending_buffers(sc, txq,
-                               ATH9K_BH_STATUS_CHANGE);
+                       ath_txq_drain_pending_buffers(sc, txq);
                        spin_unlock_bh(&txq->axq_lock);
                }
        }
@@ -2410,64 +2321,39 @@ u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum)
        return sc->sc_txq[qnum].axq_aggr_depth;
 }
 
-/* Check if an ADDBA is required. A valid node must be passed. */
-enum ATH_AGGR_CHECK ath_tx_aggr_check(struct ath_softc *sc,
-                                     struct ath_node *an,
-                                     u8 tidno)
+bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
 {
        struct ath_atx_tid *txtid;
-       DECLARE_MAC_BUF(mac);
 
        if (!(sc->sc_flags & SC_OP_TXAGGR))
-               return AGGR_NOT_REQUIRED;
+               return false;
 
-       /* ADDBA exchange must be completed before sending aggregates */
        txtid = ATH_AN_2_TID(an, tidno);
 
-       if (txtid->addba_exchangecomplete)
-               return AGGR_EXCHANGE_DONE;
-
-       if (txtid->cleanup_inprogress)
-               return AGGR_CLEANUP_PROGRESS;
-
-       if (txtid->addba_exchangeinprogress)
-               return AGGR_EXCHANGE_PROGRESS;
-
-       if (!txtid->addba_exchangecomplete) {
-               if (!txtid->addba_exchangeinprogress &&
+       if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
+               if (!(txtid->state & AGGR_ADDBA_PROGRESS) &&
                    (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) {
                        txtid->addba_exchangeattempts++;
-                       return AGGR_REQUIRED;
+                       return true;
                }
        }
 
-       return AGGR_NOT_REQUIRED;
+       return false;
 }
 
 /* Start TX aggregation */
 
-int ath_tx_aggr_start(struct ath_softc *sc,
-                     const u8 *addr,
-                     u16 tid,
-                     u16 *ssn)
+int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+                     u16 tid, u16 *ssn)
 {
        struct ath_atx_tid *txtid;
        struct ath_node *an;
 
-       spin_lock_bh(&sc->node_lock);
-       an = ath_node_find(sc, (u8 *) addr);
-       spin_unlock_bh(&sc->node_lock);
-
-       if (!an) {
-               DPRINTF(sc, ATH_DBG_AGGR,
-                       "%s: Node not found to initialize "
-                       "TX aggregation\n", __func__);
-               return -1;
-       }
+       an = (struct ath_node *)sta->drv_priv;
 
        if (sc->sc_flags & SC_OP_TXAGGR) {
                txtid = ATH_AN_2_TID(an, tid);
-               txtid->addba_exchangeinprogress = 1;
+               txtid->state |= AGGR_ADDBA_PROGRESS;
                ath_tx_pause_tid(sc, txtid);
        }
 
@@ -2476,24 +2362,31 @@ int ath_tx_aggr_start(struct ath_softc *sc,
 
 /* Stop tx aggregation */
 
-int ath_tx_aggr_stop(struct ath_softc *sc,
-                    const u8 *addr,
-                    u16 tid)
+int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
 {
+       struct ath_node *an = (struct ath_node *)sta->drv_priv;
+
+       ath_tx_aggr_teardown(sc, an, tid);
+       return 0;
+}
+
+/* Resume tx aggregation */
+
+void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+{
+       struct ath_atx_tid *txtid;
        struct ath_node *an;
 
-       spin_lock_bh(&sc->node_lock);
-       an = ath_node_find(sc, (u8 *) addr);
-       spin_unlock_bh(&sc->node_lock);
+       an = (struct ath_node *)sta->drv_priv;
 
-       if (!an) {
-               DPRINTF(sc, ATH_DBG_AGGR,
-                       "%s: TX aggr stop for non-existent node\n", __func__);
-               return -1;
+       if (sc->sc_flags & SC_OP_TXAGGR) {
+               txtid = ATH_AN_2_TID(an, tid);
+               txtid->baw_size =
+                       IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
+               txtid->state |= AGGR_ADDBA_COMPLETE;
+               txtid->state &= ~AGGR_ADDBA_PROGRESS;
+               ath_tx_resume_tid(sc, txtid);
        }
-
-       ath_tx_aggr_teardown(sc, an, tid);
-       return 0;
 }
 
 /*
@@ -2503,8 +2396,7 @@ int ath_tx_aggr_stop(struct ath_softc *sc,
  * - Discard all retry frames from the s/w queue.
  */
 
-void ath_tx_aggr_teardown(struct ath_softc *sc,
-       struct ath_node *an, u8 tid)
+void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid)
 {
        struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
        struct ath_txq *txq = &sc->sc_txq[txtid->ac->qnum];
@@ -2514,10 +2406,10 @@ void ath_tx_aggr_teardown(struct ath_softc *sc,
 
        DPRINTF(sc, ATH_DBG_AGGR, "%s: teardown TX aggregation\n", __func__);
 
-       if (txtid->cleanup_inprogress) /* cleanup is in progress */
+       if (txtid->state & AGGR_CLEANUP) /* cleanup is in progress */
                return;
 
-       if (!txtid->addba_exchangecomplete) {
+       if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
                txtid->addba_exchangeattempts = 0;
                return;
        }
@@ -2547,9 +2439,9 @@ void ath_tx_aggr_teardown(struct ath_softc *sc,
 
        if (txtid->baw_head != txtid->baw_tail) {
                spin_unlock_bh(&txq->axq_lock);
-               txtid->cleanup_inprogress = true;
+               txtid->state |= AGGR_CLEANUP;
        } else {
-               txtid->addba_exchangecomplete = 0;
+               txtid->state &= ~AGGR_ADDBA_COMPLETE;
                txtid->addba_exchangeattempts = 0;
                spin_unlock_bh(&txq->axq_lock);
                ath_tx_flush_tid(sc, txtid);
@@ -2591,10 +2483,8 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
                if (tid->paused)    /* check next tid to keep h/w busy */
                        continue;
 
-               if (!(tid->an->an_smmode == ATH_SM_PWRSAV_DYNAMIC) ||
-                   ((txq->axq_depth % 2) == 0)) {
+               if ((txq->axq_depth % 2) == 0)
                        ath_tx_sched_aggr(sc, txq, tid);
-               }
 
                /*
                 * add tid to round-robin queue if more frames
@@ -2625,72 +2515,67 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
 
 void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
 {
-       if (sc->sc_flags & SC_OP_TXAGGR) {
-               struct ath_atx_tid *tid;
-               struct ath_atx_ac *ac;
-               int tidno, acno;
-
-               sc->sc_ht_info.maxampdu = ATH_AMPDU_LIMIT_DEFAULT;
+       struct ath_atx_tid *tid;
+       struct ath_atx_ac *ac;
+       int tidno, acno;
 
-               /*
-                * Init per tid tx state
-                */
-               for (tidno = 0, tid = &an->an_aggr.tx.tid[tidno];
-                               tidno < WME_NUM_TID;
-                               tidno++, tid++) {
-                       tid->an        = an;
-                       tid->tidno     = tidno;
-                       tid->seq_start = tid->seq_next = 0;
-                       tid->baw_size  = WME_MAX_BA;
-                       tid->baw_head  = tid->baw_tail = 0;
-                       tid->sched     = false;
-                       tid->paused = false;
-                       tid->cleanup_inprogress = false;
-                       INIT_LIST_HEAD(&tid->buf_q);
-
-                       acno = TID_TO_WME_AC(tidno);
-                       tid->ac = &an->an_aggr.tx.ac[acno];
-
-                       /* ADDBA state */
-                       tid->addba_exchangecomplete     = 0;
-                       tid->addba_exchangeinprogress   = 0;
-                       tid->addba_exchangeattempts     = 0;
-               }
+       /*
+        * Init per tid tx state
+        */
+       for (tidno = 0, tid = &an->an_aggr.tx.tid[tidno];
+            tidno < WME_NUM_TID;
+            tidno++, tid++) {
+               tid->an        = an;
+               tid->tidno     = tidno;
+               tid->seq_start = tid->seq_next = 0;
+               tid->baw_size  = WME_MAX_BA;
+               tid->baw_head  = tid->baw_tail = 0;
+               tid->sched     = false;
+               tid->paused = false;
+               tid->state &= ~AGGR_CLEANUP;
+               INIT_LIST_HEAD(&tid->buf_q);
+
+               acno = TID_TO_WME_AC(tidno);
+               tid->ac = &an->an_aggr.tx.ac[acno];
+
+               /* ADDBA state */
+               tid->state &= ~AGGR_ADDBA_COMPLETE;
+               tid->state &= ~AGGR_ADDBA_PROGRESS;
+               tid->addba_exchangeattempts = 0;
+       }
 
-               /*
-                * Init per ac tx state
-                */
-               for (acno = 0, ac = &an->an_aggr.tx.ac[acno];
-                               acno < WME_NUM_AC; acno++, ac++) {
-                       ac->sched    = false;
-                       INIT_LIST_HEAD(&ac->tid_q);
-
-                       switch (acno) {
-                       case WME_AC_BE:
-                               ac->qnum = ath_tx_get_qnum(sc,
-                                       ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
-                               break;
-                       case WME_AC_BK:
-                               ac->qnum = ath_tx_get_qnum(sc,
-                                       ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK);
-                               break;
-                       case WME_AC_VI:
-                               ac->qnum = ath_tx_get_qnum(sc,
-                                       ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI);
-                               break;
-                       case WME_AC_VO:
-                               ac->qnum = ath_tx_get_qnum(sc,
-                                       ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO);
-                               break;
-                       }
+       /*
+        * Init per ac tx state
+        */
+       for (acno = 0, ac = &an->an_aggr.tx.ac[acno];
+            acno < WME_NUM_AC; acno++, ac++) {
+               ac->sched    = false;
+               INIT_LIST_HEAD(&ac->tid_q);
+
+               switch (acno) {
+               case WME_AC_BE:
+                       ac->qnum = ath_tx_get_qnum(sc,
+                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
+                       break;
+               case WME_AC_BK:
+                       ac->qnum = ath_tx_get_qnum(sc,
+                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK);
+                       break;
+               case WME_AC_VI:
+                       ac->qnum = ath_tx_get_qnum(sc,
+                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI);
+                       break;
+               case WME_AC_VO:
+                       ac->qnum = ath_tx_get_qnum(sc,
+                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO);
+                       break;
                }
        }
 }
 
 /* Cleanupthe pending buffers for the node. */
 
-void ath_tx_node_cleanup(struct ath_softc *sc,
-       struct ath_node *an, bool bh_flag)
+void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
 {
        int i;
        struct ath_atx_ac *ac, *ac_tmp;
@@ -2700,10 +2585,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc,
                if (ATH_TXQ_SETUP(sc, i)) {
                        txq = &sc->sc_txq[i];
 
-                       if (likely(bh_flag))
-                               spin_lock_bh(&txq->axq_lock);
-                       else
-                               spin_lock(&txq->axq_lock);
+                       spin_lock(&txq->axq_lock);
 
                        list_for_each_entry_safe(ac,
                                        ac_tmp, &txq->axq_acq, list) {
@@ -2718,36 +2600,14 @@ void ath_tx_node_cleanup(struct ath_softc *sc,
                                                tid_tmp, &ac->tid_q, list) {
                                        list_del(&tid->list);
                                        tid->sched = false;
-                                       ath_tid_drain(sc, txq, tid, bh_flag);
-                                       tid->addba_exchangecomplete = 0;
+                                       ath_tid_drain(sc, txq, tid);
+                                       tid->state &= ~AGGR_ADDBA_COMPLETE;
                                        tid->addba_exchangeattempts = 0;
-                                       tid->cleanup_inprogress = false;
+                                       tid->state &= ~AGGR_CLEANUP;
                                }
                        }
 
-                       if (likely(bh_flag))
-                               spin_unlock_bh(&txq->axq_lock);
-                       else
-                               spin_unlock(&txq->axq_lock);
-               }
-       }
-}
-
-/* Cleanup per node transmit state */
-
-void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an)
-{
-       if (sc->sc_flags & SC_OP_TXAGGR) {
-               struct ath_atx_tid *tid;
-               int tidno, i;
-
-               /* Init per tid rx state */
-               for (tidno = 0, tid = &an->an_aggr.tx.tid[tidno];
-                       tidno < WME_NUM_TID;
-                    tidno++, tid++) {
-
-                       for (i = 0; i < ATH_TID_MAX_BUFS; i++)
-                               ASSERT(tid->tx_buf[i] == NULL);
+                       spin_unlock(&txq->axq_lock);
                }
        }
 }
@@ -2758,6 +2618,8 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb)
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ath_tx_control txctl;
 
+       memset(&txctl, 0, sizeof(struct ath_tx_control));
+
        /*
         * As a temporary workaround, assign seq# here; this will likely need
         * to be cleaned up to work better with Beacon transmission and virtual
@@ -2785,23 +2647,18 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb)
                memmove(skb->data, skb->data + padsize, hdrlen);
        }
 
+       txctl.txq = sc->sc_cabq;
+
        DPRINTF(sc, ATH_DBG_XMIT, "%s: transmitting CABQ packet, skb: %p\n",
                __func__,
                skb);
 
-       memset(&txctl, 0, sizeof(struct ath_tx_control));
-       txctl.flags = ATH9K_TXDESC_CAB;
-       if (ath_tx_prepare(sc, skb, &txctl) == 0) {
-               /*
-                * Start DMA mapping.
-                * ath_tx_start_dma() will be called either synchronously
-                * or asynchrounsly once DMA is complete.
-                */
-               xmit_map_sg(sc, skb, &txctl);
-       } else {
-               ath_node_put(sc, txctl.an, ATH9K_BH_STATUS_CHANGE);
-               DPRINTF(sc, ATH_DBG_XMIT, "%s: TX CABQ failed\n", __func__);
-               dev_kfree_skb_any(skb);
+       if (ath_tx_start(sc, skb, &txctl) != 0) {
+               DPRINTF(sc, ATH_DBG_XMIT, "%s: TX failed\n", __func__);
+               goto exit;
        }
-}
 
+       return;
+exit:
+       dev_kfree_skb_any(skb);
+}
index ecb02bdaab5be183821287d1d540a1eaad872d22..3962b553fbf1ed73de0946203f83310a8560b2c1 100644 (file)
@@ -67,7 +67,7 @@
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
 #include <linux/jiffies.h>
-#include <net/ieee80211.h>
+#include <linux/ieee80211.h>
 #include "atmel.h"
 
 #define DRIVER_MAJOR 0
@@ -569,7 +569,7 @@ static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
 static void atmel_command_irq(struct atmel_private *priv);
 static int atmel_validate_channel(struct atmel_private *priv, int channel);
 static void atmel_management_frame(struct atmel_private *priv,
-                                  struct ieee80211_hdr_4addr *header,
+                                  struct ieee80211_hdr *header,
                                   u16 frame_len, u8 rssi);
 static void atmel_management_timer(u_long a);
 static void atmel_send_command(struct atmel_private *priv, int command,
@@ -577,7 +577,7 @@ static void atmel_send_command(struct atmel_private *priv, int command,
 static int atmel_send_command_wait(struct atmel_private *priv, int command,
                                   void *cmd, int cmd_size);
 static void atmel_transmit_management_frame(struct atmel_private *priv,
-                                           struct ieee80211_hdr_4addr *header,
+                                           struct ieee80211_hdr *header,
                                            u8 *body, int body_len);
 
 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
@@ -785,7 +785,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
 {
        static const u8 SNAP_RFC1024[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
        struct atmel_private *priv = netdev_priv(dev);
-       struct ieee80211_hdr_4addr header;
+       struct ieee80211_hdr header;
        unsigned long flags;
        u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
 
@@ -823,7 +823,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
 
        frame_ctl = IEEE80211_FTYPE_DATA;
        header.duration_id = 0;
-       header.seq_ctl = 0;
+       header.seq_ctrl = 0;
        if (priv->wep_is_on)
                frame_ctl |= IEEE80211_FCTL_PROTECTED;
        if (priv->operating_mode == IW_MODE_ADHOC) {
@@ -840,7 +840,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
        if (priv->use_wpa)
                memcpy(&header.addr4, SNAP_RFC1024, 6);
 
-       header.frame_ctl = cpu_to_le16(frame_ctl);
+       header.frame_control = cpu_to_le16(frame_ctl);
        /* Copy the wireless header into the card */
        atmel_copy_to_card(dev, buff, (unsigned char *)&header, DATA_FRAME_WS_HEADER_SIZE);
        /* Copy the packet sans its 802.3 header addresses which have been replaced */
@@ -860,7 +860,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
 }
 
 static void atmel_transmit_management_frame(struct atmel_private *priv,
-                                           struct ieee80211_hdr_4addr *header,
+                                           struct ieee80211_hdr *header,
                                            u8 *body, int body_len)
 {
        u16 buff;
@@ -876,7 +876,7 @@ static void atmel_transmit_management_frame(struct atmel_private *priv,
 }
 
 static void fast_rx_path(struct atmel_private *priv,
-                        struct ieee80211_hdr_4addr *header,
+                        struct ieee80211_hdr *header,
                         u16 msdu_size, u16 rx_packet_loc, u32 crc)
 {
        /* fast path: unfragmented packet copy directly into skbuf */
@@ -914,12 +914,11 @@ static void fast_rx_path(struct atmel_private *priv,
        }
 
        memcpy(skbp, header->addr1, 6); /* destination address */
-       if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
+       if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
                memcpy(&skbp[6], header->addr3, 6);
        else
                memcpy(&skbp[6], header->addr2, 6); /* source address */
 
-       priv->dev->last_rx = jiffies;
        skb->protocol = eth_type_trans(skb, priv->dev);
        skb->ip_summed = CHECKSUM_NONE;
        netif_rx(skb);
@@ -950,7 +949,7 @@ static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
 }
 
 static void frag_rx_path(struct atmel_private *priv,
-                        struct ieee80211_hdr_4addr *header,
+                        struct ieee80211_hdr *header,
                         u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no,
                         u8 frag_no, int more_frags)
 {
@@ -958,7 +957,7 @@ static void frag_rx_path(struct atmel_private *priv,
        u8 source[6];
        struct sk_buff *skb;
 
-       if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
+       if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
                memcpy(source, header->addr3, 6);
        else
                memcpy(source, header->addr2, 6);
@@ -1026,7 +1025,6 @@ static void frag_rx_path(struct atmel_private *priv,
                                memcpy(skb_put(skb, priv->frag_len + 12),
                                       priv->rx_buf,
                                       priv->frag_len + 12);
-                               priv->dev->last_rx = jiffies;
                                skb->protocol = eth_type_trans(skb, priv->dev);
                                skb->ip_summed = CHECKSUM_NONE;
                                netif_rx(skb);
@@ -1041,7 +1039,7 @@ static void frag_rx_path(struct atmel_private *priv,
 static void rx_done_irq(struct atmel_private *priv)
 {
        int i;
-       struct ieee80211_hdr_4addr header;
+       struct ieee80211_hdr header;
 
        for (i = 0;
             atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
@@ -1068,10 +1066,10 @@ static void rx_done_irq(struct atmel_private *priv)
                        goto next;
                }
 
-               /* Get header as far as end of seq_ctl */
+               /* Get header as far as end of seq_ctrl */
                atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24);
-               frame_ctl = le16_to_cpu(header.frame_ctl);
-               seq_control = le16_to_cpu(header.seq_ctl);
+               frame_ctl = le16_to_cpu(header.frame_control);
+               seq_control = le16_to_cpu(header.seq_ctrl);
 
                /* probe for CRC use here if needed  once five packets have
                   arrived with the same crc status, we assume we know what's
@@ -1479,7 +1477,6 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
        struct net_device *dev;
        struct atmel_private *priv;
        int rc;
-       DECLARE_MAC_BUF(mac);
 
        /* Create the network device object. */
         dev = alloc_etherdev(sizeof(*priv));
@@ -1591,8 +1588,8 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
        if (!ent)
                printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
 
-       printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %s\n",
-              dev->name, DRIVER_MAJOR, DRIVER_MINOR, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n",
+              dev->name, DRIVER_MAJOR, DRIVER_MINOR, dev->dev_addr);
 
        return dev;
 
@@ -1822,7 +1819,7 @@ static int atmel_set_encodeext(struct net_device *dev,
        /* Determine and validate the key index */
        idx = encoding->flags & IW_ENCODE_INDEX;
        if (idx) {
-               if (idx < 1 || idx > WEP_KEYS)
+               if (idx < 1 || idx > 4)
                        return -EINVAL;
                idx--;
        } else
@@ -1885,7 +1882,7 @@ static int atmel_get_encodeext(struct net_device *dev,
 
        idx = encoding->flags & IW_ENCODE_INDEX;
        if (idx) {
-               if (idx < 1 || idx > WEP_KEYS)
+               if (idx < 1 || idx > 4)
                        return -EINVAL;
                idx--;
        } else
@@ -2800,7 +2797,7 @@ static void handle_beacon_probe(struct atmel_private *priv, u16 capability,
                                u8 channel)
 {
        int rejoin = 0;
-       int new = capability & MFIE_TYPE_POWER_CONSTRAINT ?
+       int new = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
                SHORT_PREAMBLE : LONG_PREAMBLE;
 
        if (priv->preamble != new) {
@@ -2829,19 +2826,19 @@ static void handle_beacon_probe(struct atmel_private *priv, u16 capability,
 static void send_authentication_request(struct atmel_private *priv, u16 system,
                                        u8 *challenge, int challenge_len)
 {
-       struct ieee80211_hdr_4addr header;
+       struct ieee80211_hdr header;
        struct auth_body auth;
 
-       header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
+       header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
        header.duration_id = cpu_to_le16(0x8000);
-       header.seq_ctl = 0;
+       header.seq_ctrl = 0;
        memcpy(header.addr1, priv->CurrentBSSID, 6);
        memcpy(header.addr2, priv->dev->dev_addr, 6);
        memcpy(header.addr3, priv->CurrentBSSID, 6);
 
        if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
                /* no WEP for authentication frames with TrSeqNo 1 */
-                header.frame_ctl |=  cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+                header.frame_control |=  cpu_to_le16(IEEE80211_FCTL_PROTECTED);
 
        auth.alg = cpu_to_le16(system);
 
@@ -2864,7 +2861,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
 {
        u8 *ssid_el_p;
        int bodysize;
-       struct ieee80211_hdr_4addr header;
+       struct ieee80211_hdr header;
        struct ass_req_format {
                __le16 capability;
                __le16 listen_interval;
@@ -2877,10 +2874,10 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
                u8 rates[4];
        } body;
 
-       header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+       header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
                (is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
        header.duration_id = cpu_to_le16(0x8000);
-       header.seq_ctl = 0;
+       header.seq_ctrl = 0;
 
        memcpy(header.addr1, priv->CurrentBSSID, 6);
        memcpy(header.addr2, priv->dev->dev_addr, 6);
@@ -2890,7 +2887,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
        if (priv->wep_is_on)
                body.capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
        if (priv->preamble == SHORT_PREAMBLE)
-               body.capability |= cpu_to_le16(MFIE_TYPE_POWER_CONSTRAINT);
+               body.capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
 
        body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
 
@@ -2904,10 +2901,10 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
                bodysize = 12 + priv->SSID_size;
        }
 
-       ssid_el_p[0] = MFIE_TYPE_SSID;
+       ssid_el_p[0] = WLAN_EID_SSID;
        ssid_el_p[1] = priv->SSID_size;
        memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
-       ssid_el_p[2 + priv->SSID_size] = MFIE_TYPE_RATES;
+       ssid_el_p[2 + priv->SSID_size] = WLAN_EID_SUPP_RATES;
        ssid_el_p[3 + priv->SSID_size] = 4; /* len of suported rates */
        memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4);
 
@@ -2915,9 +2912,9 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
 }
 
 static int is_frame_from_current_bss(struct atmel_private *priv,
-                                    struct ieee80211_hdr_4addr *header)
+                                    struct ieee80211_hdr *header)
 {
-       if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
+       if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
                return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
        else
                return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
@@ -2965,7 +2962,7 @@ static int retrieve_bss(struct atmel_private *priv)
 }
 
 static void store_bss_info(struct atmel_private *priv,
-                          struct ieee80211_hdr_4addr *header, u16 capability,
+                          struct ieee80211_hdr *header, u16 capability,
                           u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len,
                           u8 *ssid, int is_beacon)
 {
@@ -3004,7 +3001,7 @@ static void store_bss_info(struct atmel_private *priv,
        else if (capability & WLAN_CAPABILITY_ESS)
                priv->BSSinfo[index].BSStype =IW_MODE_INFRA;
 
-       priv->BSSinfo[index].preamble = capability & MFIE_TYPE_POWER_CONSTRAINT ?
+       priv->BSSinfo[index].preamble = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
                SHORT_PREAMBLE : LONG_PREAMBLE;
 }
 
@@ -3040,7 +3037,7 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
                        }
                } else if (system == WLAN_AUTH_SHARED_KEY) {
                        if (trans_seq_no == 0x0002 &&
-                           auth->el_id == MFIE_TYPE_CHALLENGE) {
+                           auth->el_id == WLAN_EID_CHALLENGE) {
                                send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
                                return;
                        } else if (trans_seq_no == 0x0004) {
@@ -3291,12 +3288,12 @@ static void atmel_smooth_qual(struct atmel_private *priv)
 
 /* deals with incoming managment frames. */
 static void atmel_management_frame(struct atmel_private *priv,
-                                  struct ieee80211_hdr_4addr *header,
+                                  struct ieee80211_hdr *header,
                                   u16 frame_len, u8 rssi)
 {
        u16 subtype;
 
-       subtype = le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_STYPE;
+       subtype = le16_to_cpu(header->frame_control) & IEEE80211_FCTL_STYPE;
        switch (subtype) {
        case IEEE80211_STYPE_BEACON:
        case IEEE80211_STYPE_PROBE_RESP:
index 427b8203e3f96af2d8367d5ef1e8b2fa0386ab4a..a53c378e74844ebdca86dd83fb3b5c9104511b27 100644 (file)
@@ -718,7 +718,6 @@ struct b43_wldev {
 
        bool bad_frames_preempt;        /* Use "Bad Frames Preemption" (default off) */
        bool dfq_valid;         /* Directed frame queue valid (IBSS PS mode, ATIM) */
-       bool short_slot;        /* TRUE, if short slot timing is enabled. */
        bool radio_hw_enable;   /* saved state of radio hardware enabled state */
        bool suspend_in_progress;       /* TRUE, if we are in a suspend/resume cycle */
 
index 098f886976f658fe636c39aa8a9f3810d227e25f..6d65a02b7052cdfa0d754a029038dcb66d96c788 100644 (file)
@@ -1387,13 +1387,11 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
 
                        info = IEEE80211_SKB_CB(meta->skb);
 
-                       memset(&info->status, 0, sizeof(info->status));
-
                        /*
                         * Call back to inform the ieee80211 subsystem about
                         * the status of the transmission.
                         */
-                       frame_succeed = b43_fill_txstatus_report(info, status);
+                       frame_succeed = b43_fill_txstatus_report(dev, info, status);
 #ifdef CONFIG_B43_DEBUG
                        if (frame_succeed)
                                ring->nr_succeed_tx_packets++;
index 14c44df584d0973a383729955d8c4089a48f5e8d..ba7a5ab7fe1d8f9c44bd5d961bff1b06a4eb8bda 100644 (file)
@@ -703,13 +703,11 @@ static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time)
 static void b43_short_slot_timing_enable(struct b43_wldev *dev)
 {
        b43_set_slot_time(dev, 9);
-       dev->short_slot = 1;
 }
 
 static void b43_short_slot_timing_disable(struct b43_wldev *dev)
 {
        b43_set_slot_time(dev, 20);
-       dev->short_slot = 0;
 }
 
 /* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
@@ -1339,25 +1337,6 @@ u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev,
        return antenna_nr;
 }
 
-static int b43_antenna_from_ieee80211(struct b43_wldev *dev, u8 antenna)
-{
-       antenna = b43_ieee80211_antenna_sanitize(dev, antenna);
-       switch (antenna) {
-       case 0:         /* default/diversity */
-               return B43_ANTENNA_DEFAULT;
-       case 1:         /* Antenna 0 */
-               return B43_ANTENNA0;
-       case 2:         /* Antenna 1 */
-               return B43_ANTENNA1;
-       case 3:         /* Antenna 2 */
-               return B43_ANTENNA2;
-       case 4:         /* Antenna 3 */
-               return B43_ANTENNA3;
-       default:
-               return B43_ANTENNA_DEFAULT;
-       }
-}
-
 /* Convert a b43 antenna number value to the PHY TX control value. */
 static u16 b43_antenna_to_phyctl(int antenna)
 {
@@ -1399,7 +1378,7 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
                                  len, ram_offset, shm_size_offset, rate);
 
        /* Write the PHY TX control parameters. */
-       antenna = b43_antenna_from_ieee80211(dev, info->antenna_sel_tx);
+       antenna = B43_ANTENNA_DEFAULT;
        antenna = b43_antenna_to_phyctl(antenna);
        ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
        /* We can't send beacons with short preamble. Would get PHY errors. */
@@ -1693,25 +1672,6 @@ static void b43_update_templates(struct b43_wl *wl)
        queue_work(wl->hw->workqueue, &wl->beacon_update_trigger);
 }
 
-static void b43_set_ssid(struct b43_wldev *dev, const u8 * ssid, u8 ssid_len)
-{
-       u32 tmp;
-       u16 i, len;
-
-       len = min((u16) ssid_len, (u16) 0x100);
-       for (i = 0; i < len; i += sizeof(u32)) {
-               tmp = (u32) (ssid[i + 0]);
-               if (i + 1 < len)
-                       tmp |= (u32) (ssid[i + 1]) << 8;
-               if (i + 2 < len)
-                       tmp |= (u32) (ssid[i + 2]) << 16;
-               if (i + 3 < len)
-                       tmp |= (u32) (ssid[i + 3]) << 24;
-               b43_shm_write32(dev, B43_SHM_SHARED, 0x380 + i, tmp);
-       }
-       b43_shm_write16(dev, B43_SHM_SHARED, 0x48, len);
-}
-
 static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
 {
        b43_time_lock(dev);
@@ -3339,11 +3299,28 @@ init_failure:
        return err;
 }
 
-static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+/* Write the short and long frame retry limit values. */
+static void b43_set_retry_limits(struct b43_wldev *dev,
+                                unsigned int short_retry,
+                                unsigned int long_retry)
+{
+       /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing
+        * the chip-internal counter. */
+       short_retry = min(short_retry, (unsigned int)0xF);
+       long_retry = min(long_retry, (unsigned int)0xF);
+
+       b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_SRLIMIT,
+                       short_retry);
+       b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_LRLIMIT,
+                       long_retry);
+}
+
+static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev;
        struct b43_phy *phy;
+       struct ieee80211_conf *conf = &hw->conf;
        unsigned long flags;
        int antenna;
        int err = 0;
@@ -3358,6 +3335,13 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
        dev = wl->current_dev;
        phy = &dev->phy;
 
+       if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
+               b43_set_retry_limits(dev, conf->short_frame_max_tx_count,
+                                         conf->long_frame_max_tx_count);
+       changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS;
+       if (!changed)
+               goto out_unlock_mutex;
+
        /* Disable IRQs while reconfiguring the device.
         * This makes it possible to drop the spinlock throughout
         * the reconfiguration process. */
@@ -3375,16 +3359,6 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
        if (conf->channel->hw_value != phy->channel)
                b43_switch_channel(dev, conf->channel->hw_value);
 
-       /* Enable/Disable ShortSlot timing. */
-       if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) !=
-           dev->short_slot) {
-               B43_WARN_ON(phy->type != B43_PHYTYPE_G);
-               if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)
-                       b43_short_slot_timing_enable(dev);
-               else
-                       b43_short_slot_timing_disable(dev);
-       }
-
        dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
 
        /* Adjust the desired TX power level. */
@@ -3399,9 +3373,9 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
        }
 
        /* Antennas for RX and management frame TX. */
-       antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_tx);
+       antenna = B43_ANTENNA_DEFAULT;
        b43_mgmtframe_txantenna(dev, antenna);
-       antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_rx);
+       antenna = B43_ANTENNA_DEFAULT;
        if (phy->ops->set_rx_antenna)
                phy->ops->set_rx_antenna(dev, antenna);
 
@@ -3435,6 +3409,104 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
        return err;
 }
 
+static void b43_update_basic_rates(struct b43_wldev *dev, u64 brates)
+{
+       struct ieee80211_supported_band *sband =
+               dev->wl->hw->wiphy->bands[b43_current_band(dev->wl)];
+       struct ieee80211_rate *rate;
+       int i;
+       u16 basic, direct, offset, basic_offset, rateptr;
+
+       for (i = 0; i < sband->n_bitrates; i++) {
+               rate = &sband->bitrates[i];
+
+               if (b43_is_cck_rate(rate->hw_value)) {
+                       direct = B43_SHM_SH_CCKDIRECT;
+                       basic = B43_SHM_SH_CCKBASIC;
+                       offset = b43_plcp_get_ratecode_cck(rate->hw_value);
+                       offset &= 0xF;
+               } else {
+                       direct = B43_SHM_SH_OFDMDIRECT;
+                       basic = B43_SHM_SH_OFDMBASIC;
+                       offset = b43_plcp_get_ratecode_ofdm(rate->hw_value);
+                       offset &= 0xF;
+               }
+
+               rate = ieee80211_get_response_rate(sband, brates, rate->bitrate);
+
+               if (b43_is_cck_rate(rate->hw_value)) {
+                       basic_offset = b43_plcp_get_ratecode_cck(rate->hw_value);
+                       basic_offset &= 0xF;
+               } else {
+                       basic_offset = b43_plcp_get_ratecode_ofdm(rate->hw_value);
+                       basic_offset &= 0xF;
+               }
+
+               /*
+                * Get the pointer that we need to point to
+                * from the direct map
+                */
+               rateptr = b43_shm_read16(dev, B43_SHM_SHARED,
+                                        direct + 2 * basic_offset);
+               /* and write it to the basic map */
+               b43_shm_write16(dev, B43_SHM_SHARED, basic + 2 * offset,
+                               rateptr);
+       }
+}
+
+static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
+                                   struct ieee80211_vif *vif,
+                                   struct ieee80211_bss_conf *conf,
+                                   u32 changed)
+{
+       struct b43_wl *wl = hw_to_b43_wl(hw);
+       struct b43_wldev *dev;
+       struct b43_phy *phy;
+       unsigned long flags;
+       u32 savedirqs;
+
+       mutex_lock(&wl->mutex);
+
+       dev = wl->current_dev;
+       phy = &dev->phy;
+
+       /* Disable IRQs while reconfiguring the device.
+        * This makes it possible to drop the spinlock throughout
+        * the reconfiguration process. */
+       spin_lock_irqsave(&wl->irq_lock, flags);
+       if (b43_status(dev) < B43_STAT_STARTED) {
+               spin_unlock_irqrestore(&wl->irq_lock, flags);
+               goto out_unlock_mutex;
+       }
+       savedirqs = b43_interrupt_disable(dev, B43_IRQ_ALL);
+       spin_unlock_irqrestore(&wl->irq_lock, flags);
+       b43_synchronize_irq(dev);
+
+       b43_mac_suspend(dev);
+
+       if (changed & BSS_CHANGED_BASIC_RATES)
+               b43_update_basic_rates(dev, conf->basic_rates);
+
+       if (changed & BSS_CHANGED_ERP_SLOT) {
+               if (conf->use_short_slot)
+                       b43_short_slot_timing_enable(dev);
+               else
+                       b43_short_slot_timing_disable(dev);
+       }
+
+       b43_mac_enable(dev);
+
+       spin_lock_irqsave(&wl->irq_lock, flags);
+       b43_interrupt_enable(dev, savedirqs);
+       /* XXX: why? */
+       mmiowb();
+       spin_unlock_irqrestore(&wl->irq_lock, flags);
+ out_unlock_mutex:
+       mutex_unlock(&wl->mutex);
+
+       return;
+}
+
 static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                           const u8 *local_addr, const u8 *addr,
                           struct ieee80211_key_conf *key)
@@ -3445,7 +3517,6 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        u8 algorithm;
        u8 index;
        int err;
-       DECLARE_MAC_BUF(mac);
 
        if (modparam_nohwcrypt)
                return -ENOSPC; /* User disabled HW-crypto */
@@ -3533,9 +3604,9 @@ out_unlock:
        mutex_unlock(&wl->mutex);
        if (!err) {
                b43dbg(wl, "%s hardware based encryption for keyidx: %d, "
-                      "mac: %s\n",
+                      "mac: %pM\n",
                       cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
-                      print_mac(mac, addr));
+                      addr);
        }
        return err;
 }
@@ -3598,8 +3669,6 @@ static int b43_op_config_interface(struct ieee80211_hw *hw,
                if (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
                    b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT)) {
                        B43_WARN_ON(vif->type != wl->if_type);
-                       if (conf->changed & IEEE80211_IFCC_SSID)
-                               b43_set_ssid(dev, conf->ssid, conf->ssid_len);
                        if (conf->changed & IEEE80211_IFCC_BEACON)
                                b43_update_templates(wl);
                } else if (b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) {
@@ -3878,22 +3947,6 @@ static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)
 #endif /* CONFIG_SSB_DRIVER_PCICORE */
 }
 
-/* Write the short and long frame retry limit values. */
-static void b43_set_retry_limits(struct b43_wldev *dev,
-                                unsigned int short_retry,
-                                unsigned int long_retry)
-{
-       /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing
-        * the chip-internal counter. */
-       short_retry = min(short_retry, (unsigned int)0xF);
-       long_retry = min(long_retry, (unsigned int)0xF);
-
-       b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_SRLIMIT,
-                       short_retry);
-       b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_LRLIMIT,
-                       long_retry);
-}
-
 static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle)
 {
        u16 pu_delay;
@@ -4214,26 +4267,6 @@ static void b43_op_stop(struct ieee80211_hw *hw)
        cancel_work_sync(&(wl->txpower_adjust_work));
 }
 
-static int b43_op_set_retry_limit(struct ieee80211_hw *hw,
-                                 u32 short_retry_limit, u32 long_retry_limit)
-{
-       struct b43_wl *wl = hw_to_b43_wl(hw);
-       struct b43_wldev *dev;
-       int err = 0;
-
-       mutex_lock(&wl->mutex);
-       dev = wl->current_dev;
-       if (unlikely(!dev || (b43_status(dev) < B43_STAT_INITIALIZED))) {
-               err = -ENODEV;
-               goto out_unlock;
-       }
-       b43_set_retry_limits(dev, short_retry_limit, long_retry_limit);
-out_unlock:
-       mutex_unlock(&wl->mutex);
-
-       return err;
-}
-
 static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
                                 struct ieee80211_sta *sta, bool set)
 {
@@ -4263,6 +4296,7 @@ static const struct ieee80211_ops b43_hw_ops = {
        .add_interface          = b43_op_add_interface,
        .remove_interface       = b43_op_remove_interface,
        .config                 = b43_op_config,
+       .bss_info_changed       = b43_op_bss_info_changed,
        .config_interface       = b43_op_config_interface,
        .configure_filter       = b43_op_configure_filter,
        .set_key                = b43_op_set_key,
@@ -4270,7 +4304,6 @@ static const struct ieee80211_ops b43_hw_ops = {
        .get_tx_stats           = b43_op_get_tx_stats,
        .start                  = b43_op_start,
        .stop                   = b43_op_stop,
-       .set_retry_limit        = b43_op_set_retry_limit,
        .set_tim                = b43_op_beacon_set_tim,
        .sta_notify             = b43_op_sta_notify,
 };
@@ -4588,7 +4621,7 @@ static int b43_wireless_init(struct ssb_device *dev)
                BIT(NL80211_IFTYPE_ADHOC);
 
        hw->queues = b43_modparam_qos ? 4 : 1;
-       hw->max_altrates = 1;
+       hw->max_rates = 2;
        SET_IEEE80211_DEV(hw, dev->dev);
        if (is_valid_ether_addr(sprom->et1mac))
                SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac);
index 4015912675922f4a5e9f8e6249885f70d364c8b1..1036bef8c4cc398e0fe72c16e09c4b43f67c45a3 100644 (file)
@@ -587,9 +587,8 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
        spin_lock(&q->lock); /* IRQs are already disabled. */
 
        info = IEEE80211_SKB_CB(pack->skb);
-       memset(&info->status, 0, sizeof(info->status));
 
-       b43_fill_txstatus_report(info, status);
+       b43_fill_txstatus_report(dev, info, status);
 
        total_len = pack->skb->len + b43_txhdr_size(dev);
        total_len = roundup(total_len, 4);
index 2fabcf8f0474253bba1dca6fb46fa7b7afd4584c..adba89b816d4885cfbdbab55b7598b929a73c7d5 100644 (file)
@@ -185,7 +185,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                       u8 *_txhdr,
                       const unsigned char *fragment_data,
                       unsigned int fragment_len,
-                      const struct ieee80211_tx_info *info,
+                      struct ieee80211_tx_info *info,
                       u16 cookie)
 {
        struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
@@ -202,6 +202,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
        u16 phy_ctl = 0;
        u8 extra_ft = 0;
        struct ieee80211_rate *txrate;
+       struct ieee80211_tx_rate *rates;
 
        memset(txhdr, 0, sizeof(*txhdr));
 
@@ -291,7 +292,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                phy_ctl |= B43_TXH_PHY_ENC_OFDM;
        else
                phy_ctl |= B43_TXH_PHY_ENC_CCK;
-       if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE)
+       if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
                phy_ctl |= B43_TXH_PHY_SHORTPRMBL;
 
        switch (b43_ieee80211_antenna_sanitize(dev, info->antenna_sel_tx)) {
@@ -314,6 +315,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                B43_WARN_ON(1);
        }
 
+       rates = info->control.rates;
        /* MAC control */
        if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
                mac_ctl |= B43_TXH_MAC_ACK;
@@ -324,12 +326,22 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                mac_ctl |= B43_TXH_MAC_STMSDU;
        if (phy->type == B43_PHYTYPE_A)
                mac_ctl |= B43_TXH_MAC_5GHZ;
-       if (info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT)
+
+       /* Overwrite rates[0].count to make the retry calculation
+        * in the tx status easier. need the actual retry limit to
+        * detect whether the fallback rate was used.
+        */
+       if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
+           (rates[0].count <= dev->wl->hw->conf.long_frame_max_tx_count)) {
+               rates[0].count = dev->wl->hw->conf.long_frame_max_tx_count;
                mac_ctl |= B43_TXH_MAC_LONGFRAME;
+       } else {
+               rates[0].count = dev->wl->hw->conf.short_frame_max_tx_count;
+       }
 
        /* Generate the RTS or CTS-to-self frame */
-       if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
-           (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) {
+       if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
+           (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) {
                unsigned int len;
                struct ieee80211_hdr *hdr;
                int rts_rate, rts_rate_fb;
@@ -344,7 +356,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                rts_rate_fb = b43_calc_fallback_rate(rts_rate);
                rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
 
-               if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
+               if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
                        struct ieee80211_cts *cts;
 
                        if (b43_is_old_txhdr_format(dev)) {
@@ -687,10 +699,18 @@ void b43_handle_txstatus(struct b43_wldev *dev,
 /* Fill out the mac80211 TXstatus report based on the b43-specific
  * txstatus report data. This returns a boolean whether the frame was
  * successfully transmitted. */
-bool b43_fill_txstatus_report(struct ieee80211_tx_info *report,
+bool b43_fill_txstatus_report(struct b43_wldev *dev,
+                             struct ieee80211_tx_info *report,
                              const struct b43_txstatus *status)
 {
        bool frame_success = 1;
+       int retry_limit;
+
+       /* preserve the confiured retry limit before clearing the status
+        * The xmit function has overwritten the rc's value with the actual
+        * retry limit done by the hardware */
+       retry_limit = report->status.rates[0].count;
+       ieee80211_tx_info_clear_status(report);
 
        if (status->acked) {
                /* The frame was ACKed. */
@@ -700,14 +720,32 @@ bool b43_fill_txstatus_report(struct ieee80211_tx_info *report,
                if (!(report->flags & IEEE80211_TX_CTL_NO_ACK)) {
                        /* ...but we expected an ACK. */
                        frame_success = 0;
-                       report->status.excessive_retries = 1;
                }
        }
        if (status->frame_count == 0) {
                /* The frame was not transmitted at all. */
-               report->status.retry_count = 0;
-       } else
-               report->status.retry_count = status->frame_count - 1;
+               report->status.rates[0].count = 0;
+       } else if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) {
+               /*
+                * If the short retries (RTS, not data frame) have exceeded
+                * the limit, the hw will not have tried the selected rate,
+                * but will have used the fallback rate instead.
+                * Don't let the rate control count attempts for the selected
+                * rate in this case, otherwise the statistics will be off.
+                */
+               report->status.rates[0].count = 0;
+               report->status.rates[1].count = status->frame_count;
+       } else {
+               if (status->frame_count > retry_limit) {
+                       report->status.rates[0].count = retry_limit;
+                       report->status.rates[1].count = status->frame_count -
+                                       retry_limit;
+
+               } else {
+                       report->status.rates[0].count = status->frame_count;
+                       report->status.rates[1].idx = -1;
+               }
+       }
 
        return frame_success;
 }
index 0215faf4754181cb6069b4878349d3d4c48e88d6..4fb2a190f7a74fc8f1a8cd9b44a27beff263281f 100644 (file)
@@ -178,7 +178,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
                       u8 * txhdr,
                       const unsigned char *fragment_data,
                       unsigned int fragment_len,
-                      const struct ieee80211_tx_info *txctl, u16 cookie);
+                      struct ieee80211_tx_info *txctl, u16 cookie);
 
 /* Transmit Status */
 struct b43_txstatus {
@@ -294,7 +294,8 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr);
 
 void b43_handle_txstatus(struct b43_wldev *dev,
                         const struct b43_txstatus *status);
-bool b43_fill_txstatus_report(struct ieee80211_tx_info *report,
+bool b43_fill_txstatus_report(struct b43_wldev *dev,
+                             struct ieee80211_tx_info *report,
                              const struct b43_txstatus *status);
 
 void b43_tx_suspend(struct b43_wldev *dev);
index fb6819e40f383442a7c73ceb254f866e1dc6eb9b..3649fc3670988219cd99185fc3acfbec6e162b3e 100644 (file)
@@ -919,7 +919,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
                        if (!ring->txhdr_cache)
                                goto err_kfree_meta;
 
-                               dma_test = ssb_dma_map_single(dev->dev,
+                       dma_test = ssb_dma_map_single(dev->dev,
                                        ring->txhdr_cache,
                                        sizeof(struct b43legacy_txhdr_fw3),
                                        DMA_TO_DEVICE);
@@ -1411,6 +1411,7 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
        struct b43legacy_dmaring *ring;
        struct b43legacy_dmadesc_generic *desc;
        struct b43legacy_dmadesc_meta *meta;
+       int retry_limit;
        int slot;
 
        ring = parse_cookie(dev, status->cookie, &slot);
@@ -1437,25 +1438,42 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev,
                        struct ieee80211_tx_info *info;
                        BUG_ON(!meta->skb);
                        info = IEEE80211_SKB_CB(meta->skb);
-                       /* Call back to inform the ieee80211 subsystem about the
-                        * status of the transmission.
-                        * Some fields of txstat are already filled in dma_tx().
-                        */
 
-                       memset(&info->status, 0, sizeof(info->status));
+                       /* preserve the confiured retry limit before clearing the status
+                        * The xmit function has overwritten the rc's value with the actual
+                        * retry limit done by the hardware */
+                       retry_limit = info->status.rates[0].count;
+                       ieee80211_tx_info_clear_status(info);
 
-                       if (status->acked) {
+                       if (status->acked)
                                info->flags |= IEEE80211_TX_STAT_ACK;
+
+                       if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) {
+                               /*
+                                * If the short retries (RTS, not data frame) have exceeded
+                                * the limit, the hw will not have tried the selected rate,
+                                * but will have used the fallback rate instead.
+                                * Don't let the rate control count attempts for the selected
+                                * rate in this case, otherwise the statistics will be off.
+                                */
+                               info->status.rates[0].count = 0;
+                               info->status.rates[1].count = status->frame_count;
                        } else {
-                               if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
-                                        info->status.excessive_retries = 1;
+                               if (status->frame_count > retry_limit) {
+                                       info->status.rates[0].count = retry_limit;
+                                       info->status.rates[1].count = status->frame_count -
+                                                       retry_limit;
+
+                               } else {
+                                       info->status.rates[0].count = status->frame_count;
+                                       info->status.rates[1].idx = -1;
+                               }
                        }
-                       if (status->frame_count == 0) {
-                               /* The frame was not transmitted at all. */
-                               info->status.retry_count = 0;
-                       } else
-                               info->status.retry_count = status->frame_count
-                                                          - 1;
+
+                       /* Call back to inform the ieee80211 subsystem about the
+                        * status of the transmission.
+                        * Some fields of txstat are already filled in dma_tx().
+                        */
                        ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb);
                        /* skb is freed by ieee80211_tx_status_irqsafe() */
                        meta->skb = NULL;
index c66d57560e7ceb97af514a8c4bc05e07f03e9971..6c8eb4d2519ad5da678bc41e0bd88ccc6074f236 100644 (file)
@@ -1160,29 +1160,6 @@ static void b43legacy_update_templates(struct b43legacy_wl *wl)
        wl->beacon1_uploaded = 0;
 }
 
-static void b43legacy_set_ssid(struct b43legacy_wldev *dev,
-                              const u8 *ssid, u8 ssid_len)
-{
-       u32 tmp;
-       u16 i;
-       u16 len;
-
-       len = min((u16)ssid_len, (u16)0x100);
-       for (i = 0; i < len; i += sizeof(u32)) {
-               tmp = (u32)(ssid[i + 0]);
-               if (i + 1 < len)
-                       tmp |= (u32)(ssid[i + 1]) << 8;
-               if (i + 2 < len)
-                       tmp |= (u32)(ssid[i + 2]) << 16;
-               if (i + 3 < len)
-                       tmp |= (u32)(ssid[i + 3]) << 24;
-               b43legacy_shm_write32(dev, B43legacy_SHM_SHARED,
-                                     0x380 + i, tmp);
-       }
-       b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
-                             0x48, len);
-}
-
 static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev,
                                     u16 beacon_int)
 {
@@ -2556,26 +2533,27 @@ init_failure:
        return err;
 }
 
-static int b43legacy_antenna_from_ieee80211(u8 antenna)
+/* Write the short and long frame retry limit values. */
+static void b43legacy_set_retry_limits(struct b43legacy_wldev *dev,
+                                      unsigned int short_retry,
+                                      unsigned int long_retry)
 {
-       switch (antenna) {
-       case 0: /* default/diversity */
-               return B43legacy_ANTENNA_DEFAULT;
-       case 1: /* Antenna 0 */
-               return B43legacy_ANTENNA0;
-       case 2: /* Antenna 1 */
-               return B43legacy_ANTENNA1;
-       default:
-               return B43legacy_ANTENNA_DEFAULT;
-       }
+       /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing
+        * the chip-internal counter. */
+       short_retry = min(short_retry, (unsigned int)0xF);
+       long_retry = min(long_retry, (unsigned int)0xF);
+
+       b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0006, short_retry);
+       b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0007, long_retry);
 }
 
 static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
-                                  struct ieee80211_conf *conf)
+                                  u32 changed)
 {
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        struct b43legacy_wldev *dev;
        struct b43legacy_phy *phy;
+       struct ieee80211_conf *conf = &hw->conf;
        unsigned long flags;
        unsigned int new_phymode = 0xFFFF;
        int antenna_tx;
@@ -2583,13 +2561,21 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
        int err = 0;
        u32 savedirqs;
 
-       antenna_tx = b43legacy_antenna_from_ieee80211(conf->antenna_sel_tx);
-       antenna_rx = b43legacy_antenna_from_ieee80211(conf->antenna_sel_rx);
+       antenna_tx = B43legacy_ANTENNA_DEFAULT;
+       antenna_rx = B43legacy_ANTENNA_DEFAULT;
 
        mutex_lock(&wl->mutex);
        dev = wl->current_dev;
        phy = &dev->phy;
 
+       if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
+               b43legacy_set_retry_limits(dev,
+                                          conf->short_frame_max_tx_count,
+                                          conf->long_frame_max_tx_count);
+       changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS;
+       if (!changed)
+               goto out_unlock_mutex;
+
        /* Switch the PHY mode (if necessary). */
        switch (conf->channel->band) {
        case IEEE80211_BAND_2GHZ:
@@ -2735,7 +2721,6 @@ static int b43legacy_op_config_interface(struct ieee80211_hw *hw,
        if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) {
                if (b43legacy_is_mode(wl, NL80211_IFTYPE_AP)) {
                        B43legacy_WARN_ON(vif->type != NL80211_IFTYPE_AP);
-                       b43legacy_set_ssid(dev, conf->ssid, conf->ssid_len);
                        if (conf->changed & IEEE80211_IFCC_BEACON)
                                b43legacy_update_templates(wl);
                } else if (b43legacy_is_mode(wl, NL80211_IFTYPE_ADHOC)) {
@@ -3002,20 +2987,6 @@ static void b43legacy_imcfglo_timeouts_workaround(struct b43legacy_wldev *dev)
 #endif /* CONFIG_SSB_DRIVER_PCICORE */
 }
 
-/* Write the short and long frame retry limit values. */
-static void b43legacy_set_retry_limits(struct b43legacy_wldev *dev,
-                                      unsigned int short_retry,
-                                      unsigned int long_retry)
-{
-       /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing
-        * the chip-internal counter. */
-       short_retry = min(short_retry, (unsigned int)0xF);
-       long_retry = min(long_retry, (unsigned int)0xF);
-
-       b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0006, short_retry);
-       b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0007, long_retry);
-}
-
 static void b43legacy_set_synth_pu_delay(struct b43legacy_wldev *dev,
                                          bool idle) {
        u16 pu_delay = 1050;
@@ -3380,28 +3351,6 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw)
        mutex_unlock(&wl->mutex);
 }
 
-static int b43legacy_op_set_retry_limit(struct ieee80211_hw *hw,
-                                       u32 short_retry_limit,
-                                       u32 long_retry_limit)
-{
-       struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
-       struct b43legacy_wldev *dev;
-       int err = 0;
-
-       mutex_lock(&wl->mutex);
-       dev = wl->current_dev;
-       if (unlikely(!dev ||
-                    (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED))) {
-               err = -ENODEV;
-               goto out_unlock;
-       }
-       b43legacy_set_retry_limits(dev, short_retry_limit, long_retry_limit);
-out_unlock:
-       mutex_unlock(&wl->mutex);
-
-       return err;
-}
-
 static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw,
                                       struct ieee80211_sta *sta, bool set)
 {
@@ -3427,7 +3376,6 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
        .get_tx_stats           = b43legacy_op_get_tx_stats,
        .start                  = b43legacy_op_start,
        .stop                   = b43legacy_op_stop,
-       .set_retry_limit        = b43legacy_op_set_retry_limit,
        .set_tim                = b43legacy_op_beacon_set_tim,
 };
 
@@ -3710,7 +3658,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
                BIT(NL80211_IFTYPE_WDS) |
                BIT(NL80211_IFTYPE_ADHOC);
        hw->queues = 1; /* FIXME: hardware has more queues */
-       hw->max_altrates = 1;
+       hw->max_rates = 2;
        SET_IEEE80211_DEV(hw, dev->dev);
        if (is_valid_ether_addr(sprom->et1mac))
                SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac);
index a86c7647fa2d62caec9027d316f3ddd648f156a6..746d5361bba017b56838c6cf5b5c54add2cd0317 100644 (file)
@@ -491,6 +491,7 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
        struct b43legacy_pioqueue *queue;
        struct b43legacy_pio_txpacket *packet;
        struct ieee80211_tx_info *info;
+       int retry_limit;
 
        queue = parse_cookie(dev, status->cookie, &packet);
        B43legacy_WARN_ON(!queue);
@@ -503,11 +504,37 @@ void b43legacy_pio_handle_txstatus(struct b43legacy_wldev *dev,
                                sizeof(struct b43legacy_txhdr_fw3));
 
        info = IEEE80211_SKB_CB(packet->skb);
-       memset(&info->status, 0, sizeof(info->status));
+
+       /* preserve the confiured retry limit before clearing the status
+        * The xmit function has overwritten the rc's value with the actual
+        * retry limit done by the hardware */
+       retry_limit = info->status.rates[0].count;
+       ieee80211_tx_info_clear_status(info);
 
        if (status->acked)
                info->flags |= IEEE80211_TX_STAT_ACK;
-       info->status.retry_count = status->frame_count - 1;
+
+       if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) {
+               /*
+                * If the short retries (RTS, not data frame) have exceeded
+                * the limit, the hw will not have tried the selected rate,
+                * but will have used the fallback rate instead.
+                * Don't let the rate control count attempts for the selected
+                * rate in this case, otherwise the statistics will be off.
+                */
+               info->status.rates[0].count = 0;
+               info->status.rates[1].count = status->frame_count;
+       } else {
+               if (status->frame_count > retry_limit) {
+                       info->status.rates[0].count = retry_limit;
+                       info->status.rates[1].count = status->frame_count -
+                                       retry_limit;
+
+               } else {
+                       info->status.rates[0].count = status->frame_count;
+                       info->status.rates[1].idx = -1;
+               }
+       }
        ieee80211_tx_status_irqsafe(dev->wl->hw, packet->skb);
        packet->skb = NULL;
 
index 65e833781608ecda0629e85dd6755dcf9104847c..12fca99f7578d28744eb8a815fac0b7a2adcddcd 100644 (file)
@@ -188,7 +188,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
                               struct b43legacy_txhdr_fw3 *txhdr,
                               const unsigned char *fragment_data,
                               unsigned int fragment_len,
-                              const struct ieee80211_tx_info *info,
+                              struct ieee80211_tx_info *info,
                               u16 cookie)
 {
        const struct ieee80211_hdr *wlhdr;
@@ -201,6 +201,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
        u32 mac_ctl = 0;
        u16 phy_ctl = 0;
        struct ieee80211_rate *tx_rate;
+       struct ieee80211_tx_rate *rates;
 
        wlhdr = (const struct ieee80211_hdr *)fragment_data;
 
@@ -274,7 +275,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
        /* PHY TX Control word */
        if (rate_ofdm)
                phy_ctl |= B43legacy_TX4_PHY_OFDM;
-       if (dev->short_preamble)
+       if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
                phy_ctl |= B43legacy_TX4_PHY_SHORTPRMBL;
        switch (info->antenna_sel_tx) {
        case 0:
@@ -291,6 +292,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
        }
 
        /* MAC control */
+       rates = info->control.rates;
        if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
                mac_ctl |= B43legacy_TX4_MAC_ACK;
        if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
@@ -299,12 +301,22 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
                mac_ctl |= B43legacy_TX4_MAC_STMSDU;
        if (rate_fb_ofdm)
                mac_ctl |= B43legacy_TX4_MAC_FALLBACKOFDM;
-       if (info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT)
+
+       /* Overwrite rates[0].count to make the retry calculation
+        * in the tx status easier. need the actual retry limit to
+        * detect whether the fallback rate was used.
+        */
+       if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
+           (rates[0].count <= dev->wl->hw->conf.long_frame_max_tx_count)) {
+               rates[0].count = dev->wl->hw->conf.long_frame_max_tx_count;
                mac_ctl |= B43legacy_TX4_MAC_LONGFRAME;
+       } else {
+               rates[0].count = dev->wl->hw->conf.short_frame_max_tx_count;
+       }
 
        /* Generate the RTS or CTS-to-self frame */
-       if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
-           (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) {
+       if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
+           (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) {
                unsigned int len;
                struct ieee80211_hdr *hdr;
                int rts_rate;
@@ -319,7 +331,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
                if (rts_rate_fb_ofdm)
                        mac_ctl |= B43legacy_TX4_MAC_CTSFALLBACKOFDM;
 
-               if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
+               if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
                        ieee80211_ctstoself_get(dev->wl->hw,
                                                info->control.vif,
                                                fragment_data,
@@ -362,7 +374,7 @@ int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
                              u8 *txhdr,
                              const unsigned char *fragment_data,
                              unsigned int fragment_len,
-                             const struct ieee80211_tx_info *info,
+                             struct ieee80211_tx_info *info,
                              u16 cookie)
 {
        return generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr,
index e56777e0feabf7f0e4552449e29daf91c8b11577..62e09d02788fb74648b13bfe324c35588ee50d87 100644 (file)
@@ -80,7 +80,7 @@ int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
                              u8 *txhdr,
                              const unsigned char *fragment_data,
                              unsigned int fragment_len,
-                             const struct ieee80211_tx_info *info,
+                             struct ieee80211_tx_info *info,
                              u16 cookie);
 
 
diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
deleted file mode 100644 (file)
index bfa3753..0000000
+++ /dev/null
@@ -1,544 +0,0 @@
-/* hermes.c
- *
- * Driver core for the "Hermes" wireless MAC controller, as used in
- * the Lucent Orinoco and Cabletron RoamAbout cards. It should also
- * work on the hfa3841 and hfa3842 MAC controller chips used in the
- * Prism II chipsets.
- *
- * This is not a complete driver, just low-level access routines for
- * the MAC controller itself.
- *
- * Based on the prism2 driver from Absolute Value Systems' linux-wlan
- * project, the Linux wvlan_cs driver, Lucent's HCF-Light
- * (wvlan_hcf.c) library, and the NetBSD wireless driver (in no
- * particular order).
- *
- * Copyright (C) 2000, David Gibson, Linuxcare Australia.
- * (C) Copyright David Gibson, IBM Corp. 2001-2003.
- * 
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in
- * which case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#include "hermes.h"
-
-MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller");
-MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>"
-       " & David Gibson <hermes@gibson.dropbear.id.au>");
-MODULE_LICENSE("Dual MPL/GPL");
-
-/* These are maximum timeouts. Most often, card wil react much faster */
-#define CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */
-#define CMD_INIT_TIMEOUT (50000) /* in iterations of ~10us */
-#define CMD_COMPL_TIMEOUT (20000) /* in iterations of ~10us */
-#define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */
-
-/*
- * Debugging helpers
- */
-
-#define DMSG(stuff...) do {printk(KERN_DEBUG "hermes @ %p: " , hw->iobase); \
-                       printk(stuff);} while (0)
-
-#undef HERMES_DEBUG
-#ifdef HERMES_DEBUG
-#include <stdarg.h>
-
-#define DEBUG(lvl, stuff...) if ( (lvl) <= HERMES_DEBUG) DMSG(stuff)
-
-#else /* ! HERMES_DEBUG */
-
-#define DEBUG(lvl, stuff...) do { } while (0)
-
-#endif /* ! HERMES_DEBUG */
-
-
-/*
- * Internal functions
- */
-
-/* Issue a command to the chip. Waiting for it to complete is the caller's
-   problem.
-
-   Returns -EBUSY if the command register is busy, 0 on success.
-
-   Callable from any context.
-*/
-static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0,
-                           u16 param1, u16 param2)
-{
-       int k = CMD_BUSY_TIMEOUT;
-       u16 reg;
-
-       /* First wait for the command register to unbusy */
-       reg = hermes_read_regn(hw, CMD);
-       while ( (reg & HERMES_CMD_BUSY) && k ) {
-               k--;
-               udelay(1);
-               reg = hermes_read_regn(hw, CMD);
-       }
-       if (reg & HERMES_CMD_BUSY) {
-               return -EBUSY;
-       }
-
-       hermes_write_regn(hw, PARAM2, param2);
-       hermes_write_regn(hw, PARAM1, param1);
-       hermes_write_regn(hw, PARAM0, param0);
-       hermes_write_regn(hw, CMD, cmd);
-       
-       return 0;
-}
-
-/*
- * Function definitions
- */
-
-/* For doing cmds that wipe the magic constant in SWSUPPORT0 */
-int hermes_doicmd_wait(hermes_t *hw, u16 cmd,
-                      u16 parm0, u16 parm1, u16 parm2,
-                      struct hermes_response *resp)
-{
-       int err = 0;
-       int k;
-       u16 status, reg;
-
-       err = hermes_issue_cmd(hw, cmd, parm0, parm1, parm2);
-       if (err)
-               return err;
-
-       reg = hermes_read_regn(hw, EVSTAT);
-       k = CMD_INIT_TIMEOUT;
-       while ((!(reg & HERMES_EV_CMD)) && k) {
-               k--;
-               udelay(10);
-               reg = hermes_read_regn(hw, EVSTAT);
-       }
-
-       hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC);
-
-       if (!hermes_present(hw)) {
-               DEBUG(0, "hermes @ 0x%x: Card removed during reset.\n",
-                      hw->iobase);
-               err = -ENODEV;
-               goto out;
-       }
-
-       if (!(reg & HERMES_EV_CMD)) {
-               printk(KERN_ERR "hermes @ %p: "
-                      "Timeout waiting for card to reset (reg=0x%04x)!\n",
-                      hw->iobase, reg);
-               err = -ETIMEDOUT;
-               goto out;
-       }
-
-       status = hermes_read_regn(hw, STATUS);
-       if (resp) {
-               resp->status = status;
-               resp->resp0 = hermes_read_regn(hw, RESP0);
-               resp->resp1 = hermes_read_regn(hw, RESP1);
-               resp->resp2 = hermes_read_regn(hw, RESP2);
-       }
-
-       hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
-
-       if (status & HERMES_STATUS_RESULT)
-               err = -EIO;
-out:
-       return err;
-}
-EXPORT_SYMBOL(hermes_doicmd_wait);
-
-void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing)
-{
-       hw->iobase = address;
-       hw->reg_spacing = reg_spacing;
-       hw->inten = 0x0;
-}
-EXPORT_SYMBOL(hermes_struct_init);
-
-int hermes_init(hermes_t *hw)
-{
-       u16 reg;
-       int err = 0;
-       int k;
-
-       /* We don't want to be interrupted while resetting the chipset */
-       hw->inten = 0x0;
-       hermes_write_regn(hw, INTEN, 0);
-       hermes_write_regn(hw, EVACK, 0xffff);
-
-       /* Normally it's a "can't happen" for the command register to
-           be busy when we go to issue a command because we are
-           serializing all commands.  However we want to have some
-           chance of resetting the card even if it gets into a stupid
-           state, so we actually wait to see if the command register
-           will unbusy itself here. */
-       k = CMD_BUSY_TIMEOUT;
-       reg = hermes_read_regn(hw, CMD);
-       while (k && (reg & HERMES_CMD_BUSY)) {
-               if (reg == 0xffff) /* Special case - the card has probably been removed,
-                                     so don't wait for the timeout */
-                       return -ENODEV;
-
-               k--;
-               udelay(1);
-               reg = hermes_read_regn(hw, CMD);
-       }
-       
-       /* No need to explicitly handle the timeout - if we've timed
-          out hermes_issue_cmd() will probably return -EBUSY below */
-
-       /* According to the documentation, EVSTAT may contain
-          obsolete event occurrence information.  We have to acknowledge
-          it by writing EVACK. */
-       reg = hermes_read_regn(hw, EVSTAT);
-       hermes_write_regn(hw, EVACK, reg);
-
-       /* We don't use hermes_docmd_wait here, because the reset wipes
-          the magic constant in SWSUPPORT0 away, and it gets confused */
-       err = hermes_doicmd_wait(hw, HERMES_CMD_INIT, 0, 0, 0, NULL);
-
-       return err;
-}
-EXPORT_SYMBOL(hermes_init);
-
-/* Issue a command to the chip, and (busy!) wait for it to
- * complete.
- *
- * Returns: < 0 on internal error, 0 on success, > 0 on error returned by the firmware
- *
- * Callable from any context, but locking is your problem. */
-int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
-                     struct hermes_response *resp)
-{
-       int err;
-       int k;
-       u16 reg;
-       u16 status;
-
-       err = hermes_issue_cmd(hw, cmd, parm0, 0, 0);
-       if (err) {
-               if (! hermes_present(hw)) {
-                       if (net_ratelimit())
-                               printk(KERN_WARNING "hermes @ %p: "
-                                      "Card removed while issuing command "
-                                      "0x%04x.\n", hw->iobase, cmd);
-                       err = -ENODEV;
-               } else 
-                       if (net_ratelimit())
-                               printk(KERN_ERR "hermes @ %p: "
-                                      "Error %d issuing command 0x%04x.\n",
-                                      hw->iobase, err, cmd);
-               goto out;
-       }
-
-       reg = hermes_read_regn(hw, EVSTAT);
-       k = CMD_COMPL_TIMEOUT;
-       while ( (! (reg & HERMES_EV_CMD)) && k) {
-               k--;
-               udelay(10);
-               reg = hermes_read_regn(hw, EVSTAT);
-       }
-
-       if (! hermes_present(hw)) {
-               printk(KERN_WARNING "hermes @ %p: Card removed "
-                      "while waiting for command 0x%04x completion.\n",
-                      hw->iobase, cmd);
-               err = -ENODEV;
-               goto out;
-       }
-               
-       if (! (reg & HERMES_EV_CMD)) {
-               printk(KERN_ERR "hermes @ %p: Timeout waiting for "
-                      "command 0x%04x completion.\n", hw->iobase, cmd);
-               err = -ETIMEDOUT;
-               goto out;
-       }
-
-       status = hermes_read_regn(hw, STATUS);
-       if (resp) {
-               resp->status = status;
-               resp->resp0 = hermes_read_regn(hw, RESP0);
-               resp->resp1 = hermes_read_regn(hw, RESP1);
-               resp->resp2 = hermes_read_regn(hw, RESP2);
-       }
-
-       hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
-
-       if (status & HERMES_STATUS_RESULT)
-               err = -EIO;
-
- out:
-       return err;
-}
-EXPORT_SYMBOL(hermes_docmd_wait);
-
-int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
-{
-       int err = 0;
-       int k;
-       u16 reg;
-       
-       if ( (size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX) )
-               return -EINVAL;
-
-       err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, NULL);
-       if (err) {
-               return err;
-       }
-
-       reg = hermes_read_regn(hw, EVSTAT);
-       k = ALLOC_COMPL_TIMEOUT;
-       while ( (! (reg & HERMES_EV_ALLOC)) && k) {
-               k--;
-               udelay(10);
-               reg = hermes_read_regn(hw, EVSTAT);
-       }
-       
-       if (! hermes_present(hw)) {
-               printk(KERN_WARNING "hermes @ %p: "
-                      "Card removed waiting for frame allocation.\n",
-                      hw->iobase);
-               return -ENODEV;
-       }
-               
-       if (! (reg & HERMES_EV_ALLOC)) {
-               printk(KERN_ERR "hermes @ %p: "
-                      "Timeout waiting for frame allocation\n",
-                      hw->iobase);
-               return -ETIMEDOUT;
-       }
-
-       *fid = hermes_read_regn(hw, ALLOCFID);
-       hermes_write_regn(hw, EVACK, HERMES_EV_ALLOC);
-       
-       return 0;
-}
-EXPORT_SYMBOL(hermes_allocate);
-
-/* Set up a BAP to read a particular chunk of data from card's internal buffer.
- *
- * Returns: < 0 on internal failure (errno), 0 on success, >0 on error
- * from firmware
- *
- * Callable from any context */
-static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
-{
-       int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
-       int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
-       int k;
-       u16 reg;
-
-       /* Paranoia.. */
-       if ( (offset > HERMES_BAP_OFFSET_MAX) || (offset % 2) )
-               return -EINVAL;
-
-       k = HERMES_BAP_BUSY_TIMEOUT;
-       reg = hermes_read_reg(hw, oreg);
-       while ((reg & HERMES_OFFSET_BUSY) && k) {
-               k--;
-               udelay(1);
-               reg = hermes_read_reg(hw, oreg);
-       }
-
-       if (reg & HERMES_OFFSET_BUSY)
-               return -ETIMEDOUT;
-
-       /* Now we actually set up the transfer */
-       hermes_write_reg(hw, sreg, id);
-       hermes_write_reg(hw, oreg, offset);
-
-       /* Wait for the BAP to be ready */
-       k = HERMES_BAP_BUSY_TIMEOUT;
-       reg = hermes_read_reg(hw, oreg);
-       while ( (reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
-               k--;
-               udelay(1);
-               reg = hermes_read_reg(hw, oreg);
-       }
-
-       if (reg != offset) {
-               printk(KERN_ERR "hermes @ %p: BAP%d offset %s: "
-                      "reg=0x%x id=0x%x offset=0x%x\n", hw->iobase, bap,
-                      (reg & HERMES_OFFSET_BUSY) ? "timeout" : "error",
-                      reg, id, offset);
-
-               if (reg & HERMES_OFFSET_BUSY) {
-                       return -ETIMEDOUT;
-               }
-
-               return -EIO;            /* error or wrong offset */
-       }
-
-       return 0;
-}
-
-/* Read a block of data from the chip's buffer, via the
- * BAP. Synchronization/serialization is the caller's problem.  len
- * must be even.
- *
- * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
- */
-int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
-                    u16 id, u16 offset)
-{
-       int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
-       int err = 0;
-
-       if ( (len < 0) || (len % 2) )
-               return -EINVAL;
-
-       err = hermes_bap_seek(hw, bap, id, offset);
-       if (err)
-               goto out;
-
-       /* Actually do the transfer */
-       hermes_read_words(hw, dreg, buf, len/2);
-
- out:
-       return err;
-}
-EXPORT_SYMBOL(hermes_bap_pread);
-
-/* Write a block of data to the chip's buffer, via the
- * BAP. Synchronization/serialization is the caller's problem.
- *
- * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
- */
-int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
-                     u16 id, u16 offset)
-{
-       int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
-       int err = 0;
-
-       if (len < 0)
-               return -EINVAL;
-
-       err = hermes_bap_seek(hw, bap, id, offset);
-       if (err)
-               goto out;
-       
-       /* Actually do the transfer */
-       hermes_write_bytes(hw, dreg, buf, len);
-
- out:  
-       return err;
-}
-EXPORT_SYMBOL(hermes_bap_pwrite);
-
-/* Read a Length-Type-Value record from the card.
- *
- * If length is NULL, we ignore the length read from the card, and
- * read the entire buffer regardless. This is useful because some of
- * the configuration records appear to have incorrect lengths in
- * practice.
- *
- * Callable from user or bh context.  */
-int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
-                   u16 *length, void *buf)
-{
-       int err = 0;
-       int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
-       u16 rlength, rtype;
-       unsigned nwords;
-
-       if ( (bufsize < 0) || (bufsize % 2) )
-               return -EINVAL;
-
-       err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, NULL);
-       if (err)
-               return err;
-
-       err = hermes_bap_seek(hw, bap, rid, 0);
-       if (err)
-               return err;
-
-       rlength = hermes_read_reg(hw, dreg);
-
-       if (! rlength)
-               return -ENODATA;
-
-       rtype = hermes_read_reg(hw, dreg);
-
-       if (length)
-               *length = rlength;
-
-       if (rtype != rid)
-               printk(KERN_WARNING "hermes @ %p: %s(): "
-                      "rid (0x%04x) does not match type (0x%04x)\n",
-                      hw->iobase, __func__, rid, rtype);
-       if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize)
-               printk(KERN_WARNING "hermes @ %p: "
-                      "Truncating LTV record from %d to %d bytes. "
-                      "(rid=0x%04x, len=0x%04x)\n", hw->iobase,
-                      HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);
-
-       nwords = min((unsigned)rlength - 1, bufsize / 2);
-       hermes_read_words(hw, dreg, buf, nwords);
-
-       return 0;
-}
-EXPORT_SYMBOL(hermes_read_ltv);
-
-int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, 
-                    u16 length, const void *value)
-{
-       int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
-       int err = 0;
-       unsigned count;
-
-       if (length == 0)
-               return -EINVAL;
-
-       err = hermes_bap_seek(hw, bap, rid, 0);
-       if (err)
-               return err;
-
-       hermes_write_reg(hw, dreg, length);
-       hermes_write_reg(hw, dreg, rid);
-
-       count = length - 1;
-
-       hermes_write_bytes(hw, dreg, value, count << 1);
-
-       err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE,
-                               rid, NULL);
-
-       return err;
-}
-EXPORT_SYMBOL(hermes_write_ltv);
-
-static int __init init_hermes(void)
-{
-       return 0;
-}
-
-static void __exit exit_hermes(void)
-{
-}
-
-module_init(init_hermes);
-module_exit(exit_hermes);
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
deleted file mode 100644 (file)
index 8b13c8f..0000000
+++ /dev/null
@@ -1,494 +0,0 @@
-/* hermes.h
- *
- * Driver core for the "Hermes" wireless MAC controller, as used in
- * the Lucent Orinoco and Cabletron RoamAbout cards. It should also
- * work on the hfa3841 and hfa3842 MAC controller chips used in the
- * Prism I & II chipsets.
- *
- * This is not a complete driver, just low-level access routines for
- * the MAC controller itself.
- *
- * Based on the prism2 driver from Absolute Value Systems' linux-wlan
- * project, the Linux wvlan_cs driver, Lucent's HCF-Light
- * (wvlan_hcf.c) library, and the NetBSD wireless driver.
- *
- * Copyright (C) 2000, David Gibson, Linuxcare Australia.
- * (C) Copyright David Gibson, IBM Corp. 2001-2003.
- *
- * Portions taken from hfa384x.h, Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
- *
- * This file distributed under the GPL, version 2.
- */
-
-#ifndef _HERMES_H
-#define _HERMES_H
-
-/* Notes on locking:
- *
- * As a module of low level hardware access routines, there is no
- * locking. Users of this module should ensure that they serialize
- * access to the hermes_t structure, and to the hardware
-*/
-
-#include <linux/if_ether.h>
-#include <asm/io.h>
-
-/*
- * Limits and constants
- */
-#define                HERMES_ALLOC_LEN_MIN            (4)
-#define                HERMES_ALLOC_LEN_MAX            (2400)
-#define                HERMES_LTV_LEN_MAX              (34)
-#define                HERMES_BAP_DATALEN_MAX          (4096)
-#define                HERMES_BAP_OFFSET_MAX           (4096)
-#define                HERMES_PORTID_MAX               (7)
-#define                HERMES_NUMPORTS_MAX             (HERMES_PORTID_MAX+1)
-#define                HERMES_PDR_LEN_MAX              (260)   /* in bytes, from EK */
-#define                HERMES_PDA_RECS_MAX             (200)   /* a guess */
-#define                HERMES_PDA_LEN_MAX              (1024)  /* in bytes, from EK */
-#define                HERMES_SCANRESULT_MAX           (35)
-#define                HERMES_CHINFORESULT_MAX         (8)
-#define                HERMES_MAX_MULTICAST            (16)
-#define                HERMES_MAGIC                    (0x7d1f)
-
-/*
- * Hermes register offsets
- */
-#define                HERMES_CMD                      (0x00)
-#define                HERMES_PARAM0                   (0x02)
-#define                HERMES_PARAM1                   (0x04)
-#define                HERMES_PARAM2                   (0x06)
-#define                HERMES_STATUS                   (0x08)
-#define                HERMES_RESP0                    (0x0A)
-#define                HERMES_RESP1                    (0x0C)
-#define                HERMES_RESP2                    (0x0E)
-#define                HERMES_INFOFID                  (0x10)
-#define                HERMES_RXFID                    (0x20)
-#define                HERMES_ALLOCFID                 (0x22)
-#define                HERMES_TXCOMPLFID               (0x24)
-#define                HERMES_SELECT0                  (0x18)
-#define                HERMES_OFFSET0                  (0x1C)
-#define                HERMES_DATA0                    (0x36)
-#define                HERMES_SELECT1                  (0x1A)
-#define                HERMES_OFFSET1                  (0x1E)
-#define                HERMES_DATA1                    (0x38)
-#define                HERMES_EVSTAT                   (0x30)
-#define                HERMES_INTEN                    (0x32)
-#define                HERMES_EVACK                    (0x34)
-#define                HERMES_CONTROL                  (0x14)
-#define                HERMES_SWSUPPORT0               (0x28)
-#define                HERMES_SWSUPPORT1               (0x2A)
-#define                HERMES_SWSUPPORT2               (0x2C)
-#define                HERMES_AUXPAGE                  (0x3A)
-#define                HERMES_AUXOFFSET                (0x3C)
-#define                HERMES_AUXDATA                  (0x3E)
-
-/*
- * CMD register bitmasks
- */
-#define                HERMES_CMD_BUSY                 (0x8000)
-#define                HERMES_CMD_AINFO                (0x7f00)
-#define                HERMES_CMD_MACPORT              (0x0700)
-#define                HERMES_CMD_RECL                 (0x0100)
-#define                HERMES_CMD_WRITE                (0x0100)
-#define                HERMES_CMD_PROGMODE             (0x0300)
-#define                HERMES_CMD_CMDCODE              (0x003f)
-
-/*
- * STATUS register bitmasks
- */
-#define                HERMES_STATUS_RESULT            (0x7f00)
-#define                HERMES_STATUS_CMDCODE           (0x003f)
-
-/*
- * OFFSET register bitmasks
- */
-#define                HERMES_OFFSET_BUSY              (0x8000)
-#define                HERMES_OFFSET_ERR               (0x4000)
-#define                HERMES_OFFSET_DATAOFF           (0x0ffe)
-
-/*
- * Event register bitmasks (INTEN, EVSTAT, EVACK)
- */
-#define                HERMES_EV_TICK                  (0x8000)
-#define                HERMES_EV_WTERR                 (0x4000)
-#define                HERMES_EV_INFDROP               (0x2000)
-#define                HERMES_EV_INFO                  (0x0080)
-#define                HERMES_EV_DTIM                  (0x0020)
-#define                HERMES_EV_CMD                   (0x0010)
-#define                HERMES_EV_ALLOC                 (0x0008)
-#define                HERMES_EV_TXEXC                 (0x0004)
-#define                HERMES_EV_TX                    (0x0002)
-#define                HERMES_EV_RX                    (0x0001)
-
-/*
- * Command codes
- */
-/*--- Controller Commands ----------------------------*/
-#define                HERMES_CMD_INIT                 (0x0000)
-#define                HERMES_CMD_ENABLE               (0x0001)
-#define                HERMES_CMD_DISABLE              (0x0002)
-#define                HERMES_CMD_DIAG                 (0x0003)
-
-/*--- Buffer Mgmt Commands ---------------------------*/
-#define                HERMES_CMD_ALLOC                (0x000A)
-#define                HERMES_CMD_TX                   (0x000B)
-
-/*--- Regulate Commands ------------------------------*/
-#define                HERMES_CMD_NOTIFY               (0x0010)
-#define                HERMES_CMD_INQUIRE              (0x0011)
-
-/*--- Configure Commands -----------------------------*/
-#define                HERMES_CMD_ACCESS               (0x0021)
-#define                HERMES_CMD_DOWNLD               (0x0022)
-
-/*--- Serial I/O Commands ----------------------------*/
-#define                HERMES_CMD_READMIF              (0x0030)
-#define                HERMES_CMD_WRITEMIF             (0x0031)
-
-/*--- Debugging Commands -----------------------------*/
-#define        HERMES_CMD_TEST                 (0x0038)
-
-
-/* Test command arguments */
-#define                HERMES_TEST_SET_CHANNEL         0x0800
-#define                HERMES_TEST_MONITOR             0x0b00
-#define                HERMES_TEST_STOP                0x0f00
-
-/* Authentication algorithms */
-#define                HERMES_AUTH_OPEN                1
-#define                HERMES_AUTH_SHARED_KEY          2
-
-/* WEP settings */
-#define                HERMES_WEP_PRIVACY_INVOKED      0x0001
-#define                HERMES_WEP_EXCL_UNENCRYPTED     0x0002
-#define                HERMES_WEP_HOST_ENCRYPT         0x0010
-#define                HERMES_WEP_HOST_DECRYPT         0x0080
-
-/* Symbol hostscan options */
-#define                HERMES_HOSTSCAN_SYMBOL_5SEC     0x0001
-#define                HERMES_HOSTSCAN_SYMBOL_ONCE     0x0002
-#define                HERMES_HOSTSCAN_SYMBOL_PASSIVE  0x0040
-#define                HERMES_HOSTSCAN_SYMBOL_BCAST    0x0080
-
-/*
- * Frame structures and constants
- */
-
-#define HERMES_DESCRIPTOR_OFFSET       0
-#define HERMES_802_11_OFFSET           (14)
-#define HERMES_802_3_OFFSET            (14+32)
-#define HERMES_802_2_OFFSET            (14+32+14)
-#define HERMES_TXCNTL2_OFFSET          (HERMES_802_3_OFFSET - 2)
-
-#define HERMES_RXSTAT_ERR              (0x0003)
-#define        HERMES_RXSTAT_BADCRC            (0x0001)
-#define        HERMES_RXSTAT_UNDECRYPTABLE     (0x0002)
-#define        HERMES_RXSTAT_MIC               (0x0010)        /* Frame contains MIC */
-#define        HERMES_RXSTAT_MACPORT           (0x0700)
-#define HERMES_RXSTAT_PCF              (0x1000)        /* Frame was received in CF period */
-#define        HERMES_RXSTAT_MIC_KEY_ID        (0x1800)        /* MIC key used */
-#define        HERMES_RXSTAT_MSGTYPE           (0xE000)
-#define        HERMES_RXSTAT_1042              (0x2000)        /* RFC-1042 frame */
-#define        HERMES_RXSTAT_TUNNEL            (0x4000)        /* bridge-tunnel encoded frame */
-#define        HERMES_RXSTAT_WMP               (0x6000)        /* Wavelan-II Management Protocol frame */
-
-/* Shift amount for key ID in RXSTAT and TXCTRL */
-#define        HERMES_MIC_KEY_ID_SHIFT         11
-
-struct hermes_tx_descriptor {
-       __le16 status;
-       __le16 reserved1;
-       __le16 reserved2;
-       __le32 sw_support;
-       u8 retry_count;
-       u8 tx_rate;
-       __le16 tx_control;      
-} __attribute__ ((packed));
-
-#define HERMES_TXSTAT_RETRYERR         (0x0001)
-#define HERMES_TXSTAT_AGEDERR          (0x0002)
-#define HERMES_TXSTAT_DISCON           (0x0004)
-#define HERMES_TXSTAT_FORMERR          (0x0008)
-
-#define HERMES_TXCTRL_TX_OK            (0x0002)        /* ?? interrupt on Tx complete */
-#define HERMES_TXCTRL_TX_EX            (0x0004)        /* ?? interrupt on Tx exception */
-#define HERMES_TXCTRL_802_11           (0x0008)        /* We supply 802.11 header */
-#define HERMES_TXCTRL_MIC              (0x0010)        /* 802.3 + TKIP */
-#define HERMES_TXCTRL_MIC_KEY_ID       (0x1800)        /* MIC Key ID mask */
-#define HERMES_TXCTRL_ALT_RTRY         (0x0020)
-
-/* Inquiry constants and data types */
-
-#define HERMES_INQ_TALLIES             (0xF100)
-#define HERMES_INQ_SCAN                        (0xF101)
-#define HERMES_INQ_CHANNELINFO         (0xF102)
-#define HERMES_INQ_HOSTSCAN            (0xF103)
-#define HERMES_INQ_HOSTSCAN_SYMBOL     (0xF104)
-#define HERMES_INQ_LINKSTATUS          (0xF200)
-#define HERMES_INQ_SEC_STAT_AGERE      (0xF202)
-
-struct hermes_tallies_frame {
-       __le16 TxUnicastFrames;
-       __le16 TxMulticastFrames;
-       __le16 TxFragments;
-       __le16 TxUnicastOctets;
-       __le16 TxMulticastOctets;
-       __le16 TxDeferredTransmissions;
-       __le16 TxSingleRetryFrames;
-       __le16 TxMultipleRetryFrames;
-       __le16 TxRetryLimitExceeded;
-       __le16 TxDiscards;
-       __le16 RxUnicastFrames;
-       __le16 RxMulticastFrames;
-       __le16 RxFragments;
-       __le16 RxUnicastOctets;
-       __le16 RxMulticastOctets;
-       __le16 RxFCSErrors;
-       __le16 RxDiscards_NoBuffer;
-       __le16 TxDiscardsWrongSA;
-       __le16 RxWEPUndecryptable;
-       __le16 RxMsgInMsgFragments;
-       __le16 RxMsgInBadMsgFragments;
-       /* Those last are probably not available in very old firmwares */
-       __le16 RxDiscards_WEPICVError;
-       __le16 RxDiscards_WEPExcluded;
-} __attribute__ ((packed));
-
-/* Grabbed from wlan-ng - Thanks Mark... - Jean II
- * This is the result of a scan inquiry command */
-/* Structure describing info about an Access Point */
-struct prism2_scan_apinfo {
-       __le16 channel;         /* Channel where the AP sits */
-       __le16 noise;           /* Noise level */
-       __le16 level;           /* Signal level */
-       u8 bssid[ETH_ALEN];     /* MAC address of the Access Point */
-       __le16 beacon_interv;   /* Beacon interval */
-       __le16 capabilities;    /* Capabilities */
-       __le16 essid_len;       /* ESSID length */
-       u8 essid[32];           /* ESSID of the network */
-       u8 rates[10];           /* Bit rate supported */
-       __le16 proberesp_rate;  /* Data rate of the response frame */
-       __le16 atim;            /* ATIM window time, Kus (hostscan only) */
-} __attribute__ ((packed));
-
-/* Same stuff for the Lucent/Agere card.
- * Thanks to h1kari <h1kari AT dachb0den.com> - Jean II */
-struct agere_scan_apinfo {
-       __le16 channel;         /* Channel where the AP sits */
-       __le16 noise;           /* Noise level */
-       __le16 level;           /* Signal level */
-       u8 bssid[ETH_ALEN];     /* MAC address of the Access Point */
-       __le16 beacon_interv;   /* Beacon interval */
-       __le16 capabilities;    /* Capabilities */
-       /* bits: 0-ess, 1-ibss, 4-privacy [wep] */
-       __le16 essid_len;       /* ESSID length */
-       u8 essid[32];           /* ESSID of the network */
-} __attribute__ ((packed));
-
-/* Moustafa: Scan structure for Symbol cards */
-struct symbol_scan_apinfo {
-       u8 channel;             /* Channel where the AP sits */
-       u8 unknown1;            /* 8 in 2.9x and 3.9x f/w, 0 otherwise */
-       __le16 noise;           /* Noise level */
-       __le16 level;           /* Signal level */
-       u8 bssid[ETH_ALEN];     /* MAC address of the Access Point */
-       __le16 beacon_interv;   /* Beacon interval */
-       __le16 capabilities;    /* Capabilities */
-       /* bits: 0-ess, 1-ibss, 4-privacy [wep] */
-       __le16 essid_len;       /* ESSID length */
-       u8 essid[32];           /* ESSID of the network */
-       __le16 rates[5];        /* Bit rate supported */
-       __le16 basic_rates;     /* Basic rates bitmask */
-       u8 unknown2[6];         /* Always FF:FF:FF:FF:00:00 */
-       u8 unknown3[8];         /* Always 0, appeared in f/w 3.91-68 */
-} __attribute__ ((packed));
-
-union hermes_scan_info {
-       struct agere_scan_apinfo        a;
-       struct prism2_scan_apinfo       p;
-       struct symbol_scan_apinfo       s;
-};
-
-/* Extended scan struct for HERMES_INQ_CHANNELINFO.
- * wl_lkm calls this an ACS scan (Automatic Channel Select).
- * Keep out of union hermes_scan_info because it is much bigger than
- * the older scan structures. */
-struct agere_ext_scan_info {
-       __le16  reserved0;
-
-       u8      noise;
-       u8      level;
-       u8      rx_flow;
-       u8      rate;
-       __le16  reserved1[2];
-
-       __le16  frame_control;
-       __le16  dur_id;
-       u8      addr1[ETH_ALEN];
-       u8      addr2[ETH_ALEN];
-       u8      bssid[ETH_ALEN];
-       __le16  sequence;
-       u8      addr4[ETH_ALEN];
-
-       __le16  data_length;
-
-       /* Next 3 fields do not get filled in. */
-       u8      daddr[ETH_ALEN];
-       u8      saddr[ETH_ALEN];
-       __le16  len_type;
-
-       __le64  timestamp;
-       __le16  beacon_interval;
-       __le16  capabilities;
-       u8      data[316];
-} __attribute__ ((packed));
-
-#define HERMES_LINKSTATUS_NOT_CONNECTED   (0x0000)  
-#define HERMES_LINKSTATUS_CONNECTED       (0x0001)
-#define HERMES_LINKSTATUS_DISCONNECTED    (0x0002)
-#define HERMES_LINKSTATUS_AP_CHANGE       (0x0003)
-#define HERMES_LINKSTATUS_AP_OUT_OF_RANGE (0x0004)
-#define HERMES_LINKSTATUS_AP_IN_RANGE     (0x0005)
-#define HERMES_LINKSTATUS_ASSOC_FAILED    (0x0006)
-  
-struct hermes_linkstatus {
-       __le16 linkstatus;         /* Link status */
-} __attribute__ ((packed));
-
-struct hermes_response {
-       u16 status, resp0, resp1, resp2;
-};
-
-/* "ID" structure - used for ESSID and station nickname */
-struct hermes_idstring {
-       __le16 len;
-       __le16 val[16];
-} __attribute__ ((packed));
-
-struct hermes_multicast {
-       u8 addr[HERMES_MAX_MULTICAST][ETH_ALEN];
-} __attribute__ ((packed));
-
-/* Timeouts */
-#define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */
-
-/* Basic control structure */
-typedef struct hermes {
-       void __iomem *iobase;
-       int reg_spacing;
-#define HERMES_16BIT_REGSPACING        0
-#define HERMES_32BIT_REGSPACING        1
-       u16 inten; /* Which interrupts should be enabled? */
-} hermes_t;
-
-/* Register access convenience macros */
-#define hermes_read_reg(hw, off) \
-       (ioread16((hw)->iobase + ( (off) << (hw)->reg_spacing )))
-#define hermes_write_reg(hw, off, val) \
-       (iowrite16((val), (hw)->iobase + ((off) << (hw)->reg_spacing)))
-#define hermes_read_regn(hw, name) hermes_read_reg((hw), HERMES_##name)
-#define hermes_write_regn(hw, name, val) hermes_write_reg((hw), HERMES_##name, (val))
-
-/* Function prototypes */
-void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing);
-int hermes_init(hermes_t *hw);
-int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
-                     struct hermes_response *resp);
-int hermes_doicmd_wait(hermes_t *hw, u16 cmd,
-                      u16 parm0, u16 parm1, u16 parm2,
-                      struct hermes_response *resp);
-int hermes_allocate(hermes_t *hw, u16 size, u16 *fid);
-
-int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
-                      u16 id, u16 offset);
-int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
-                       u16 id, u16 offset);
-int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen,
-                   u16 *length, void *buf);
-int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
-                     u16 length, const void *value);
-
-/* Inline functions */
-
-static inline int hermes_present(hermes_t *hw)
-{
-       return hermes_read_regn(hw, SWSUPPORT0) == HERMES_MAGIC;
-}
-
-static inline void hermes_set_irqmask(hermes_t *hw, u16 events)
-{
-       hw->inten = events;
-       hermes_write_regn(hw, INTEN, events);
-}
-
-static inline int hermes_enable_port(hermes_t *hw, int port)
-{
-       return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8),
-                                0, NULL);
-}
-
-static inline int hermes_disable_port(hermes_t *hw, int port)
-{
-       return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8), 
-                                0, NULL);
-}
-
-/* Initiate an INQUIRE command (tallies or scan).  The result will come as an
- * information frame in __orinoco_ev_info() */
-static inline int hermes_inquire(hermes_t *hw, u16 rid)
-{
-       return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL);
-}
-
-#define HERMES_BYTES_TO_RECLEN(n) ( (((n)+1)/2) + 1 )
-#define HERMES_RECLEN_TO_BYTES(n) ( ((n)-1) * 2 )
-
-/* Note that for the next two, the count is in 16-bit words, not bytes */
-static inline void hermes_read_words(struct hermes *hw, int off, void *buf, unsigned count)
-{
-       off = off << hw->reg_spacing;
-       ioread16_rep(hw->iobase + off, buf, count);
-}
-
-static inline void hermes_write_bytes(struct hermes *hw, int off,
-                                     const char *buf, unsigned count)
-{
-       off = off << hw->reg_spacing;
-       iowrite16_rep(hw->iobase + off, buf, count >> 1);
-       if (unlikely(count & 1))
-               iowrite8(buf[count - 1], hw->iobase + off);
-}
-
-static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count)
-{
-       unsigned i;
-
-       off = off << hw->reg_spacing;
-
-       for (i = 0; i < count; i++)
-               iowrite16(0, hw->iobase + off);
-}
-
-#define HERMES_READ_RECORD(hw, bap, rid, buf) \
-       (hermes_read_ltv((hw),(bap),(rid), sizeof(*buf), NULL, (buf)))
-#define HERMES_WRITE_RECORD(hw, bap, rid, buf) \
-       (hermes_write_ltv((hw),(bap),(rid),HERMES_BYTES_TO_RECLEN(sizeof(*buf)),(buf)))
-
-static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
-{
-       __le16 rec;
-       int err;
-
-       err = HERMES_READ_RECORD(hw, bap, rid, &rec);
-       *word = le16_to_cpu(rec);
-       return err;
-}
-
-static inline int hermes_write_wordrec(hermes_t *hw, int bap, u16 rid, u16 word)
-{
-       __le16 rec = cpu_to_le16(word);
-       return HERMES_WRITE_RECORD(hw, bap, rid, &rec);
-}
-
-#endif  /* _HERMES_H */
diff --git a/drivers/net/wireless/hermes_dld.c b/drivers/net/wireless/hermes_dld.c
deleted file mode 100644 (file)
index d8c626e..0000000
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * Hermes download helper driver.
- *
- * This could be entirely merged into hermes.c.
- *
- * I'm keeping it separate to minimise the amount of merging between
- * kernel upgrades. It also means the memory overhead for drivers that
- * don't need firmware download low.
- *
- * This driver:
- *  - is capable of writing to the volatile area of the hermes device
- *  - is currently not capable of writing to non-volatile areas
- *  - provide helpers to identify and update plugin data
- *  - is not capable of interpreting a fw image directly. That is up to
- *    the main card driver.
- *  - deals with Hermes I devices. It can probably be modified to deal
- *    with Hermes II devices
- *
- * Copyright (C) 2007, David Kilroy
- *
- * Plug data code slightly modified from spectrum_cs driver
- *    Copyright (C) 2002-2005 Pavel Roskin <proski@gnu.org>
- * Portions based on information in wl_lkm_718 Agere driver
- *    COPYRIGHT (C) 2001-2004 by Agere Systems Inc. All Rights Reserved
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in
- * which case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include "hermes.h"
-#include "hermes_dld.h"
-
-MODULE_DESCRIPTION("Download helper for Lucent Hermes chipset");
-MODULE_AUTHOR("David Kilroy <kilroyd@gmail.com>");
-MODULE_LICENSE("Dual MPL/GPL");
-
-#define PFX "hermes_dld: "
-
-/*
- * AUX port access.  To unlock the AUX port write the access keys to the
- * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL
- * register.  Then read it and make sure it's HERMES_AUX_ENABLED.
- */
-#define HERMES_AUX_ENABLE      0x8000  /* Enable auxiliary port access */
-#define HERMES_AUX_DISABLE     0x4000  /* Disable to auxiliary port access */
-#define HERMES_AUX_ENABLED     0xC000  /* Auxiliary port is open */
-#define HERMES_AUX_DISABLED    0x0000  /* Auxiliary port is closed */
-
-#define HERMES_AUX_PW0 0xFE01
-#define HERMES_AUX_PW1 0xDC23
-#define HERMES_AUX_PW2 0xBA45
-
-/* HERMES_CMD_DOWNLD */
-#define HERMES_PROGRAM_DISABLE             (0x0000 | HERMES_CMD_DOWNLD)
-#define HERMES_PROGRAM_ENABLE_VOLATILE     (0x0100 | HERMES_CMD_DOWNLD)
-#define HERMES_PROGRAM_ENABLE_NON_VOLATILE (0x0200 | HERMES_CMD_DOWNLD)
-#define HERMES_PROGRAM_NON_VOLATILE        (0x0300 | HERMES_CMD_DOWNLD)
-
-/* End markers used in dblocks */
-#define PDI_END                0x00000000      /* End of PDA */
-#define BLOCK_END      0xFFFFFFFF      /* Last image block */
-#define TEXT_END       0x1A            /* End of text header */
-
-/*
- * PDA == Production Data Area
- *
- * In principle, the max. size of the PDA is is 4096 words. Currently,
- * however, only about 500 bytes of this area are used.
- *
- * Some USB implementations can't handle sizes in excess of 1016. Note
- * that PDA is not actually used in those USB environments, but may be
- * retrieved by common code.
- */
-#define MAX_PDA_SIZE   1000
-
-/* Limit the amout we try to download in a single shot.
- * Size is in bytes.
- */
-#define MAX_DL_SIZE 1024
-#define LIMIT_PROGRAM_SIZE 0
-
-/*
- * The following structures have little-endian fields denoted by
- * the leading underscore.  Don't access them directly - use inline
- * functions defined below.
- */
-
-/*
- * The binary image to be downloaded consists of series of data blocks.
- * Each block has the following structure.
- */
-struct dblock {
-       __le32 addr;            /* adapter address where to write the block */
-       __le16 len;             /* length of the data only, in bytes */
-       char data[0];           /* data to be written */
-} __attribute__ ((packed));
-
-/*
- * Plug Data References are located in in the image after the last data
- * block.  They refer to areas in the adapter memory where the plug data
- * items with matching ID should be written.
- */
-struct pdr {
-       __le32 id;              /* record ID */
-       __le32 addr;            /* adapter address where to write the data */
-       __le32 len;             /* expected length of the data, in bytes */
-       char next[0];           /* next PDR starts here */
-} __attribute__ ((packed));
-
-/*
- * Plug Data Items are located in the EEPROM read from the adapter by
- * primary firmware.  They refer to the device-specific data that should
- * be plugged into the secondary firmware.
- */
-struct pdi {
-       __le16 len;             /* length of ID and data, in words */
-       __le16 id;              /* record ID */
-       char data[0];           /* plug data */
-} __attribute__ ((packed));
-
-/*** FW data block access functions ***/
-
-static inline u32
-dblock_addr(const struct dblock *blk)
-{
-       return le32_to_cpu(blk->addr);
-}
-
-static inline u32
-dblock_len(const struct dblock *blk)
-{
-       return le16_to_cpu(blk->len);
-}
-
-/*** PDR Access functions ***/
-
-static inline u32
-pdr_id(const struct pdr *pdr)
-{
-       return le32_to_cpu(pdr->id);
-}
-
-static inline u32
-pdr_addr(const struct pdr *pdr)
-{
-       return le32_to_cpu(pdr->addr);
-}
-
-static inline u32
-pdr_len(const struct pdr *pdr)
-{
-       return le32_to_cpu(pdr->len);
-}
-
-/*** PDI Access functions ***/
-
-static inline u32
-pdi_id(const struct pdi *pdi)
-{
-       return le16_to_cpu(pdi->id);
-}
-
-/* Return length of the data only, in bytes */
-static inline u32
-pdi_len(const struct pdi *pdi)
-{
-       return 2 * (le16_to_cpu(pdi->len) - 1);
-}
-
-/*** Hermes AUX control ***/
-
-static inline void
-hermes_aux_setaddr(hermes_t *hw, u32 addr)
-{
-       hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7));
-       hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F));
-}
-
-static inline int
-hermes_aux_control(hermes_t *hw, int enabled)
-{
-       int desired_state = enabled ? HERMES_AUX_ENABLED : HERMES_AUX_DISABLED;
-       int action = enabled ? HERMES_AUX_ENABLE : HERMES_AUX_DISABLE;
-       int i;
-
-       /* Already open? */
-       if (hermes_read_reg(hw, HERMES_CONTROL) == desired_state)
-               return 0;
-
-       hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0);
-       hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1);
-       hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2);
-       hermes_write_reg(hw, HERMES_CONTROL, action);
-
-       for (i = 0; i < 20; i++) {
-               udelay(10);
-               if (hermes_read_reg(hw, HERMES_CONTROL) ==
-                   desired_state)
-                       return 0;
-       }
-
-       return -EBUSY;
-}
-
-/*** Plug Data Functions ***/
-
-/*
- * Scan PDR for the record with the specified RECORD_ID.
- * If it's not found, return NULL.
- */
-static struct pdr *
-hermes_find_pdr(struct pdr *first_pdr, u32 record_id)
-{
-       struct pdr *pdr = first_pdr;
-       void *end = (void *)first_pdr + MAX_PDA_SIZE;
-
-       while (((void *)pdr < end) &&
-              (pdr_id(pdr) != PDI_END)) {
-               /*
-                * PDR area is currently not terminated by PDI_END.
-                * It's followed by CRC records, which have the type
-                * field where PDR has length.  The type can be 0 or 1.
-                */
-               if (pdr_len(pdr) < 2)
-                       return NULL;
-
-               /* If the record ID matches, we are done */
-               if (pdr_id(pdr) == record_id)
-                       return pdr;
-
-               pdr = (struct pdr *) pdr->next;
-       }
-       return NULL;
-}
-
-/* Scan production data items for a particular entry */
-static struct pdi *
-hermes_find_pdi(struct pdi *first_pdi, u32 record_id)
-{
-       struct pdi *pdi = first_pdi;
-
-       while (pdi_id(pdi) != PDI_END) {
-
-               /* If the record ID matches, we are done */
-               if (pdi_id(pdi) == record_id)
-                       return pdi;
-
-               pdi = (struct pdi *) &pdi->data[pdi_len(pdi)];
-       }
-       return NULL;
-}
-
-/* Process one Plug Data Item - find corresponding PDR and plug it */
-static int
-hermes_plug_pdi(hermes_t *hw, struct pdr *first_pdr, const struct pdi *pdi)
-{
-       struct pdr *pdr;
-
-       /* Find the PDR corresponding to this PDI */
-       pdr = hermes_find_pdr(first_pdr, pdi_id(pdi));
-
-       /* No match is found, safe to ignore */
-       if (!pdr)
-               return 0;
-
-       /* Lengths of the data in PDI and PDR must match */
-       if (pdi_len(pdi) != pdr_len(pdr))
-               return -EINVAL;
-
-       /* do the actual plugging */
-       hermes_aux_setaddr(hw, pdr_addr(pdr));
-       hermes_write_bytes(hw, HERMES_AUXDATA, pdi->data, pdi_len(pdi));
-
-       return 0;
-}
-
-/* Read PDA from the adapter */
-int hermes_read_pda(hermes_t *hw,
-                   __le16 *pda,
-                   u32 pda_addr,
-                   u16 pda_len,
-                   int use_eeprom) /* can we get this into hw? */
-{
-       int ret;
-       u16 pda_size;
-       u16 data_len = pda_len;
-       __le16 *data = pda;
-
-       if (use_eeprom) {
-               /* PDA of spectrum symbol is in eeprom */
-
-               /* Issue command to read EEPROM */
-               ret = hermes_docmd_wait(hw, HERMES_CMD_READMIF, 0, NULL);
-               if (ret)
-                       return ret;
-       } else {
-               /* wl_lkm does not include PDA size in the PDA area.
-                * We will pad the information into pda, so other routines
-                * don't have to be modified */
-               pda[0] = cpu_to_le16(pda_len - 2);
-                       /* Includes CFG_PROD_DATA but not itself */
-               pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */
-               data_len = pda_len - 4;
-               data = pda + 2;
-       }
-
-       /* Open auxiliary port */
-       ret = hermes_aux_control(hw, 1);
-       printk(KERN_DEBUG PFX "AUX enable returned %d\n", ret);
-       if (ret)
-               return ret;
-
-       /* read PDA from EEPROM */
-       hermes_aux_setaddr(hw, pda_addr);
-       hermes_read_words(hw, HERMES_AUXDATA, data, data_len / 2);
-
-       /* Close aux port */
-       ret = hermes_aux_control(hw, 0);
-       printk(KERN_DEBUG PFX "AUX disable returned %d\n", ret);
-
-       /* Check PDA length */
-       pda_size = le16_to_cpu(pda[0]);
-       printk(KERN_DEBUG PFX "Actual PDA length %d, Max allowed %d\n",
-              pda_size, pda_len);
-       if (pda_size > pda_len)
-               return -EINVAL;
-
-       return 0;
-}
-EXPORT_SYMBOL(hermes_read_pda);
-
-/* Parse PDA and write the records into the adapter
- *
- * Attempt to write every records that is in the specified pda
- * which also has a valid production data record for the firmware.
- */
-int hermes_apply_pda(hermes_t *hw,
-                    const char *first_pdr,
-                    const __le16 *pda)
-{
-       int ret;
-       const struct pdi *pdi;
-       struct pdr *pdr;
-
-       pdr = (struct pdr *) first_pdr;
-
-       /* Go through every PDI and plug them into the adapter */
-       pdi = (const struct pdi *) (pda + 2);
-       while (pdi_id(pdi) != PDI_END) {
-               ret = hermes_plug_pdi(hw, pdr, pdi);
-               if (ret)
-                       return ret;
-
-               /* Increment to the next PDI */
-               pdi = (const struct pdi *) &pdi->data[pdi_len(pdi)];
-       }
-       return 0;
-}
-EXPORT_SYMBOL(hermes_apply_pda);
-
-/* Identify the total number of bytes in all blocks
- * including the header data.
- */
-size_t
-hermes_blocks_length(const char *first_block)
-{
-       const struct dblock *blk = (const struct dblock *) first_block;
-       int total_len = 0;
-       int len;
-
-       /* Skip all blocks to locate Plug Data References
-        * (Spectrum CS) */
-       while (dblock_addr(blk) != BLOCK_END) {
-               len = dblock_len(blk);
-               total_len += sizeof(*blk) + len;
-               blk = (struct dblock *) &blk->data[len];
-       }
-
-       return total_len;
-}
-EXPORT_SYMBOL(hermes_blocks_length);
-
-/*** Hermes programming ***/
-
-/* About to start programming data (Hermes I)
- * offset is the entry point
- *
- * Spectrum_cs' Symbol fw does not require this
- * wl_lkm Agere fw does
- * Don't know about intersil
- */
-int hermesi_program_init(hermes_t *hw, u32 offset)
-{
-       int err;
-
-       /* Disable interrupts?*/
-       /*hw->inten = 0x0;*/
-       /*hermes_write_regn(hw, INTEN, 0);*/
-       /*hermes_set_irqmask(hw, 0);*/
-
-       /* Acknowledge any outstanding command */
-       hermes_write_regn(hw, EVACK, 0xFFFF);
-
-       /* Using doicmd_wait rather than docmd_wait */
-       err = hermes_doicmd_wait(hw,
-                                0x0100 | HERMES_CMD_INIT,
-                                0, 0, 0, NULL);
-       if (err)
-               return err;
-
-       err = hermes_doicmd_wait(hw,
-                                0x0000 | HERMES_CMD_INIT,
-                                0, 0, 0, NULL);
-       if (err)
-               return err;
-
-       err = hermes_aux_control(hw, 1);
-       printk(KERN_DEBUG PFX "AUX enable returned %d\n", err);
-
-       if (err)
-               return err;
-
-       printk(KERN_DEBUG PFX "Enabling volatile, EP 0x%08x\n", offset);
-       err = hermes_doicmd_wait(hw,
-                                HERMES_PROGRAM_ENABLE_VOLATILE,
-                                offset & 0xFFFFu,
-                                offset >> 16,
-                                0,
-                                NULL);
-       printk(KERN_DEBUG PFX "PROGRAM_ENABLE returned %d\n",
-              err);
-
-       return err;
-}
-EXPORT_SYMBOL(hermesi_program_init);
-
-/* Done programming data (Hermes I)
- *
- * Spectrum_cs' Symbol fw does not require this
- * wl_lkm Agere fw does
- * Don't know about intersil
- */
-int hermesi_program_end(hermes_t *hw)
-{
-       struct hermes_response resp;
-       int rc = 0;
-       int err;
-
-       rc = hermes_docmd_wait(hw, HERMES_PROGRAM_DISABLE, 0, &resp);
-
-       printk(KERN_DEBUG PFX "PROGRAM_DISABLE returned %d, "
-              "r0 0x%04x, r1 0x%04x, r2 0x%04x\n",
-              rc, resp.resp0, resp.resp1, resp.resp2);
-
-       if ((rc == 0) &&
-           ((resp.status & HERMES_STATUS_CMDCODE) != HERMES_CMD_DOWNLD))
-               rc = -EIO;
-
-       err = hermes_aux_control(hw, 0);
-       printk(KERN_DEBUG PFX "AUX disable returned %d\n", err);
-
-       /* Acknowledge any outstanding command */
-       hermes_write_regn(hw, EVACK, 0xFFFF);
-
-       /* Reinitialise, ignoring return */
-       (void) hermes_doicmd_wait(hw, 0x0000 | HERMES_CMD_INIT,
-                                 0, 0, 0, NULL);
-
-       return rc ? rc : err;
-}
-EXPORT_SYMBOL(hermesi_program_end);
-
-/* Program the data blocks */
-int hermes_program(hermes_t *hw, const char *first_block, const char *end)
-{
-       const struct dblock *blk;
-       u32 blkaddr;
-       u32 blklen;
-#if LIMIT_PROGRAM_SIZE
-       u32 addr;
-       u32 len;
-#endif
-
-       blk = (const struct dblock *) first_block;
-
-       if ((const char *) blk > (end - sizeof(*blk)))
-               return -EIO;
-
-       blkaddr = dblock_addr(blk);
-       blklen = dblock_len(blk);
-
-       while ((blkaddr != BLOCK_END) &&
-              (((const char *) blk + blklen) <= end)) {
-               printk(KERN_DEBUG PFX
-                      "Programming block of length %d to address 0x%08x\n",
-                      blklen, blkaddr);
-
-#if !LIMIT_PROGRAM_SIZE
-               /* wl_lkm driver splits this into writes of 2000 bytes */
-               hermes_aux_setaddr(hw, blkaddr);
-               hermes_write_bytes(hw, HERMES_AUXDATA, blk->data,
-                                  blklen);
-#else
-               len = (blklen < MAX_DL_SIZE) ? blklen : MAX_DL_SIZE;
-               addr = blkaddr;
-
-               while (addr < (blkaddr + blklen)) {
-                       printk(KERN_DEBUG PFX
-                              "Programming subblock of length %d "
-                              "to address 0x%08x. Data @ %p\n",
-                              len, addr, &blk->data[addr - blkaddr]);
-
-                       hermes_aux_setaddr(hw, addr);
-                       hermes_write_bytes(hw, HERMES_AUXDATA,
-                                          &blk->data[addr - blkaddr],
-                                          len);
-
-                       addr += len;
-                       len = ((blkaddr + blklen - addr) < MAX_DL_SIZE) ?
-                               (blkaddr + blklen - addr) : MAX_DL_SIZE;
-               }
-#endif
-               blk = (const struct dblock *) &blk->data[blklen];
-
-               if ((const char *) blk > (end - sizeof(*blk)))
-                       return -EIO;
-
-               blkaddr = dblock_addr(blk);
-               blklen = dblock_len(blk);
-       }
-       return 0;
-}
-EXPORT_SYMBOL(hermes_program);
-
-static int __init init_hermes_dld(void)
-{
-       return 0;
-}
-
-static void __exit exit_hermes_dld(void)
-{
-}
-
-module_init(init_hermes_dld);
-module_exit(exit_hermes_dld);
-
-/*** Default plugging data for Hermes I ***/
-/* Values from wl_lkm_718/hcf/dhf.c */
-
-#define DEFINE_DEFAULT_PDR(pid, length, data)                          \
-static const struct {                                                  \
-       __le16 len;                                                     \
-       __le16 id;                                                      \
-       u8 val[length];                                                 \
-} __attribute__ ((packed)) default_pdr_data_##pid = {                  \
-       __constant_cpu_to_le16((sizeof(default_pdr_data_##pid)/         \
-                               sizeof(__le16)) - 1),                   \
-       __constant_cpu_to_le16(pid),                                    \
-       data                                                            \
-}
-
-#define DEFAULT_PDR(pid) default_pdr_data_##pid
-
-/*  HWIF Compatiblity */
-DEFINE_DEFAULT_PDR(0x0005, 10, "\x00\x00\x06\x00\x01\x00\x01\x00\x01\x00");
-
-/* PPPPSign */
-DEFINE_DEFAULT_PDR(0x0108, 4, "\x00\x00\x00\x00");
-
-/* PPPPProf */
-DEFINE_DEFAULT_PDR(0x0109, 10, "\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00");
-
-/* Antenna diversity */
-DEFINE_DEFAULT_PDR(0x0150, 2, "\x00\x3F");
-
-/* Modem VCO band Set-up */
-DEFINE_DEFAULT_PDR(0x0160, 28,
-                  "\x00\x00\x00\x00\x00\x00\x00\x00"
-                  "\x00\x00\x00\x00\x00\x00\x00\x00"
-                  "\x00\x00\x00\x00\x00\x00\x00\x00"
-                  "\x00\x00\x00\x00");
-
-/* Modem Rx Gain Table Values */
-DEFINE_DEFAULT_PDR(0x0161, 256,
-                  "\x3F\x01\x3F\01\x3F\x01\x3F\x01"
-                  "\x3F\x01\x3F\01\x3F\x01\x3F\x01"
-                  "\x3F\x01\x3F\01\x3F\x01\x3F\x01"
-                  "\x3F\x01\x3F\01\x3F\x01\x3F\x01"
-                  "\x3F\x01\x3E\01\x3E\x01\x3D\x01"
-                  "\x3D\x01\x3C\01\x3C\x01\x3B\x01"
-                  "\x3B\x01\x3A\01\x3A\x01\x39\x01"
-                  "\x39\x01\x38\01\x38\x01\x37\x01"
-                  "\x37\x01\x36\01\x36\x01\x35\x01"
-                  "\x35\x01\x34\01\x34\x01\x33\x01"
-                  "\x33\x01\x32\x01\x32\x01\x31\x01"
-                  "\x31\x01\x30\x01\x30\x01\x7B\x01"
-                  "\x7B\x01\x7A\x01\x7A\x01\x79\x01"
-                  "\x79\x01\x78\x01\x78\x01\x77\x01"
-                  "\x77\x01\x76\x01\x76\x01\x75\x01"
-                  "\x75\x01\x74\x01\x74\x01\x73\x01"
-                  "\x73\x01\x72\x01\x72\x01\x71\x01"
-                  "\x71\x01\x70\x01\x70\x01\x68\x01"
-                  "\x68\x01\x67\x01\x67\x01\x66\x01"
-                  "\x66\x01\x65\x01\x65\x01\x57\x01"
-                  "\x57\x01\x56\x01\x56\x01\x55\x01"
-                  "\x55\x01\x54\x01\x54\x01\x53\x01"
-                  "\x53\x01\x52\x01\x52\x01\x51\x01"
-                  "\x51\x01\x50\x01\x50\x01\x48\x01"
-                  "\x48\x01\x47\x01\x47\x01\x46\x01"
-                  "\x46\x01\x45\x01\x45\x01\x44\x01"
-                  "\x44\x01\x43\x01\x43\x01\x42\x01"
-                  "\x42\x01\x41\x01\x41\x01\x40\x01"
-                  "\x40\x01\x40\x01\x40\x01\x40\x01"
-                  "\x40\x01\x40\x01\x40\x01\x40\x01"
-                  "\x40\x01\x40\x01\x40\x01\x40\x01"
-                  "\x40\x01\x40\x01\x40\x01\x40\x01");
-
-/* Write PDA according to certain rules.
- *
- * For every production data record, look for a previous setting in
- * the pda, and use that.
- *
- * For certain records, use defaults if they are not found in pda.
- */
-int hermes_apply_pda_with_defaults(hermes_t *hw,
-                                  const char *first_pdr,
-                                  const __le16 *pda)
-{
-       const struct pdr *pdr = (const struct pdr *) first_pdr;
-       struct pdi *first_pdi = (struct pdi *) &pda[2];
-       struct pdi *pdi;
-       struct pdi *default_pdi = NULL;
-       struct pdi *outdoor_pdi;
-       void *end = (void *)first_pdr + MAX_PDA_SIZE;
-       int record_id;
-
-       while (((void *)pdr < end) &&
-              (pdr_id(pdr) != PDI_END)) {
-               /*
-                * For spectrum_cs firmwares,
-                * PDR area is currently not terminated by PDI_END.
-                * It's followed by CRC records, which have the type
-                * field where PDR has length.  The type can be 0 or 1.
-                */
-               if (pdr_len(pdr) < 2)
-                       break;
-               record_id = pdr_id(pdr);
-
-               pdi = hermes_find_pdi(first_pdi, record_id);
-               if (pdi)
-                       printk(KERN_DEBUG PFX "Found record 0x%04x at %p\n",
-                              record_id, pdi);
-
-               switch (record_id) {
-               case 0x110: /* Modem REFDAC values */
-               case 0x120: /* Modem VGDAC values */
-                       outdoor_pdi = hermes_find_pdi(first_pdi, record_id + 1);
-                       default_pdi = NULL;
-                       if (outdoor_pdi) {
-                               pdi = outdoor_pdi;
-                               printk(KERN_DEBUG PFX
-                                      "Using outdoor record 0x%04x at %p\n",
-                                      record_id + 1, pdi);
-                       }
-                       break;
-               case 0x5: /*  HWIF Compatiblity */
-                       default_pdi = (struct pdi *) &DEFAULT_PDR(0x0005);
-                       break;
-               case 0x108: /* PPPPSign */
-                       default_pdi = (struct pdi *) &DEFAULT_PDR(0x0108);
-                       break;
-               case 0x109: /* PPPPProf */
-                       default_pdi = (struct pdi *) &DEFAULT_PDR(0x0109);
-                       break;
-               case 0x150: /* Antenna diversity */
-                       default_pdi = (struct pdi *) &DEFAULT_PDR(0x0150);
-                       break;
-               case 0x160: /* Modem VCO band Set-up */
-                       default_pdi = (struct pdi *) &DEFAULT_PDR(0x0160);
-                       break;
-               case 0x161: /* Modem Rx Gain Table Values */
-                       default_pdi = (struct pdi *) &DEFAULT_PDR(0x0161);
-                       break;
-               default:
-                       default_pdi = NULL;
-                       break;
-               }
-               if (!pdi && default_pdi) {
-                       /* Use default */
-                       pdi = default_pdi;
-                       printk(KERN_DEBUG PFX
-                              "Using default record 0x%04x at %p\n",
-                              record_id, pdi);
-               }
-
-               if (pdi) {
-                       /* Lengths of the data in PDI and PDR must match */
-                       if (pdi_len(pdi) == pdr_len(pdr)) {
-                               /* do the actual plugging */
-                               hermes_aux_setaddr(hw, pdr_addr(pdr));
-                               hermes_write_bytes(hw, HERMES_AUXDATA,
-                                                  pdi->data, pdi_len(pdi));
-                       }
-               }
-
-               pdr++;
-       }
-       return 0;
-}
-EXPORT_SYMBOL(hermes_apply_pda_with_defaults);
diff --git a/drivers/net/wireless/hermes_dld.h b/drivers/net/wireless/hermes_dld.h
deleted file mode 100644 (file)
index 6fcb262..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2007, David Kilroy
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in
- * which case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
- */
-#ifndef _HERMES_DLD_H
-#define _HERMES_DLD_H
-
-#include "hermes.h"
-
-int hermesi_program_init(hermes_t *hw, u32 offset);
-int hermesi_program_end(hermes_t *hw);
-int hermes_program(hermes_t *hw, const char *first_block, const char *end);
-
-int hermes_read_pda(hermes_t *hw,
-                   __le16 *pda,
-                   u32 pda_addr,
-                   u16 pda_len,
-                   int use_eeprom);
-int hermes_apply_pda(hermes_t *hw,
-                    const char *first_pdr,
-                    const __le16 *pda);
-int hermes_apply_pda_with_defaults(hermes_t *hw,
-                                  const char *first_pdr,
-                                  const __le16 *pda);
-
-size_t hermes_blocks_length(const char *first_block);
-
-#endif /* _HERMES_DLD_H */
diff --git a/drivers/net/wireless/hermes_rid.h b/drivers/net/wireless/hermes_rid.h
deleted file mode 100644 (file)
index 42eb67d..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-#ifndef _HERMES_RID_H
-#define _HERMES_RID_H
-
-/*
- * Configuration RIDs
- */
-#define HERMES_RID_CNFPORTTYPE                 0xFC00
-#define HERMES_RID_CNFOWNMACADDR               0xFC01
-#define HERMES_RID_CNFDESIREDSSID              0xFC02
-#define HERMES_RID_CNFOWNCHANNEL               0xFC03
-#define HERMES_RID_CNFOWNSSID                  0xFC04
-#define HERMES_RID_CNFOWNATIMWINDOW            0xFC05
-#define HERMES_RID_CNFSYSTEMSCALE              0xFC06
-#define HERMES_RID_CNFMAXDATALEN               0xFC07
-#define HERMES_RID_CNFWDSADDRESS               0xFC08
-#define HERMES_RID_CNFPMENABLED                        0xFC09
-#define HERMES_RID_CNFPMEPS                    0xFC0A
-#define HERMES_RID_CNFMULTICASTRECEIVE         0xFC0B
-#define HERMES_RID_CNFMAXSLEEPDURATION         0xFC0C
-#define HERMES_RID_CNFPMHOLDOVERDURATION       0xFC0D
-#define HERMES_RID_CNFOWNNAME                  0xFC0E
-#define HERMES_RID_CNFOWNDTIMPERIOD            0xFC10
-#define HERMES_RID_CNFWDSADDRESS1              0xFC11
-#define HERMES_RID_CNFWDSADDRESS2              0xFC12
-#define HERMES_RID_CNFWDSADDRESS3              0xFC13
-#define HERMES_RID_CNFWDSADDRESS4              0xFC14
-#define HERMES_RID_CNFWDSADDRESS5              0xFC15
-#define HERMES_RID_CNFWDSADDRESS6              0xFC16
-#define HERMES_RID_CNFMULTICASTPMBUFFERING     0xFC17
-#define HERMES_RID_CNFWEPENABLED_AGERE         0xFC20
-#define HERMES_RID_CNFAUTHENTICATION_AGERE     0xFC21
-#define HERMES_RID_CNFMANDATORYBSSID_SYMBOL    0xFC21
-#define HERMES_RID_CNFDROPUNENCRYPTED          0xFC22
-#define HERMES_RID_CNFWEPDEFAULTKEYID          0xFC23
-#define HERMES_RID_CNFDEFAULTKEY0              0xFC24
-#define HERMES_RID_CNFDEFAULTKEY1              0xFC25
-#define HERMES_RID_CNFMWOROBUST_AGERE          0xFC25
-#define HERMES_RID_CNFDEFAULTKEY2              0xFC26
-#define HERMES_RID_CNFDEFAULTKEY3              0xFC27
-#define HERMES_RID_CNFWEPFLAGS_INTERSIL                0xFC28
-#define HERMES_RID_CNFWEPKEYMAPPINGTABLE       0xFC29
-#define HERMES_RID_CNFAUTHENTICATION           0xFC2A
-#define HERMES_RID_CNFMAXASSOCSTA              0xFC2B
-#define        HERMES_RID_CNFKEYLENGTH_SYMBOL          0xFC2B
-#define HERMES_RID_CNFTXCONTROL                        0xFC2C
-#define HERMES_RID_CNFROAMINGMODE              0xFC2D
-#define HERMES_RID_CNFHOSTAUTHENTICATION       0xFC2E
-#define HERMES_RID_CNFRCVCRCERROR              0xFC30
-#define HERMES_RID_CNFMMLIFE                   0xFC31
-#define HERMES_RID_CNFALTRETRYCOUNT            0xFC32
-#define HERMES_RID_CNFBEACONINT                        0xFC33
-#define HERMES_RID_CNFAPPCFINFO                        0xFC34
-#define HERMES_RID_CNFSTAPCFINFO               0xFC35
-#define HERMES_RID_CNFPRIORITYQUSAGE           0xFC37
-#define HERMES_RID_CNFTIMCTRL                  0xFC40
-#define HERMES_RID_CNFTHIRTY2TALLY             0xFC42
-#define HERMES_RID_CNFENHSECURITY              0xFC43
-#define HERMES_RID_CNFGROUPADDRESSES           0xFC80
-#define HERMES_RID_CNFCREATEIBSS               0xFC81
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD   0xFC82
-#define HERMES_RID_CNFRTSTHRESHOLD             0xFC83
-#define HERMES_RID_CNFTXRATECONTROL            0xFC84
-#define HERMES_RID_CNFPROMISCUOUSMODE          0xFC85
-#define HERMES_RID_CNFBASICRATES_SYMBOL                0xFC8A
-#define HERMES_RID_CNFPREAMBLE_SYMBOL          0xFC8C
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD0  0xFC90
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD1  0xFC91
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD2  0xFC92
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD3  0xFC93
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD4  0xFC94
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD5  0xFC95
-#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD6  0xFC96
-#define HERMES_RID_CNFRTSTHRESHOLD0            0xFC97
-#define HERMES_RID_CNFRTSTHRESHOLD1            0xFC98
-#define HERMES_RID_CNFRTSTHRESHOLD2            0xFC99
-#define HERMES_RID_CNFRTSTHRESHOLD3            0xFC9A
-#define HERMES_RID_CNFRTSTHRESHOLD4            0xFC9B
-#define HERMES_RID_CNFRTSTHRESHOLD5            0xFC9C
-#define HERMES_RID_CNFRTSTHRESHOLD6            0xFC9D
-#define HERMES_RID_CNFHOSTSCAN_SYMBOL          0xFCAB
-#define HERMES_RID_CNFSHORTPREAMBLE            0xFCB0
-#define HERMES_RID_CNFWEPKEYS_AGERE            0xFCB0
-#define HERMES_RID_CNFEXCLUDELONGPREAMBLE      0xFCB1
-#define HERMES_RID_CNFTXKEY_AGERE              0xFCB1
-#define HERMES_RID_CNFAUTHENTICATIONRSPTO      0xFCB2
-#define HERMES_RID_CNFSCANSSID_AGERE           0xFCB2
-#define HERMES_RID_CNFBASICRATES               0xFCB3
-#define HERMES_RID_CNFSUPPORTEDRATES           0xFCB4
-#define HERMES_RID_CNFADDDEFAULTTKIPKEY_AGERE  0xFCB4
-#define HERMES_RID_CNFSETWPAAUTHMGMTSUITE_AGERE        0xFCB5
-#define HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE  0xFCB6
-#define HERMES_RID_CNFADDMAPPEDTKIPKEY_AGERE   0xFCB7
-#define HERMES_RID_CNFREMMAPPEDTKIPKEY_AGERE   0xFCB8
-#define HERMES_RID_CNFSETWPACAPABILITIES_AGERE 0xFCB9
-#define HERMES_RID_CNFCACHEDPMKADDRESS         0xFCBA
-#define HERMES_RID_CNFREMOVEPMKADDRESS         0xFCBB
-#define HERMES_RID_CNFSCANCHANNELS2GHZ         0xFCC2
-#define HERMES_RID_CNFDISASSOCIATE             0xFCC8
-#define HERMES_RID_CNFTICKTIME                 0xFCE0
-#define HERMES_RID_CNFSCANREQUEST              0xFCE1
-#define HERMES_RID_CNFJOINREQUEST              0xFCE2
-#define HERMES_RID_CNFAUTHENTICATESTATION      0xFCE3
-#define HERMES_RID_CNFCHANNELINFOREQUEST       0xFCE4
-#define HERMES_RID_CNFHOSTSCAN                 0xFCE5
-
-/*
- * Information RIDs
- */
-#define HERMES_RID_MAXLOADTIME                 0xFD00
-#define HERMES_RID_DOWNLOADBUFFER              0xFD01
-#define HERMES_RID_PRIID                       0xFD02
-#define HERMES_RID_PRISUPRANGE                 0xFD03
-#define HERMES_RID_CFIACTRANGES                        0xFD04
-#define HERMES_RID_NICSERNUM                   0xFD0A
-#define HERMES_RID_NICID                       0xFD0B
-#define HERMES_RID_MFISUPRANGE                 0xFD0C
-#define HERMES_RID_CFISUPRANGE                 0xFD0D
-#define HERMES_RID_CHANNELLIST                 0xFD10
-#define HERMES_RID_REGULATORYDOMAINS           0xFD11
-#define HERMES_RID_TEMPTYPE                    0xFD12
-#define HERMES_RID_CIS                         0xFD13
-#define HERMES_RID_STAID                       0xFD20
-#define HERMES_RID_STASUPRANGE                 0xFD21
-#define HERMES_RID_MFIACTRANGES                        0xFD22
-#define HERMES_RID_CFIACTRANGES2               0xFD23
-#define HERMES_RID_SECONDARYVERSION_SYMBOL     0xFD24
-#define HERMES_RID_PORTSTATUS                  0xFD40
-#define HERMES_RID_CURRENTSSID                 0xFD41
-#define HERMES_RID_CURRENTBSSID                        0xFD42
-#define HERMES_RID_COMMSQUALITY                        0xFD43
-#define HERMES_RID_CURRENTTXRATE               0xFD44
-#define HERMES_RID_CURRENTBEACONINTERVAL       0xFD45
-#define HERMES_RID_CURRENTSCALETHRESHOLDS      0xFD46
-#define HERMES_RID_PROTOCOLRSPTIME             0xFD47
-#define HERMES_RID_SHORTRETRYLIMIT             0xFD48
-#define HERMES_RID_LONGRETRYLIMIT              0xFD49
-#define HERMES_RID_MAXTRANSMITLIFETIME         0xFD4A
-#define HERMES_RID_MAXRECEIVELIFETIME          0xFD4B
-#define HERMES_RID_CFPOLLABLE                  0xFD4C
-#define HERMES_RID_AUTHENTICATIONALGORITHMS    0xFD4D
-#define HERMES_RID_PRIVACYOPTIONIMPLEMENTED    0xFD4F
-#define HERMES_RID_DBMCOMMSQUALITY_INTERSIL    0xFD51
-#define HERMES_RID_CURRENTTXRATE1              0xFD80
-#define HERMES_RID_CURRENTTXRATE2              0xFD81
-#define HERMES_RID_CURRENTTXRATE3              0xFD82
-#define HERMES_RID_CURRENTTXRATE4              0xFD83
-#define HERMES_RID_CURRENTTXRATE5              0xFD84
-#define HERMES_RID_CURRENTTXRATE6              0xFD85
-#define HERMES_RID_OWNMACADDR                  0xFD86
-#define HERMES_RID_SCANRESULTSTABLE            0xFD88
-#define HERMES_RID_CURRENT_COUNTRY_INFO                0xFD89
-#define HERMES_RID_CURRENT_WPA_IE              0xFD8A
-#define HERMES_RID_CURRENT_TKIP_IV             0xFD8B
-#define HERMES_RID_CURRENT_ASSOC_REQ_INFO      0xFD8C
-#define HERMES_RID_CURRENT_ASSOC_RESP_INFO     0xFD8D
-#define HERMES_RID_TXQUEUEEMPTY                        0xFD91
-#define HERMES_RID_PHYTYPE                     0xFDC0
-#define HERMES_RID_CURRENTCHANNEL              0xFDC1
-#define HERMES_RID_CURRENTPOWERSTATE           0xFDC2
-#define HERMES_RID_CCAMODE                     0xFDC3
-#define HERMES_RID_SUPPORTEDDATARATES          0xFDC6
-#define HERMES_RID_BUILDSEQ                    0xFFFE
-#define HERMES_RID_FWID                                0xFFFF
-
-#endif
index f106bc1585a45bbeacb1c1a6f2716e2ac8dfc1b0..5f64461aa54e6d1755183ad1bb3c5dd8b631b113 100644 (file)
@@ -19,7 +19,6 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
 {
        struct ieee80211_hdr_4addr *hdr;
        u16 fc;
-       DECLARE_MAC_BUF(mac);
 
        hdr = (struct ieee80211_hdr_4addr *) skb->data;
 
@@ -45,11 +44,11 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
        printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id),
               le16_to_cpu(hdr->seq_ctl));
 
-       printk(KERN_DEBUG "   A1=%s", print_mac(mac, hdr->addr1));
-       printk(" A2=%s", print_mac(mac, hdr->addr2));
-       printk(" A3=%s", print_mac(mac, hdr->addr3));
+       printk(KERN_DEBUG "   A1=%pM", hdr->addr1);
+       printk(" A2=%pM", hdr->addr2);
+       printk(" A3=%pM", hdr->addr3);
        if (skb->len >= 30)
-               printk(" A4=%s", print_mac(mac, hdr->addr4));
+               printk(" A4=%pM", hdr->addr4);
        printk("\n");
 }
 
@@ -68,7 +67,6 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
 
        iface = netdev_priv(dev);
        local = iface->local;
-       dev->last_rx = jiffies;
 
        if (dev->type == ARPHRD_IEEE80211_PRISM) {
                if (local->monitor_type == PRISM2_MONITOR_PRISM) {
@@ -557,7 +555,6 @@ static int
 hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
                    u16 fc, struct net_device **wds)
 {
-       DECLARE_MAC_BUF(mac);
        /* FIX: is this really supposed to accept WDS frames only in Master
         * mode? What about Repeater or Managed with WDS frames? */
        if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) !=
@@ -573,10 +570,10 @@ hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
             hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) {
                /* RA (or BSSID) is not ours - drop */
                PDEBUG(DEBUG_EXTRA2, "%s: received WDS frame with "
-                      "not own or broadcast %s=%s\n",
+                      "not own or broadcast %s=%pM\n",
                       local->dev->name,
                       fc & IEEE80211_FCTL_FROMDS ? "RA" : "BSSID",
-                      print_mac(mac, hdr->addr1));
+                      hdr->addr1);
                return -1;
        }
 
@@ -589,8 +586,8 @@ hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
                /* require that WDS link has been registered with TA or the
                 * frame is from current AP when using 'AP client mode' */
                PDEBUG(DEBUG_EXTRA, "%s: received WDS[4 addr] frame "
-                      "from unknown TA=%s\n",
-                      local->dev->name, print_mac(mac, hdr->addr2));
+                      "from unknown TA=%pM\n",
+                      local->dev->name, hdr->addr2);
                if (local->ap && local->ap->autom_ap_wds)
                        hostap_wds_link_oper(local, hdr->addr2, WDS_ADD);
                return -1;
@@ -667,10 +664,8 @@ hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
            strcmp(crypt->ops->name, "TKIP") == 0) {
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-                              "received packet from " MAC_FMT "\n",
-                              local->dev->name,
-                              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-                              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5]);
+                              "received packet from %pM\n",
+                              local->dev->name, hdr->addr2);
                }
                return -1;
        }
@@ -679,12 +674,8 @@ hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
        res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
        atomic_dec(&crypt->refcnt);
        if (res < 0) {
-               printk(KERN_DEBUG "%s: decryption failed (SA=" MAC_FMT
-                      ") res=%d\n",
-                      local->dev->name,
-                      hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-                      hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
-                      res);
+               printk(KERN_DEBUG "%s: decryption failed (SA=%pM) res=%d\n",
+                      local->dev->name, hdr->addr2, res);
                local->comm_tallies.rx_discards_wep_undecryptable++;
                return -1;
        }
@@ -700,7 +691,6 @@ hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
 {
        struct ieee80211_hdr_4addr *hdr;
        int res, hdrlen;
-       DECLARE_MAC_BUF(mac);
 
        if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
                return 0;
@@ -713,8 +703,8 @@ hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
        atomic_dec(&crypt->refcnt);
        if (res < 0) {
                printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
-                      " (SA=%s keyidx=%d)\n",
-                      local->dev->name, print_mac(mac, hdr->addr2), keyidx);
+                      " (SA=%pM keyidx=%d)\n",
+                      local->dev->name, hdr->addr2, keyidx);
                return -1;
        }
 
@@ -822,10 +812,8 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
                         * frames silently instead of filling system log with
                         * these reports. */
                        printk(KERN_DEBUG "%s: WEP decryption failed (not set)"
-                              " (SA=" MAC_FMT ")\n",
-                              local->dev->name,
-                              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-                              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5]);
+                              " (SA=%pM)\n",
+                              local->dev->name, hdr->addr2);
 #endif
                        local->comm_tallies.rx_discards_wep_undecryptable++;
                        goto rx_dropped;
@@ -839,9 +827,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
                    (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
                {
                        printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
-                              "from " MAC_FMT "\n", dev->name,
-                              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-                              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5]);
+                              "from %pM\n", dev->name, hdr->addr2);
                        /* TODO: could inform hostapd about this so that it
                         * could send auth failure report */
                        goto rx_dropped;
@@ -896,8 +882,6 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
                from_assoc_ap = 1;
        }
 
-       dev->last_rx = jiffies;
-
        if ((local->iw_mode == IW_MODE_MASTER ||
             local->iw_mode == IW_MODE_REPEAT) &&
            !from_assoc_ap) {
@@ -1009,10 +993,8 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
                               "unencrypted EAPOL frame\n", local->dev->name);
                } else {
                        printk(KERN_DEBUG "%s: encryption configured, but RX "
-                              "frame not encrypted (SA=" MAC_FMT ")\n",
-                              local->dev->name,
-                              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-                              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5]);
+                              "frame not encrypted (SA=%pM)\n",
+                              local->dev->name, hdr->addr2);
                        goto rx_dropped;
                }
        }
@@ -1021,10 +1003,8 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
            !hostap_is_eapol_frame(local, skb)) {
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "%s: dropped unencrypted RX data "
-                              "frame from " MAC_FMT " (drop_unencrypted=1)\n",
-                              dev->name,
-                              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-                              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5]);
+                              "frame from %pM (drop_unencrypted=1)\n",
+                              dev->name, hdr->addr2);
                }
                goto rx_dropped;
        }
index 921c984416f8b03270e57b199b2be839a6e61b50..075247188e640daa85ac8131a9c69442a858522c 100644 (file)
@@ -17,7 +17,6 @@ void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
 {
        struct ieee80211_hdr_4addr *hdr;
        u16 fc;
-       DECLARE_MAC_BUF(mac);
 
        hdr = (struct ieee80211_hdr_4addr *) skb->data;
 
@@ -41,11 +40,11 @@ void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
        printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id),
               le16_to_cpu(hdr->seq_ctl));
 
-       printk(KERN_DEBUG "   A1=%s", print_mac(mac, hdr->addr1));
-       printk(" A2=%s", print_mac(mac, hdr->addr2));
-       printk(" A3=%s", print_mac(mac, hdr->addr3));
+       printk(KERN_DEBUG "   A1=%pM", hdr->addr1);
+       printk(" A2=%pM", hdr->addr2);
+       printk(" A3=%pM", hdr->addr3);
        if (skb->len >= 30)
-               printk(" A4=%s", print_mac(mac, hdr->addr4));
+               printk(" A4=%pM", hdr->addr4);
        printk("\n");
 }
 
@@ -328,10 +327,8 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
                hdr = (struct ieee80211_hdr_4addr *) skb->data;
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-                              "TX packet to " MAC_FMT "\n",
-                              local->dev->name,
-                              hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
-                              hdr->addr1[3], hdr->addr1[4], hdr->addr1[5]);
+                              "TX packet to %pM\n",
+                              local->dev->name, hdr->addr1);
                }
                kfree_skb(skb);
                return NULL;
index af3d4ef2a80b75218b52f538e93e58e8215f5930..dec3dbe1bf8f1f4800ed0cf7a188bda45382ea36 100644 (file)
@@ -94,7 +94,6 @@ static void ap_sta_hash_add(struct ap_data *ap, struct sta_info *sta)
 static void ap_sta_hash_del(struct ap_data *ap, struct sta_info *sta)
 {
        struct sta_info *s;
-       DECLARE_MAC_BUF(mac);
 
        s = ap->sta_hash[STA_HASH(sta->addr)];
        if (s == NULL) return;
@@ -109,20 +108,18 @@ static void ap_sta_hash_del(struct ap_data *ap, struct sta_info *sta)
        if (s->hnext != NULL)
                s->hnext = s->hnext->hnext;
        else
-               printk("AP: could not remove STA %s"
-                      " from hash table\n",
-                      print_mac(mac, sta->addr));
+               printk("AP: could not remove STA %pM from hash table\n",
+                      sta->addr);
 }
 
 static void ap_free_sta(struct ap_data *ap, struct sta_info *sta)
 {
-       DECLARE_MAC_BUF(mac);
        if (sta->ap && sta->local)
                hostap_event_expired_sta(sta->local->dev, sta);
 
        if (ap->proc != NULL) {
                char name[20];
-               sprintf(name, "%s", print_mac(mac, sta->addr));
+               sprintf(name, "%pM", sta->addr);
                remove_proc_entry(name, ap->proc);
        }
 
@@ -185,7 +182,6 @@ static void ap_handle_timer(unsigned long data)
        struct ap_data *ap;
        unsigned long next_time = 0;
        int was_assoc;
-       DECLARE_MAC_BUF(mac);
 
        if (sta == NULL || sta->local == NULL || sta->local->ap == NULL) {
                PDEBUG(DEBUG_AP, "ap_handle_timer() called with NULL data\n");
@@ -242,8 +238,8 @@ static void ap_handle_timer(unsigned long data)
        if (sta->ap) {
                if (ap->autom_ap_wds) {
                        PDEBUG(DEBUG_AP, "%s: removing automatic WDS "
-                              "connection to AP %s\n",
-                              local->dev->name, print_mac(mac, sta->addr));
+                              "connection to AP %pM\n",
+                              local->dev->name, sta->addr);
                        hostap_wds_link_oper(local, sta->addr, WDS_DEL);
                }
        } else if (sta->timeout_next == STA_NULLFUNC) {
@@ -259,11 +255,11 @@ static void ap_handle_timer(unsigned long data)
        } else {
                int deauth = sta->timeout_next == STA_DEAUTH;
                __le16 resp;
-               PDEBUG(DEBUG_AP, "%s: sending %s info to STA %s"
+               PDEBUG(DEBUG_AP, "%s: sending %s info to STA %pM"
                       "(last=%lu, jiffies=%lu)\n",
                       local->dev->name,
                       deauth ? "deauthentication" : "disassociation",
-                      print_mac(mac, sta->addr), sta->last_rx, jiffies);
+                      sta->addr, sta->last_rx, jiffies);
 
                resp = cpu_to_le16(deauth ? WLAN_REASON_PREV_AUTH_NOT_VALID :
                                   WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
@@ -275,10 +271,10 @@ static void ap_handle_timer(unsigned long data)
 
        if (sta->timeout_next == STA_DEAUTH) {
                if (sta->flags & WLAN_STA_PERM) {
-                       PDEBUG(DEBUG_AP, "%s: STA %s"
+                       PDEBUG(DEBUG_AP, "%s: STA %pM"
                               " would have been removed, "
                               "but it has 'perm' flag\n",
-                              local->dev->name, print_mac(mac, sta->addr));
+                              local->dev->name, sta->addr);
                } else
                        ap_free_sta(ap, sta);
                return;
@@ -332,7 +328,6 @@ static int ap_control_proc_read(char *page, char **start, off_t off,
        struct ap_data *ap = (struct ap_data *) data;
        char *policy_txt;
        struct mac_entry *entry;
-       DECLARE_MAC_BUF(mac);
 
        if (off != 0) {
                *eof = 1;
@@ -363,7 +358,7 @@ static int ap_control_proc_read(char *page, char **start, off_t off,
                        break;
                }
 
-               p += sprintf(p, "%s\n", print_mac(mac, entry->addr));
+               p += sprintf(p, "%pM\n", entry->addr);
        }
        spin_unlock_bh(&ap->mac_restrictions.lock);
 
@@ -520,7 +515,6 @@ static int prism2_ap_proc_read(char *page, char **start, off_t off,
        struct ap_data *ap = (struct ap_data *) data;
        struct sta_info *sta;
        int i;
-       DECLARE_MAC_BUF(mac);
 
        if (off > PROC_LIMIT) {
                *eof = 1;
@@ -533,8 +527,8 @@ static int prism2_ap_proc_read(char *page, char **start, off_t off,
                if (!sta->ap)
                        continue;
 
-               p += sprintf(p, "%s %d %d %d %d '",
-                            print_mac(mac, sta->addr),
+               p += sprintf(p, "%pM %d %d %d %d '",
+                            sta->addr,
                             sta->u.ap.channel, sta->last_rx_signal,
                             sta->last_rx_silence, sta->last_rx_rate);
                for (i = 0; i < sta->u.ap.ssid_len; i++)
@@ -683,11 +677,9 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
        if (sta)
                atomic_dec(&sta->users);
        if (txt) {
-               PDEBUG(DEBUG_AP, "%s: " MAC_FMT " auth_cb - alg=%d "
+               PDEBUG(DEBUG_AP, "%s: %pM auth_cb - alg=%d "
                       "trans#=%d status=%d - %s\n",
-                      dev->name,
-                      hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
-                      hdr->addr1[3], hdr->addr1[4], hdr->addr1[5],
+                      dev->name, hdr->addr1,
                       auth_alg, auth_transaction, status, txt);
        }
        dev_kfree_skb(skb);
@@ -754,11 +746,8 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
        if (sta)
                atomic_dec(&sta->users);
        if (txt) {
-               PDEBUG(DEBUG_AP, "%s: " MAC_FMT " assoc_cb - %s\n",
-                      dev->name,
-                      hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
-                      hdr->addr1[3], hdr->addr1[4], hdr->addr1[5],
-                      txt);
+               PDEBUG(DEBUG_AP, "%s: %pM assoc_cb - %s\n",
+                      dev->name, hdr->addr1, txt);
        }
        dev_kfree_skb(skb);
 }
@@ -781,11 +770,9 @@ static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
                        sta->flags &= ~WLAN_STA_PENDING_POLL;
                spin_unlock(&ap->sta_table_lock);
        } else {
-               PDEBUG(DEBUG_AP, "%s: STA " MAC_FMT
-                      " did not ACK activity poll frame\n",
-                      ap->local->dev->name,
-                      hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
-                      hdr->addr1[3], hdr->addr1[4], hdr->addr1[5]);
+               PDEBUG(DEBUG_AP,
+                      "%s: STA %pM did not ACK activity poll frame\n",
+                      ap->local->dev->name, hdr->addr1);
        }
 
  fail:
@@ -1002,7 +989,6 @@ static int prism2_sta_proc_read(char *page, char **start, off_t off,
        char *p = page;
        struct sta_info *sta = (struct sta_info *) data;
        int i;
-       DECLARE_MAC_BUF(mac);
 
        /* FIX: possible race condition.. the STA data could have just expired,
         * but proc entry was still here so that the read could have started;
@@ -1013,11 +999,11 @@ static int prism2_sta_proc_read(char *page, char **start, off_t off,
                return 0;
        }
 
-       p += sprintf(p, "%s=%s\nusers=%d\naid=%d\n"
+       p += sprintf(p, "%s=%pM\nusers=%d\naid=%d\n"
                     "flags=0x%04x%s%s%s%s%s%s%s\n"
                     "capability=0x%02x\nlisten_interval=%d\nsupported_rates=",
                     sta->ap ? "AP" : "STA",
-                    print_mac(mac, sta->addr), atomic_read(&sta->users), sta->aid,
+                    sta->addr, atomic_read(&sta->users), sta->aid,
                     sta->flags,
                     sta->flags & WLAN_STA_AUTH ? " AUTH" : "",
                     sta->flags & WLAN_STA_ASSOC ? " ASSOC" : "",
@@ -1078,7 +1064,6 @@ static void handle_add_proc_queue(struct work_struct *work)
        struct sta_info *sta;
        char name[20];
        struct add_sta_proc_data *entry, *prev;
-       DECLARE_MAC_BUF(mac);
 
        entry = ap->add_sta_proc_entries;
        ap->add_sta_proc_entries = NULL;
@@ -1091,7 +1076,7 @@ static void handle_add_proc_queue(struct work_struct *work)
                spin_unlock_bh(&ap->sta_table_lock);
 
                if (sta) {
-                       sprintf(name, "%s", print_mac(mac, sta->addr));
+                       sprintf(name, "%pM", sta->addr);
                        sta->proc = create_proc_read_entry(
                                name, 0, ap->proc,
                                prism2_sta_proc_read, sta);
@@ -1318,9 +1303,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
 
        if (len < 6) {
                PDEBUG(DEBUG_AP, "%s: handle_authen - too short payload "
-                      "(len=%d) from " MAC_FMT "\n", dev->name, len,
-                      hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-                      hdr->addr2[3], hdr->addr2[4], hdr->addr2[5]);
+                      "(len=%d) from %pM\n", dev->name, len, hdr->addr2);
                return;
        }
 
@@ -1385,10 +1368,8 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
                if (time_after(jiffies, sta->u.ap.last_beacon +
                               (10 * sta->listen_interval * HZ) / 1024)) {
                        PDEBUG(DEBUG_AP, "%s: no beacons received for a while,"
-                              " assuming AP " MAC_FMT " is now STA\n",
-                              dev->name,
-                              sta->addr[0], sta->addr[1], sta->addr[2],
-                              sta->addr[3], sta->addr[4], sta->addr[5]);
+                              " assuming AP %pM is now STA\n",
+                              dev->name, sta->addr);
                        sta->ap = 0;
                        sta->flags = 0;
                        sta->u.sta.challenge = NULL;
@@ -1503,11 +1484,9 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
        }
 
        if (resp) {
-               PDEBUG(DEBUG_AP, "%s: " MAC_FMT " auth (alg=%d "
+               PDEBUG(DEBUG_AP, "%s: %pM auth (alg=%d "
                       "trans#=%d stat=%d len=%d fc=%04x) ==> %d (%s)\n",
-                      dev->name,
-                      hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-                      hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
+                      dev->name, hdr->addr2,
                       auth_alg, auth_transaction, status_code, len,
                       fc, resp, txt);
        }
@@ -1533,10 +1512,8 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
 
        if (len < (reassoc ? 10 : 4)) {
                PDEBUG(DEBUG_AP, "%s: handle_assoc - too short payload "
-                      "(len=%d, reassoc=%d) from " MAC_FMT "\n",
-                      dev->name, len, reassoc,
-                      hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-                      hdr->addr2[3], hdr->addr2[4], hdr->addr2[5]);
+                      "(len=%d, reassoc=%d) from %pM\n",
+                      dev->name, len, reassoc, hdr->addr2);
                return;
        }
 
@@ -1613,12 +1590,9 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
                }
 
                if (left > 0) {
-                       PDEBUG(DEBUG_AP, "%s: assoc from " MAC_FMT
+                       PDEBUG(DEBUG_AP, "%s: assoc from %pM"
                               " with extra data (%d bytes) [",
-                              dev->name,
-                              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-                              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
-                              left);
+                              dev->name, hdr->addr2, left);
                        while (left > 0) {
                                PDEBUG2(DEBUG_AP, "<%02x>", *u);
                                u++; left--;
@@ -1717,14 +1691,12 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
        }
 
 #if 0
-       PDEBUG(DEBUG_AP, "%s: " MAC_FMT" %sassoc (len=%d "
-              "prev_ap=" MAC_FMT") => %d(%d) (%s)\n",
+       PDEBUG(DEBUG_AP, "%s: %pM %sassoc (len=%d "
+              "prev_ap=%pM) => %d(%d) (%s)\n",
               dev->name,
-              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
+              hdr->addr2,
               reassoc ? "re" : "", len,
-              prev_ap[0], prev_ap[1], prev_ap[2],
-              prev_ap[3], prev_ap[4], prev_ap[5],
+              prev_ap,
               resp, send_deauth, txt);
 #endif
 }
@@ -1741,7 +1713,6 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb,
        u16 reason_code;
        __le16 *pos;
        struct sta_info *sta = NULL;
-       DECLARE_MAC_BUF(mac);
 
        len = skb->len - IEEE80211_MGMT_HDR_LEN;
 
@@ -1753,10 +1724,8 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb,
        pos = (__le16 *) body;
        reason_code = le16_to_cpu(*pos);
 
-       PDEBUG(DEBUG_AP, "%s: deauthentication: " MAC_FMT " len=%d, "
-              "reason_code=%d\n", dev->name,
-              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
+       PDEBUG(DEBUG_AP, "%s: deauthentication: %pM len=%d, "
+              "reason_code=%d\n", dev->name, hdr->addr2,
               len, reason_code);
 
        spin_lock_bh(&local->ap->sta_table_lock);
@@ -1768,11 +1737,9 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb,
        }
        spin_unlock_bh(&local->ap->sta_table_lock);
        if (sta == NULL) {
-               printk("%s: deauthentication from " MAC_FMT ", "
+               printk("%s: deauthentication from %pM, "
               "reason_code=%d, but STA not authenticated\n", dev->name,
-                      hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-                      hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
-                      reason_code);
+                      hdr->addr2, reason_code);
        }
 }
 
@@ -1799,10 +1766,8 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
        pos = (__le16 *) body;
        reason_code = le16_to_cpu(*pos);
 
-       PDEBUG(DEBUG_AP, "%s: disassociation: " MAC_FMT " len=%d, "
-              "reason_code=%d\n", dev->name,
-              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
+       PDEBUG(DEBUG_AP, "%s: disassociation: %pM len=%d, "
+              "reason_code=%d\n", dev->name, hdr->addr2,
               len, reason_code);
 
        spin_lock_bh(&local->ap->sta_table_lock);
@@ -1814,12 +1779,9 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
        }
        spin_unlock_bh(&local->ap->sta_table_lock);
        if (sta == NULL) {
-               printk("%s: disassociation from " MAC_FMT ", "
+               printk("%s: disassociation from %pM, "
                       "reason_code=%d, but STA not authenticated\n",
-                      dev->name,
-                      hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-                      hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
-                      reason_code);
+                      dev->name, hdr->addr2, reason_code);
        }
 }
 
@@ -1909,19 +1871,14 @@ static void handle_pspoll(local_info_t *local,
        u16 aid;
        struct sk_buff *skb;
 
-       PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=" MAC_FMT
-              ", TA=" MAC_FMT " PWRMGT=%d\n",
-              hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
-              hdr->addr1[3], hdr->addr1[4], hdr->addr1[5],
-              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
-              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
+       PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=%pM, TA=%pM PWRMGT=%d\n",
+              hdr->addr1, hdr->addr2,
               !!(le16_to_cpu(hdr->frame_ctl) & IEEE80211_FCTL_PM));
 
        if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
-               PDEBUG(DEBUG_AP, "handle_pspoll - addr1(BSSID)=" MAC_FMT
-                      " not own MAC\n",
-                      hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
-                      hdr->addr1[3], hdr->addr1[4], hdr->addr1[5]);
+               PDEBUG(DEBUG_AP,
+                      "handle_pspoll - addr1(BSSID)=%pM not own MAC\n",
+                      hdr->addr1);
                return;
        }
 
@@ -2007,11 +1964,10 @@ static void handle_wds_oper_queue(struct work_struct *work)
 
        while (entry) {
                PDEBUG(DEBUG_AP, "%s: %s automatic WDS connection "
-                      "to AP " MAC_FMT "\n",
+                      "to AP %pM\n",
                       local->dev->name,
                       entry->type == WDS_ADD ? "adding" : "removing",
-                      entry->addr[0], entry->addr[1], entry->addr[2],
-                      entry->addr[3], entry->addr[4], entry->addr[5]);
+                      entry->addr);
                if (entry->type == WDS_ADD)
                        prism2_wds_add(local, entry->addr, 0);
                else if (entry->type == WDS_DEL)
@@ -2215,10 +2171,8 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
                }
 
                if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
-                       PDEBUG(DEBUG_AP, "handle_ap_item - addr1(BSSID)="
-                              MAC_FMT " not own MAC\n",
-                              hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
-                              hdr->addr1[3], hdr->addr1[4], hdr->addr1[5]);
+                       PDEBUG(DEBUG_AP, "handle_ap_item - addr1(BSSID)=%pM"
+                              " not own MAC\n", hdr->addr1);
                        goto done;
                }
 
@@ -2254,18 +2208,14 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
        }
 
        if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
-               PDEBUG(DEBUG_AP, "handle_ap_item - addr1(DA)=" MAC_FMT
-                      " not own MAC\n",
-                      hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
-                      hdr->addr1[3], hdr->addr1[4], hdr->addr1[5]);
+               PDEBUG(DEBUG_AP, "handle_ap_item - addr1(DA)=%pM"
+                      " not own MAC\n", hdr->addr1);
                goto done;
        }
 
        if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN)) {
-               PDEBUG(DEBUG_AP, "handle_ap_item - addr3(BSSID)=" MAC_FMT
-                      " not own MAC\n",
-                      hdr->addr3[0], hdr->addr3[1], hdr->addr3[2],
-                      hdr->addr3[3], hdr->addr3[4], hdr->addr3[5]);
+               PDEBUG(DEBUG_AP, "handle_ap_item - addr3(BSSID)=%pM"
+                      " not own MAC\n", hdr->addr3);
                goto done;
        }
 
@@ -2366,10 +2316,9 @@ static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
        memcpy(hdr->addr2, sta->addr, ETH_ALEN);
        hdr->duration_id = cpu_to_le16(sta->aid | BIT(15) | BIT(14));
 
-       PDEBUG(DEBUG_PS2, "%s: Scheduling buffered packet delivery for STA "
-              MAC_FMT "\n", local->dev->name,
-              sta->addr[0], sta->addr[1], sta->addr[2],
-              sta->addr[3], sta->addr[4], sta->addr[5]);
+       PDEBUG(DEBUG_PS2,
+              "%s: Scheduling buffered packet delivery for STA %pM\n",
+              local->dev->name, sta->addr);
 
        skb->dev = local->dev;
 
@@ -2723,12 +2672,8 @@ static int ap_update_sta_tx_rate(struct sta_info *sta, struct net_device *dev)
                        case 3: sta->tx_rate = 110; break;
                        default: sta->tx_rate = 0; break;
                        }
-                       PDEBUG(DEBUG_AP, "%s: STA " MAC_FMT
-                              " TX rate raised to %d\n",
-                              dev->name,
-                              sta->addr[0], sta->addr[1], sta->addr[2],
-                              sta->addr[3], sta->addr[4], sta->addr[5],
-                              sta->tx_rate);
+                       PDEBUG(DEBUG_AP, "%s: STA %pM TX rate raised to %d\n",
+                              dev->name, sta->addr, sta->tx_rate);
                }
                sta->tx_since_last_failure = 0;
        }
@@ -2781,9 +2726,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
                 * print out any errors here. */
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "AP: drop packet to non-associated "
-                              "STA " MAC_FMT "\n",
-                              hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
-                              hdr->addr1[3], hdr->addr1[4], hdr->addr1[5]);
+                              "STA %pM\n", hdr->addr1);
                }
 #endif
                local->ap->tx_drop_nonassoc++;
@@ -2821,11 +2764,9 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
        }
 
        if (skb_queue_len(&sta->tx_buf) >= STA_MAX_TX_BUFFER) {
-               PDEBUG(DEBUG_PS, "%s: No more space in STA (" MAC_FMT
-                      ")'s PS mode buffer\n",
-                      local->dev->name,
-                      sta->addr[0], sta->addr[1], sta->addr[2],
-                      sta->addr[3], sta->addr[4], sta->addr[5]);
+               PDEBUG(DEBUG_PS, "%s: No more space in STA (%pM)'s"
+                      "PS mode buffer\n",
+                      local->dev->name, sta->addr);
                /* Make sure that TIM is set for the station (it might not be
                 * after AP wlan hw reset). */
                /* FIX: should fix hw reset to restore bits based on STA
@@ -2897,12 +2838,9 @@ void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
        sta = ap_get_sta(local->ap, hdr->addr1);
        if (!sta) {
                spin_unlock(&local->ap->sta_table_lock);
-               PDEBUG(DEBUG_AP, "%s: Could not find STA " MAC_FMT
+               PDEBUG(DEBUG_AP, "%s: Could not find STA %pM"
                       " for this TX error (@%lu)\n",
-                      local->dev->name,
-                      hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
-                      hdr->addr1[3], hdr->addr1[4], hdr->addr1[5],
-                      jiffies);
+                      local->dev->name, hdr->addr1, jiffies);
                return;
        }
 
@@ -2929,12 +2867,9 @@ void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
                        case 3: sta->tx_rate = 110; break;
                        default: sta->tx_rate = 0; break;
                        }
-                       PDEBUG(DEBUG_AP, "%s: STA " MAC_FMT
-                              " TX rate lowered to %d\n",
-                              local->dev->name,
-                              sta->addr[0], sta->addr[1], sta->addr[2],
-                              sta->addr[3], sta->addr[4], sta->addr[5],
-                              sta->tx_rate);
+                       PDEBUG(DEBUG_AP,
+                              "%s: STA %pM TX rate lowered to %d\n",
+                              local->dev->name, sta->addr, sta->tx_rate);
                }
                sta->tx_consecutive_exc = 0;
        }
@@ -2945,17 +2880,16 @@ void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
 static void hostap_update_sta_ps2(local_info_t *local, struct sta_info *sta,
                                  int pwrmgt, int type, int stype)
 {
-       DECLARE_MAC_BUF(mac);
        if (pwrmgt && !(sta->flags & WLAN_STA_PS)) {
                sta->flags |= WLAN_STA_PS;
-               PDEBUG(DEBUG_PS2, "STA %s changed to use PS "
+               PDEBUG(DEBUG_PS2, "STA %pM changed to use PS "
                       "mode (type=0x%02X, stype=0x%02X)\n",
-                      print_mac(mac, sta->addr), type >> 2, stype >> 4);
+                      sta->addr, type >> 2, stype >> 4);
        } else if (!pwrmgt && (sta->flags & WLAN_STA_PS)) {
                sta->flags &= ~WLAN_STA_PS;
-               PDEBUG(DEBUG_PS2, "STA %s changed to not use "
+               PDEBUG(DEBUG_PS2, "STA %pM changed to not use "
                       "PS mode (type=0x%02X, stype=0x%02X)\n",
-                      print_mac(mac, sta->addr), type >> 2, stype >> 4);
+                      sta->addr, type >> 2, stype >> 4);
                if (type != IEEE80211_FTYPE_CTL ||
                    stype != IEEE80211_STYPE_PSPOLL)
                        schedule_packet_send(local, sta);
@@ -3029,13 +2963,9 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
                        } else {
                                printk(KERN_DEBUG "%s: dropped received packet"
-                                      " from non-associated STA "
-                                      MAC_FMT
+                                      " from non-associated STA %pM"
                                       " (type=0x%02x, subtype=0x%02x)\n",
-                                      dev->name,
-                                      hdr->addr2[0], hdr->addr2[1],
-                                      hdr->addr2[2], hdr->addr2[3],
-                                      hdr->addr2[4], hdr->addr2[5],
+                                      dev->name, hdr->addr2,
                                       type >> 2, stype >> 4);
                                hostap_rx(dev, skb, rx_stats);
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
@@ -3068,13 +2998,9 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
                         * after being unavailable for some time. Speed up
                         * re-association by informing the station about it not
                         * being associated. */
-                       printk(KERN_DEBUG "%s: rejected received nullfunc "
-                              "frame without ToDS from not associated STA "
-                              MAC_FMT "\n",
-                              dev->name,
-                              hdr->addr2[0], hdr->addr2[1],
-                              hdr->addr2[2], hdr->addr2[3],
-                              hdr->addr2[4], hdr->addr2[5]);
+                       printk(KERN_DEBUG "%s: rejected received nullfunc frame"
+                              " without ToDS from not associated STA %pM\n",
+                              dev->name, hdr->addr2);
                        hostap_rx(dev, skb, rx_stats);
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
                }
@@ -3090,13 +3016,10 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
                 * broadcast frame from an IBSS network. Drop it silently.
                 * If BSSID is own, report the dropping of this frame. */
                if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
-                       printk(KERN_DEBUG "%s: dropped received packet from "
-                              MAC_FMT " with no ToDS flag "
+                       printk(KERN_DEBUG "%s: dropped received packet from %pM"
+                              " with no ToDS flag "
                               "(type=0x%02x, subtype=0x%02x)\n", dev->name,
-                              hdr->addr2[0], hdr->addr2[1],
-                              hdr->addr2[2], hdr->addr2[3],
-                              hdr->addr2[4], hdr->addr2[5],
-                              type >> 2, stype >> 4);
+                              hdr->addr2, type >> 2, stype >> 4);
                        hostap_dump_rx_80211(dev->name, skb, rx_stats);
                }
                ret = AP_RX_DROP;
index b470c743c2d1923d5214fe0507ebb6d3fbf3aba2..90b64b09200716c31cb9af9a4e2761ba0ba7100d 100644 (file)
@@ -6,19 +6,6 @@
 
 /* IEEE 802.11 defines */
 
-/* Information Element IDs */
-#define WLAN_EID_SSID 0
-#define WLAN_EID_SUPP_RATES 1
-#define WLAN_EID_FH_PARAMS 2
-#define WLAN_EID_DS_PARAMS 3
-#define WLAN_EID_CF_PARAMS 4
-#define WLAN_EID_TIM 5
-#define WLAN_EID_IBSS_PARAMS 6
-#define WLAN_EID_CHALLENGE 16
-#define WLAN_EID_RSN 48
-#define WLAN_EID_GENERIC 221
-
-
 /* HFA384X Configuration RIDs */
 #define HFA384X_RID_CNFPORTTYPE 0xFC00
 #define HFA384X_RID_CNFOWNMACADDR 0xFC01
index 3153fe9d7ce09dc32bf8764bc6437569c270ba14..fd7f7ceeac462afa9835aa4523f91539a48f1013 100644 (file)
@@ -2335,10 +2335,6 @@ static void prism2_txexc(local_info_t *local)
        int show_dump, res;
        char *payload = NULL;
        struct hfa384x_tx_frame txdesc;
-       DECLARE_MAC_BUF(mac);
-       DECLARE_MAC_BUF(mac2);
-       DECLARE_MAC_BUF(mac3);
-       DECLARE_MAC_BUF(mac4);
 
        show_dump = local->frame_dump & PRISM2_DUMP_TXEXC_HDR;
        local->stats.tx_errors++;
@@ -2404,9 +2400,9 @@ static void prism2_txexc(local_info_t *local)
               WLAN_FC_GET_STYPE(fc) >> 4,
               fc & IEEE80211_FCTL_TODS ? " ToDS" : "",
               fc & IEEE80211_FCTL_FROMDS ? " FromDS" : "");
-       PDEBUG(DEBUG_EXTRA, "   A1=%s A2=%s A3=%s A4=%s\n",
-              print_mac(mac, txdesc.addr1), print_mac(mac2, txdesc.addr2),
-              print_mac(mac3, txdesc.addr3), print_mac(mac4, txdesc.addr4));
+       PDEBUG(DEBUG_EXTRA, "   A1=%pM A2=%pM A3=%pM A4=%pM\n",
+              txdesc.addr1, txdesc.addr2,
+              txdesc.addr3, txdesc.addr4);
 }
 
 
index 7cd3fb79230e51d12f5b226049e64a474d562eb3..99b4cf41edf2c59d5d5d2ea2baa5273a21d28d43 100644 (file)
@@ -166,7 +166,6 @@ static void prism2_host_roaming(local_info_t *local)
        struct hfa384x_hostscan_result *selected, *entry;
        int i;
        unsigned long flags;
-       DECLARE_MAC_BUF(mac);
 
        if (local->last_join_time &&
            time_before(jiffies, local->last_join_time + 10 * HZ)) {
@@ -199,9 +198,8 @@ static void prism2_host_roaming(local_info_t *local)
            local->preferred_ap[2] || local->preferred_ap[3] ||
            local->preferred_ap[4] || local->preferred_ap[5]) {
                /* Try to find preferred AP */
-               PDEBUG(DEBUG_EXTRA, "%s: Preferred AP BSSID "
-                      "%s\n",
-                      dev->name, print_mac(mac, local->preferred_ap));
+               PDEBUG(DEBUG_EXTRA, "%s: Preferred AP BSSID %pM\n",
+                      dev->name, local->preferred_ap);
                for (i = 0; i < local->last_scan_results_count; i++) {
                        entry = &local->last_scan_results[i];
                        if (memcmp(local->preferred_ap, entry->bssid, 6) == 0)
@@ -218,9 +216,9 @@ static void prism2_host_roaming(local_info_t *local)
        req.channel = selected->chid;
        spin_unlock_irqrestore(&local->lock, flags);
 
-       PDEBUG(DEBUG_EXTRA, "%s: JoinRequest: BSSID=%s"
+       PDEBUG(DEBUG_EXTRA, "%s: JoinRequest: BSSID=%pM"
               " channel=%d\n",
-              dev->name, print_mac(mac, req.bssid), le16_to_cpu(req.channel));
+              dev->name, req.bssid, le16_to_cpu(req.channel));
        if (local->func->set_rid(dev, HFA384X_RID_JOINREQUEST, &req,
                                 sizeof(req))) {
                printk(KERN_DEBUG "%s: JoinRequest failed\n", dev->name);
@@ -413,7 +411,6 @@ static void handle_info_queue_linkstatus(local_info_t *local)
        int val = local->prev_link_status;
        int connected;
        union iwreq_data wrqu;
-       DECLARE_MAC_BUF(mac);
 
        connected =
                val == HFA384X_LINKSTATUS_CONNECTED ||
@@ -425,10 +422,9 @@ static void handle_info_queue_linkstatus(local_info_t *local)
                printk(KERN_DEBUG "%s: could not read CURRENTBSSID after "
                       "LinkStatus event\n", local->dev->name);
        } else {
-               PDEBUG(DEBUG_EXTRA, "%s: LinkStatus: BSSID="
-                      "%s\n",
+               PDEBUG(DEBUG_EXTRA, "%s: LinkStatus: BSSID=%pM\n",
                       local->dev->name,
-                      print_mac(mac, (unsigned char *) local->bssid));
+                      (unsigned char *) local->bssid);
                if (local->wds_type & HOSTAP_WDS_AP_CLIENT)
                        hostap_add_sta(local->ap, local->bssid);
        }
index 3f8b1d7036e51467879b1dcaf44a895223325c11..2318c5df7a08876d532d50faed32a65fd5769100 100644 (file)
@@ -664,7 +664,6 @@ static int hostap_join_ap(struct net_device *dev)
        unsigned long flags;
        int i;
        struct hfa384x_hostscan_result *entry;
-       DECLARE_MAC_BUF(mac);
 
        iface = netdev_priv(dev);
        local = iface->local;
@@ -686,14 +685,13 @@ static int hostap_join_ap(struct net_device *dev)
 
        if (local->func->set_rid(dev, HFA384X_RID_JOINREQUEST, &req,
                                 sizeof(req))) {
-               printk(KERN_DEBUG "%s: JoinRequest %s"
-                      " failed\n",
-                      dev->name, print_mac(mac, local->preferred_ap));
+               printk(KERN_DEBUG "%s: JoinRequest %pM failed\n",
+                      dev->name, local->preferred_ap);
                return -1;
        }
 
-       printk(KERN_DEBUG "%s: Trying to join BSSID %s\n",
-              dev->name, print_mac(mac, local->preferred_ap));
+       printk(KERN_DEBUG "%s: Trying to join BSSID %pM\n",
+              dev->name, local->preferred_ap);
 
        return 0;
 }
@@ -3701,10 +3699,8 @@ static int prism2_ioctl_set_assoc_ap_addr(local_info_t *local,
                                          struct prism2_hostapd_param *param,
                                          int param_len)
 {
-       DECLARE_MAC_BUF(mac);
-       printk(KERN_DEBUG "%ssta: associated as client with AP "
-              "%s\n",
-              local->dev->name, print_mac(mac, param->sta_addr));
+       printk(KERN_DEBUG "%ssta: associated as client with AP %pM\n",
+              local->dev->name, param->sta_addr);
        memcpy(local->assoc_ap_addr, param->sta_addr, ETH_ALEN);
        return 0;
 }
index 756ab56c1f4034de12c77b2ba067987aebbcd555..4c36eb2fafd1c33ea01535ca48fbc3253a778fea 100644 (file)
@@ -530,10 +530,6 @@ int hostap_set_auth_algs(local_info_t *local)
 void hostap_dump_rx_header(const char *name, const struct hfa384x_rx_frame *rx)
 {
        u16 status, fc;
-       DECLARE_MAC_BUF(mac);
-       DECLARE_MAC_BUF(mac2);
-       DECLARE_MAC_BUF(mac3);
-       DECLARE_MAC_BUF(mac4);
 
        status = __le16_to_cpu(rx->status);
 
@@ -552,12 +548,11 @@ void hostap_dump_rx_header(const char *name, const struct hfa384x_rx_frame *rx)
               fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
               fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
 
-       printk(KERN_DEBUG "   A1=%s A2=%s A3=%s A4=%s\n",
-              print_mac(mac, rx->addr1), print_mac(mac2, rx->addr2),
-              print_mac(mac3, rx->addr3), print_mac(mac4, rx->addr4));
+       printk(KERN_DEBUG "   A1=%pM A2=%pM A3=%pM A4=%pM\n",
+              rx->addr1, rx->addr2, rx->addr3, rx->addr4);
 
-       printk(KERN_DEBUG "   dst=%s src=%s len=%d\n",
-              print_mac(mac, rx->dst_addr), print_mac(mac2, rx->src_addr),
+       printk(KERN_DEBUG "   dst=%pM src=%pM len=%d\n",
+              rx->dst_addr, rx->src_addr,
               __be16_to_cpu(rx->len));
 }
 
@@ -565,10 +560,6 @@ void hostap_dump_rx_header(const char *name, const struct hfa384x_rx_frame *rx)
 void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx)
 {
        u16 fc;
-       DECLARE_MAC_BUF(mac);
-       DECLARE_MAC_BUF(mac2);
-       DECLARE_MAC_BUF(mac3);
-       DECLARE_MAC_BUF(mac4);
 
        printk(KERN_DEBUG "%s: TX status=0x%04x retry_count=%d tx_rate=%d "
               "tx_control=0x%04x; jiffies=%ld\n",
@@ -584,12 +575,11 @@ void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx)
               fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
               fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
 
-       printk(KERN_DEBUG "   A1=%s A2=%s A3=%s A4=%s\n",
-              print_mac(mac, tx->addr1), print_mac(mac2, tx->addr2),
-              print_mac(mac3, tx->addr3), print_mac(mac4, tx->addr4));
+       printk(KERN_DEBUG "   A1=%pM A2=%pM A3=%pM A4=%pM\n",
+              tx->addr1, tx->addr2, tx->addr3, tx->addr4);
 
-       printk(KERN_DEBUG "   dst=%s src=%s len=%d\n",
-              print_mac(mac, tx->dst_addr), print_mac(mac2, tx->src_addr),
+       printk(KERN_DEBUG "   dst=%pM src=%pM len=%d\n",
+              tx->dst_addr, tx->src_addr,
               __be16_to_cpu(tx->len));
 }
 
index 3a874fc621d386a3c7ccfb160c54d443ec2c664d..8fdd41f4b4f2121a65f70d322bfe3951d1e233e0 100644 (file)
@@ -312,7 +312,7 @@ static int prism2_pci_probe(struct pci_dev *pdev,
                goto err_out_disable;
        }
 
-       mem = ioremap(phymem, pci_resource_len(pdev, 0));
+       mem = pci_ioremap_bar(pdev, 0);
        if (mem == NULL) {
                printk(KERN_ERR "prism2: Cannot remap PCI memory region\n") ;
                goto fail;
index b03536008ad98df43218fe8a9aef9e7b05fb0fe2..ae7d3caf3dae852b43b91ef77f784d7d6c0b7e60 100644 (file)
@@ -106,7 +106,6 @@ static int prism2_wds_proc_read(char *page, char **start, off_t off,
        local_info_t *local = (local_info_t *) data;
        struct list_head *ptr;
        struct hostap_interface *iface;
-       DECLARE_MAC_BUF(mac);
 
        if (off > PROC_LIMIT) {
                *eof = 1;
@@ -118,9 +117,9 @@ static int prism2_wds_proc_read(char *page, char **start, off_t off,
                iface = list_entry(ptr, struct hostap_interface, list);
                if (iface->type != HOSTAP_INTERFACE_WDS)
                        continue;
-               p += sprintf(p, "%s\t%s\n",
+               p += sprintf(p, "%s\t%pM\n",
                             iface->dev->name,
-                            print_mac(mac, iface->u.wds.remote_addr));
+                            iface->u.wds.remote_addr);
                if ((p - page) > PROC_LIMIT) {
                        printk(KERN_DEBUG "%s: wds proc did not fit\n",
                               local->dev->name);
@@ -148,7 +147,6 @@ static int prism2_bss_list_proc_read(char *page, char **start, off_t off,
        struct list_head *ptr;
        struct hostap_bss_info *bss;
        int i;
-       DECLARE_MAC_BUF(mac);
 
        if (off > PROC_LIMIT) {
                *eof = 1;
@@ -160,8 +158,8 @@ static int prism2_bss_list_proc_read(char *page, char **start, off_t off,
        spin_lock_bh(&local->lock);
        list_for_each(ptr, &local->bss_list) {
                bss = list_entry(ptr, struct hostap_bss_info, list);
-               p += sprintf(p, "%s\t%lu\t%u\t0x%x\t",
-                            print_mac(mac, bss->bssid), bss->last_update,
+               p += sprintf(p, "%pM\t%lu\t%u\t0x%x\t",
+                            bss->bssid, bss->last_update,
                             bss->count, bss->capab_info);
                for (i = 0; i < bss->ssid_len; i++) {
                        p += sprintf(p, "%c",
@@ -314,7 +312,6 @@ static int prism2_scan_results_proc_read(char *page, char **start, off_t off,
        int entry, i, len, total = 0;
        struct hfa384x_hostscan_result *scanres;
        u8 *pos;
-       DECLARE_MAC_BUF(mac);
 
        p += sprintf(p, "CHID ANL SL BcnInt Capab Rate BSSID ATIM SupRates "
                     "SSID\n");
@@ -332,14 +329,14 @@ static int prism2_scan_results_proc_read(char *page, char **start, off_t off,
                if ((p - page) > (PAGE_SIZE - 200))
                        break;
 
-               p += sprintf(p, "%d %d %d %d 0x%02x %d %s %d ",
+               p += sprintf(p, "%d %d %d %d 0x%02x %d %pM %d ",
                             le16_to_cpu(scanres->chid),
                             (s16) le16_to_cpu(scanres->anl),
                             (s16) le16_to_cpu(scanres->sl),
                             le16_to_cpu(scanres->beacon_interval),
                             le16_to_cpu(scanres->capability),
                             le16_to_cpu(scanres->rate),
-                            print_mac(mac, scanres->bssid),
+                            scanres->bssid,
                             le16_to_cpu(scanres->atim));
 
                pos = scanres->sup_rates;
index a68f97c3935947a59990d188f7d95d05b19c600c..d2c7a56b8b598db01fcdead58a0b9f0b461eeda8 100644 (file)
@@ -822,7 +822,7 @@ struct local_info {
        int last_scan_results_count;
        enum { PRISM2_SCAN, PRISM2_HOSTSCAN } last_scan_type;
        struct work_struct info_queue;
-       long pending_info; /* bit field of pending info_queue items */
+       unsigned long pending_info; /* bit field of pending info_queue items */
 #define PRISM2_INFO_PENDING_LINKSTATUS 0
 #define PRISM2_INFO_PENDING_SCANRESULTS 1
        int prev_link_status; /* previous received LinkStatus info */
index bca74811bc7ff34dd946d6ef0c5b852b54165935..062c9f2803042ebadc0ed22725b49be7c89c4149 100644 (file)
@@ -163,6 +163,8 @@ that only one external action is invoked at a time.
 #include <linux/ctype.h>
 #include <linux/pm_qos_params.h>
 
+#include <net/lib80211.h>
+
 #include "ipw2100.h"
 
 #define IPW2100_VERSION "git-1.2.2"
@@ -185,7 +187,7 @@ MODULE_LICENSE("GPL");
 static int debug = 0;
 static int mode = 0;
 static int channel = 0;
-static int associate = 1;
+static int associate = 0;
 static int disable = 0;
 #ifdef CONFIG_PM
 static struct ipw2100_fw ipw2100_firmware;
@@ -201,7 +203,7 @@ module_param(disable, int, 0444);
 MODULE_PARM_DESC(debug, "debug level");
 MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
 MODULE_PARM_DESC(channel, "channel");
-MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
+MODULE_PARM_DESC(associate, "auto associate when scanning (default off)");
 MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
 
 static u32 ipw2100_debug_level = IPW_DL_NONE;
@@ -1914,7 +1916,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
        u32 chan;
        char *txratename;
        u8 bssid[ETH_ALEN];
-       DECLARE_MAC_BUF(mac);
+       DECLARE_SSID_BUF(ssid);
 
        /*
         * TBD: BSSID is usually 00:00:00:00:00:00 here and not
@@ -1975,10 +1977,9 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
                break;
        }
 
-       IPW_DEBUG_INFO("%s: Associated with '%s' at %s, channel %d (BSSID="
-                      "%s)\n",
-                      priv->net_dev->name, escape_essid(essid, essid_len),
-                      txratename, chan, print_mac(mac, bssid));
+       IPW_DEBUG_INFO("%s: Associated with '%s' at %s, channel %d (BSSID=%pM)\n",
+                      priv->net_dev->name, print_ssid(ssid, essid, essid_len),
+                      txratename, chan, bssid);
 
        /* now we copy read ssid into dev */
        if (!(priv->config & CFG_STATIC_ESSID)) {
@@ -2004,8 +2005,9 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
                .host_command_length = ssid_len
        };
        int err;
+       DECLARE_SSID_BUF(ssid);
 
-       IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len));
+       IPW_DEBUG_HC("SSID: '%s'\n", print_ssid(ssid, essid, ssid_len));
 
        if (ssid_len)
                memcpy(cmd.host_command_parameters, essid, ssid_len);
@@ -2046,12 +2048,12 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
 
 static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
 {
-       DECLARE_MAC_BUF(mac);
+       DECLARE_SSID_BUF(ssid);
 
        IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
-                 "disassociated: '%s' %s \n",
-                 escape_essid(priv->essid, priv->essid_len),
-                 print_mac(mac, priv->bssid));
+                 "disassociated: '%s' %pM \n",
+                 print_ssid(ssid, priv->essid, priv->essid_len),
+                 priv->bssid);
 
        priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
 
@@ -4058,7 +4060,6 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
        char *out = buf;
        int length;
        int ret;
-       DECLARE_MAC_BUF(mac);
 
        if (priv->status & STATUS_RF_KILL_MASK)
                return 0;
@@ -4086,7 +4087,7 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
                               __LINE__);
 
        out += sprintf(out, "ESSID: %s\n", essid);
-       out += sprintf(out, "BSSID:   %s\n", print_mac(mac, bssid));
+       out += sprintf(out, "BSSID:   %pM\n", bssid);
        out += sprintf(out, "Channel: %d\n", chan);
 
        return out - buf;
@@ -4662,7 +4663,6 @@ static int ipw2100_read_mac_address(struct ipw2100_priv *priv)
 {
        u32 length = ETH_ALEN;
        u8 addr[ETH_ALEN];
-       DECLARE_MAC_BUF(mac);
 
        int err;
 
@@ -4673,8 +4673,7 @@ static int ipw2100_read_mac_address(struct ipw2100_priv *priv)
        }
 
        memcpy(priv->net_dev->dev_addr, addr, ETH_ALEN);
-       IPW_DEBUG_INFO("card MAC is %s\n",
-                      print_mac(mac, priv->net_dev->dev_addr));
+       IPW_DEBUG_INFO("card MAC is %pM\n", priv->net_dev->dev_addr);
 
        return 0;
 }
@@ -5053,10 +5052,8 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 * bssid,
        int err;
 
 #ifdef CONFIG_IPW2100_DEBUG
-       DECLARE_MAC_BUF(mac);
        if (bssid != NULL)
-               IPW_DEBUG_HC("MANDATORY_BSSID: %s\n",
-                            print_mac(mac, bssid));
+               IPW_DEBUG_HC("MANDATORY_BSSID: %pM\n", bssid);
        else
                IPW_DEBUG_HC("MANDATORY_BSSID: <clear>\n");
 #endif
@@ -6905,7 +6902,6 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
        static const unsigned char off[] = {
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        };
-       DECLARE_MAC_BUF(mac);
 
        // sanity checks
        if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
@@ -6931,8 +6927,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
 
        err = ipw2100_set_mandatory_bssid(priv, wrqu->ap_addr.sa_data, 0);
 
-       IPW_DEBUG_WX("SET BSSID -> %s\n",
-                    print_mac(mac, wrqu->ap_addr.sa_data));
+       IPW_DEBUG_WX("SET BSSID -> %pM\n", wrqu->ap_addr.sa_data);
 
       done:
        mutex_unlock(&priv->action_mutex);
@@ -6948,7 +6943,6 @@ static int ipw2100_wx_get_wap(struct net_device *dev,
         */
 
        struct ipw2100_priv *priv = ieee80211_priv(dev);
-       DECLARE_MAC_BUF(mac);
 
        /* If we are associated, trying to associate, or have a statically
         * configured BSSID then return that; otherwise return ANY */
@@ -6958,8 +6952,7 @@ static int ipw2100_wx_get_wap(struct net_device *dev,
        } else
                memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
 
-       IPW_DEBUG_WX("Getting WAP BSSID: %s\n",
-                    print_mac(mac, wrqu->ap_addr.sa_data));
+       IPW_DEBUG_WX("Getting WAP BSSID: %pM\n", wrqu->ap_addr.sa_data);
        return 0;
 }
 
@@ -6971,6 +6964,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
        char *essid = "";       /* ANY */
        int length = 0;
        int err = 0;
+       DECLARE_SSID_BUF(ssid);
 
        mutex_lock(&priv->action_mutex);
        if (!(priv->status & STATUS_INITIALIZED)) {
@@ -7000,8 +6994,8 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
                goto done;
        }
 
-       IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", escape_essid(essid, length),
-                    length);
+       IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n",
+                    print_ssid(ssid, essid, length), length);
 
        priv->essid_len = length;
        memcpy(priv->essid, essid, priv->essid_len);
@@ -7022,12 +7016,13 @@ static int ipw2100_wx_get_essid(struct net_device *dev,
         */
 
        struct ipw2100_priv *priv = ieee80211_priv(dev);
+       DECLARE_SSID_BUF(ssid);
 
        /* If we are associated, trying to associate, or have a statically
         * configured ESSID then return that; otherwise return ANY */
        if (priv->config & CFG_STATIC_ESSID || priv->status & STATUS_ASSOCIATED) {
                IPW_DEBUG_WX("Getting essid: '%s'\n",
-                            escape_essid(priv->essid, priv->essid_len));
+                            print_ssid(ssid, priv->essid, priv->essid_len));
                memcpy(extra, priv->essid, priv->essid_len);
                wrqu->essid.length = priv->essid_len;
                wrqu->essid.flags = 1;  /* active */
index dcce3542d5a771d9eb24753d8d464854bb4e6639..051ae92d8b65cd4253f39c27ecf5918b8ce157da 100644 (file)
@@ -87,7 +87,7 @@ static int channel = 0;
 static int mode = 0;
 
 static u32 ipw_debug_level;
-static int associate = 1;
+static int associate;
 static int auto_create = 1;
 static int led = 0;
 static int disable = 0;
@@ -2265,8 +2265,8 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
                return -1;
        }
 
-       IPW_DEBUG_INFO("%s: Setting MAC to %s\n",
-                      priv->net_dev->name, print_mac(mac, mac));
+       IPW_DEBUG_INFO("%s: Setting MAC to %pM\n",
+                      priv->net_dev->name, mac);
 
        return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac);
 }
@@ -3812,7 +3812,6 @@ static u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid)
 {
        struct ipw_station_entry entry;
        int i;
-       DECLARE_MAC_BUF(mac);
 
        for (i = 0; i < priv->num_stations; i++) {
                if (!memcmp(priv->stations[i], bssid, ETH_ALEN)) {
@@ -3829,7 +3828,7 @@ static u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid)
        if (i == MAX_STATIONS)
                return IPW_INVALID_STATION;
 
-       IPW_DEBUG_SCAN("Adding AdHoc station: %s\n", print_mac(mac, bssid));
+       IPW_DEBUG_SCAN("Adding AdHoc station: %pM\n", bssid);
 
        entry.reserved = 0;
        entry.support_mode = 0;
@@ -3856,7 +3855,6 @@ static u8 ipw_find_station(struct ipw_priv *priv, u8 * bssid)
 static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
 {
        int err;
-       DECLARE_MAC_BUF(mac);
 
        if (priv->status & STATUS_ASSOCIATING) {
                IPW_DEBUG_ASSOC("Disassociating while associating.\n");
@@ -3869,9 +3867,9 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
                return;
        }
 
-       IPW_DEBUG_ASSOC("Disassocation attempt from %s "
+       IPW_DEBUG_ASSOC("Disassocation attempt from %pM "
                        "on channel %d.\n",
-                       print_mac(mac, priv->assoc_request.bssid),
+                       priv->assoc_request.bssid,
                        priv->assoc_request.channel);
 
        priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
@@ -4397,7 +4395,7 @@ static void handle_scan_event(struct ipw_priv *priv)
 static void ipw_rx_notification(struct ipw_priv *priv,
                                       struct ipw_rx_notification *notif)
 {
-       DECLARE_MAC_BUF(mac);
+       DECLARE_SSID_BUF(ssid);
        u16 size = le16_to_cpu(notif->size);
        notif->size = le16_to_cpu(notif->size);
 
@@ -4411,11 +4409,10 @@ static void ipw_rx_notification(struct ipw_priv *priv,
                        case CMAS_ASSOCIATED:{
                                        IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
                                                  IPW_DL_ASSOC,
-                                                 "associated: '%s' %s"
-                                                 " \n",
-                                                 escape_essid(priv->essid,
-                                                              priv->essid_len),
-                                                 print_mac(mac, priv->bssid));
+                                                 "associated: '%s' %pM \n",
+                                                 print_ssid(ssid, priv->essid,
+                                                            priv->essid_len),
+                                                 priv->bssid);
 
                                        switch (priv->ieee->iw_mode) {
                                        case IW_MODE_INFRA:
@@ -4449,7 +4446,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
 
 #ifdef CONFIG_IPW2200_QOS
 #define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \
-                        le16_to_cpu(((struct ieee80211_hdr *)(x))->frame_ctl))
+                        le16_to_cpu(((struct ieee80211_hdr *)(x))->frame_control))
                                        if ((priv->status & STATUS_AUTH) &&
                                            (IPW_GET_PACKET_STYPE(&notif->u.raw)
                                             == IEEE80211_STYPE_ASSOC_RESP)) {
@@ -4492,13 +4489,14 @@ static void ipw_rx_notification(struct ipw_priv *priv,
                                                          IPW_DL_STATE |
                                                          IPW_DL_ASSOC,
                                                          "deauthenticated: '%s' "
-                                                         "%s"
+                                                         "%pM"
                                                          ": (0x%04X) - %s \n",
-                                                         escape_essid(priv->
-                                                                      essid,
-                                                                      priv->
-                                                                      essid_len),
-                                                         print_mac(mac, priv->bssid),
+                                                         print_ssid(ssid,
+                                                                    priv->
+                                                                    essid,
+                                                                    priv->
+                                                                    essid_len),
+                                                         priv->bssid,
                                                          le16_to_cpu(auth->status),
                                                          ipw_get_status_code
                                                          (le16_to_cpu
@@ -4515,11 +4513,10 @@ static void ipw_rx_notification(struct ipw_priv *priv,
 
                                        IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
                                                  IPW_DL_ASSOC,
-                                                 "authenticated: '%s' %s"
-                                                 "\n",
-                                                 escape_essid(priv->essid,
-                                                              priv->essid_len),
-                                                 print_mac(mac, priv->bssid));
+                                                 "authenticated: '%s' %pM\n",
+                                                 print_ssid(ssid, priv->essid,
+                                                            priv->essid_len),
+                                                 priv->bssid);
                                        break;
                                }
 
@@ -4544,11 +4541,10 @@ static void ipw_rx_notification(struct ipw_priv *priv,
 
                                        IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
                                                  IPW_DL_ASSOC,
-                                                 "disassociated: '%s' %s"
-                                                 " \n",
-                                                 escape_essid(priv->essid,
-                                                              priv->essid_len),
-                                                 print_mac(mac, priv->bssid));
+                                                 "disassociated: '%s' %pM \n",
+                                                 print_ssid(ssid, priv->essid,
+                                                            priv->essid_len),
+                                                 priv->bssid);
 
                                        priv->status &=
                                            ~(STATUS_DISASSOCIATING |
@@ -4583,10 +4579,10 @@ static void ipw_rx_notification(struct ipw_priv *priv,
                        switch (auth->state) {
                        case CMAS_AUTHENTICATED:
                                IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
-                                         "authenticated: '%s' %s \n",
-                                         escape_essid(priv->essid,
-                                                      priv->essid_len),
-                                         print_mac(mac, priv->bssid));
+                                         "authenticated: '%s' %pM \n",
+                                         print_ssid(ssid, priv->essid,
+                                                    priv->essid_len),
+                                         priv->bssid);
                                priv->status |= STATUS_AUTH;
                                break;
 
@@ -4602,10 +4598,10 @@ static void ipw_rx_notification(struct ipw_priv *priv,
                                }
                                IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
                                          IPW_DL_ASSOC,
-                                         "deauthenticated: '%s' %s\n",
-                                         escape_essid(priv->essid,
-                                                      priv->essid_len),
-                                         print_mac(mac, priv->bssid));
+                                         "deauthenticated: '%s' %pM\n",
+                                         print_ssid(ssid, priv->essid,
+                                                    priv->essid_len),
+                                         priv->bssid);
 
                                priv->status &= ~(STATUS_ASSOCIATING |
                                                  STATUS_AUTH |
@@ -5429,27 +5425,17 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
                                  int roaming)
 {
        struct ipw_supported_rates rates;
-       DECLARE_MAC_BUF(mac);
-       DECLARE_MAC_BUF(mac2);
+       DECLARE_SSID_BUF(ssid);
 
        /* Verify that this network's capability is compatible with the
         * current mode (AdHoc or Infrastructure) */
        if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
             !(network->capability & WLAN_CAPABILITY_IBSS))) {
-               IPW_DEBUG_MERGE("Network '%s (%s)' excluded due to "
+               IPW_DEBUG_MERGE("Network '%s (%pM)' excluded due to "
                                "capability mismatch.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid));
-               return 0;
-       }
-
-       /* If we do not have an ESSID for this AP, we can not associate with
-        * it */
-       if (network->flags & NETWORK_EMPTY_ESSID) {
-               IPW_DEBUG_MERGE("Network '%s (%s)' excluded "
-                               "because of hidden ESSID.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid));
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid);
                return 0;
        }
 
@@ -5459,11 +5445,11 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
                if ((network->ssid_len != match->network->ssid_len) ||
                    memcmp(network->ssid, match->network->ssid,
                           network->ssid_len)) {
-                       IPW_DEBUG_MERGE("Network '%s (%s)' excluded "
+                       IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
                                        "because of non-network ESSID.\n",
-                                       escape_essid(network->ssid,
-                                                    network->ssid_len),
-                                       print_mac(mac, network->bssid));
+                                       print_ssid(ssid, network->ssid,
+                                                  network->ssid_len),
+                                       network->bssid);
                        return 0;
                }
        } else {
@@ -5476,13 +5462,14 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
                        char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
 
                        strncpy(escaped,
-                               escape_essid(network->ssid, network->ssid_len),
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
                                sizeof(escaped));
-                       IPW_DEBUG_MERGE("Network '%s (%s)' excluded "
+                       IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
                                        "because of ESSID mismatch: '%s'.\n",
-                                       escaped, print_mac(mac, network->bssid),
-                                       escape_essid(priv->essid,
-                                                    priv->essid_len));
+                                       escaped, network->bssid,
+                                       print_ssid(ssid, priv->essid,
+                                                  priv->essid_len));
                        return 0;
                }
        }
@@ -5493,24 +5480,25 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
        if (network->time_stamp[0] < match->network->time_stamp[0]) {
                IPW_DEBUG_MERGE("Network '%s excluded because newer than "
                                "current network.\n",
-                               escape_essid(match->network->ssid,
-                                            match->network->ssid_len));
+                               print_ssid(ssid, match->network->ssid,
+                                          match->network->ssid_len));
                return 0;
        } else if (network->time_stamp[1] < match->network->time_stamp[1]) {
                IPW_DEBUG_MERGE("Network '%s excluded because newer than "
                                "current network.\n",
-                               escape_essid(match->network->ssid,
-                                            match->network->ssid_len));
+                               print_ssid(ssid, match->network->ssid,
+                                          match->network->ssid_len));
                return 0;
        }
 
        /* Now go through and see if the requested network is valid... */
        if (priv->ieee->scan_age != 0 &&
            time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
-               IPW_DEBUG_MERGE("Network '%s (%s)' excluded "
+               IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
                                "because of age: %ums.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid),
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid,
                                jiffies_to_msecs(jiffies -
                                                 network->last_scanned));
                return 0;
@@ -5518,10 +5506,11 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
 
        if ((priv->config & CFG_STATIC_CHANNEL) &&
            (network->channel != priv->channel)) {
-               IPW_DEBUG_MERGE("Network '%s (%s)' excluded "
+               IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
                                "because of channel mismatch: %d != %d.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid),
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid,
                                network->channel, priv->channel);
                return 0;
        }
@@ -5529,10 +5518,11 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
        /* Verify privacy compatability */
        if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
            ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
-               IPW_DEBUG_MERGE("Network '%s (%s)' excluded "
+               IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
                                "because of privacy mismatch: %s != %s.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid),
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid,
                                priv->
                                capability & CAP_PRIVACY_ON ? "on" : "off",
                                network->
@@ -5542,41 +5532,44 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
        }
 
        if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
-               IPW_DEBUG_MERGE("Network '%s (%s)' excluded "
-                               "because of the same BSSID match: %s"
-                               ".\n", escape_essid(network->ssid,
-                                                   network->ssid_len),
-                               print_mac(mac, network->bssid),
-                               print_mac(mac2, priv->bssid));
+               IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
+                               "because of the same BSSID match: %pM"
+                               ".\n", print_ssid(ssid, network->ssid,
+                                                 network->ssid_len),
+                               network->bssid,
+                               priv->bssid);
                return 0;
        }
 
        /* Filter out any incompatible freq / mode combinations */
        if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
-               IPW_DEBUG_MERGE("Network '%s (%s)' excluded "
+               IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
                                "because of invalid frequency/mode "
                                "combination.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid));
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid);
                return 0;
        }
 
        /* Ensure that the rates supported by the driver are compatible with
         * this AP, including verification of basic rates (mandatory) */
        if (!ipw_compatible_rates(priv, network, &rates)) {
-               IPW_DEBUG_MERGE("Network '%s (%s)' excluded "
+               IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
                                "because configured rate mask excludes "
                                "AP mandatory rate.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid));
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid);
                return 0;
        }
 
        if (rates.num_rates == 0) {
-               IPW_DEBUG_MERGE("Network '%s (%s)' excluded "
+               IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
                                "because of no compatible rates.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid));
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid);
                return 0;
        }
 
@@ -5587,15 +5580,16 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
        /* Set up 'new' AP to this network */
        ipw_copy_rates(&match->rates, &rates);
        match->network = network;
-       IPW_DEBUG_MERGE("Network '%s (%s)' is a viable match.\n",
-                       escape_essid(network->ssid, network->ssid_len),
-                       print_mac(mac, network->bssid));
+       IPW_DEBUG_MERGE("Network '%s (%pM)' is a viable match.\n",
+                       print_ssid(ssid, network->ssid, network->ssid_len),
+                       network->bssid);
 
        return 1;
 }
 
 static void ipw_merge_adhoc_network(struct work_struct *work)
 {
+       DECLARE_SSID_BUF(ssid);
        struct ipw_priv *priv =
                container_of(work, struct ipw_priv, merge_networks);
        struct ieee80211_network *network = NULL;
@@ -5626,8 +5620,8 @@ static void ipw_merge_adhoc_network(struct work_struct *work)
                mutex_lock(&priv->mutex);
                if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
                        IPW_DEBUG_MERGE("remove network %s\n",
-                                       escape_essid(priv->essid,
-                                                    priv->essid_len));
+                                       print_ssid(ssid, priv->essid,
+                                                  priv->essid_len));
                        ipw_remove_current_network(priv);
                }
 
@@ -5643,7 +5637,7 @@ static int ipw_best_network(struct ipw_priv *priv,
                            struct ieee80211_network *network, int roaming)
 {
        struct ipw_supported_rates rates;
-       DECLARE_MAC_BUF(mac);
+       DECLARE_SSID_BUF(ssid);
 
        /* Verify that this network's capability is compatible with the
         * current mode (AdHoc or Infrastructure) */
@@ -5651,20 +5645,11 @@ static int ipw_best_network(struct ipw_priv *priv,
             !(network->capability & WLAN_CAPABILITY_ESS)) ||
            (priv->ieee->iw_mode == IW_MODE_ADHOC &&
             !(network->capability & WLAN_CAPABILITY_IBSS))) {
-               IPW_DEBUG_ASSOC("Network '%s (%s)' excluded due to "
+               IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded due to "
                                "capability mismatch.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid));
-               return 0;
-       }
-
-       /* If we do not have an ESSID for this AP, we can not associate with
-        * it */
-       if (network->flags & NETWORK_EMPTY_ESSID) {
-               IPW_DEBUG_ASSOC("Network '%s (%s)' excluded "
-                               "because of hidden ESSID.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid));
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid);
                return 0;
        }
 
@@ -5674,11 +5659,11 @@ static int ipw_best_network(struct ipw_priv *priv,
                if ((network->ssid_len != match->network->ssid_len) ||
                    memcmp(network->ssid, match->network->ssid,
                           network->ssid_len)) {
-                       IPW_DEBUG_ASSOC("Network '%s (%s)' excluded "
+                       IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
                                        "because of non-network ESSID.\n",
-                                       escape_essid(network->ssid,
-                                                    network->ssid_len),
-                                       print_mac(mac, network->bssid));
+                                       print_ssid(ssid, network->ssid,
+                                                  network->ssid_len),
+                                       network->bssid);
                        return 0;
                }
        } else {
@@ -5690,13 +5675,14 @@ static int ipw_best_network(struct ipw_priv *priv,
                            min(network->ssid_len, priv->essid_len)))) {
                        char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
                        strncpy(escaped,
-                               escape_essid(network->ssid, network->ssid_len),
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
                                sizeof(escaped));
-                       IPW_DEBUG_ASSOC("Network '%s (%s)' excluded "
+                       IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
                                        "because of ESSID mismatch: '%s'.\n",
-                                       escaped, print_mac(mac, network->bssid),
-                                       escape_essid(priv->essid,
-                                                    priv->essid_len));
+                                       escaped, network->bssid,
+                                       print_ssid(ssid, priv->essid,
+                                                  priv->essid_len));
                        return 0;
                }
        }
@@ -5706,14 +5692,14 @@ static int ipw_best_network(struct ipw_priv *priv,
        if (match->network && match->network->stats.rssi > network->stats.rssi) {
                char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
                strncpy(escaped,
-                       escape_essid(network->ssid, network->ssid_len),
+                       print_ssid(ssid, network->ssid, network->ssid_len),
                        sizeof(escaped));
-               IPW_DEBUG_ASSOC("Network '%s (%s)' excluded because "
-                               "'%s (%s)' has a stronger signal.\n",
-                               escaped, print_mac(mac, network->bssid),
-                               escape_essid(match->network->ssid,
-                                            match->network->ssid_len),
-                               print_mac(mac, match->network->bssid));
+               IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded because "
+                               "'%s (%pM)' has a stronger signal.\n",
+                               escaped, network->bssid,
+                               print_ssid(ssid, match->network->ssid,
+                                          match->network->ssid_len),
+                               match->network->bssid);
                return 0;
        }
 
@@ -5721,11 +5707,12 @@ static int ipw_best_network(struct ipw_priv *priv,
         * last 3 seconds, do not try and associate again... */
        if (network->last_associate &&
            time_after(network->last_associate + (HZ * 3UL), jiffies)) {
-               IPW_DEBUG_ASSOC("Network '%s (%s)' excluded "
+               IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
                                "because of storming (%ums since last "
                                "assoc attempt).\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid),
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid,
                                jiffies_to_msecs(jiffies -
                                                 network->last_associate));
                return 0;
@@ -5734,10 +5721,11 @@ static int ipw_best_network(struct ipw_priv *priv,
        /* Now go through and see if the requested network is valid... */
        if (priv->ieee->scan_age != 0 &&
            time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
-               IPW_DEBUG_ASSOC("Network '%s (%s)' excluded "
+               IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
                                "because of age: %ums.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid),
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid,
                                jiffies_to_msecs(jiffies -
                                                 network->last_scanned));
                return 0;
@@ -5745,10 +5733,11 @@ static int ipw_best_network(struct ipw_priv *priv,
 
        if ((priv->config & CFG_STATIC_CHANNEL) &&
            (network->channel != priv->channel)) {
-               IPW_DEBUG_ASSOC("Network '%s (%s)' excluded "
+               IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
                                "because of channel mismatch: %d != %d.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid),
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid,
                                network->channel, priv->channel);
                return 0;
        }
@@ -5756,10 +5745,11 @@ static int ipw_best_network(struct ipw_priv *priv,
        /* Verify privacy compatability */
        if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
            ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
-               IPW_DEBUG_ASSOC("Network '%s (%s)' excluded "
+               IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
                                "because of privacy mismatch: %s != %s.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid),
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid,
                                priv->capability & CAP_PRIVACY_ON ? "on" :
                                "off",
                                network->capability &
@@ -5769,48 +5759,53 @@ static int ipw_best_network(struct ipw_priv *priv,
 
        if ((priv->config & CFG_STATIC_BSSID) &&
            memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
-               IPW_DEBUG_ASSOC("Network '%s (%s)' excluded "
-                               "because of BSSID mismatch: %s.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid), print_mac(mac, priv->bssid));
+               IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
+                               "because of BSSID mismatch: %pM.\n",
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid, priv->bssid);
                return 0;
        }
 
        /* Filter out any incompatible freq / mode combinations */
        if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
-               IPW_DEBUG_ASSOC("Network '%s (%s)' excluded "
+               IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
                                "because of invalid frequency/mode "
                                "combination.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid));
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid);
                return 0;
        }
 
        /* Filter out invalid channel in current GEO */
        if (!ieee80211_is_valid_channel(priv->ieee, network->channel)) {
-               IPW_DEBUG_ASSOC("Network '%s (%s)' excluded "
+               IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
                                "because of invalid channel in current GEO\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid));
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid);
                return 0;
        }
 
        /* Ensure that the rates supported by the driver are compatible with
         * this AP, including verification of basic rates (mandatory) */
        if (!ipw_compatible_rates(priv, network, &rates)) {
-               IPW_DEBUG_ASSOC("Network '%s (%s)' excluded "
+               IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
                                "because configured rate mask excludes "
                                "AP mandatory rate.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid));
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid);
                return 0;
        }
 
        if (rates.num_rates == 0) {
-               IPW_DEBUG_ASSOC("Network '%s (%s)' excluded "
+               IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
                                "because of no compatible rates.\n",
-                               escape_essid(network->ssid, network->ssid_len),
-                               print_mac(mac, network->bssid));
+                               print_ssid(ssid, network->ssid,
+                                          network->ssid_len),
+                               network->bssid);
                return 0;
        }
 
@@ -5822,9 +5817,9 @@ static int ipw_best_network(struct ipw_priv *priv,
        ipw_copy_rates(&match->rates, &rates);
        match->network = network;
 
-       IPW_DEBUG_ASSOC("Network '%s (%s)' is a viable match.\n",
-                       escape_essid(network->ssid, network->ssid_len),
-                       print_mac(mac, network->bssid));
+       IPW_DEBUG_ASSOC("Network '%s (%pM)' is a viable match.\n",
+                       print_ssid(ssid, network->ssid, network->ssid_len),
+                       network->bssid);
 
        return 1;
 }
@@ -6066,7 +6061,7 @@ static void ipw_bg_adhoc_check(struct work_struct *work)
 
 static void ipw_debug_config(struct ipw_priv *priv)
 {
-       DECLARE_MAC_BUF(mac);
+       DECLARE_SSID_BUF(ssid);
        IPW_DEBUG_INFO("Scan completed, no valid APs matched "
                       "[CFG 0x%08X]\n", priv->config);
        if (priv->config & CFG_STATIC_CHANNEL)
@@ -6075,12 +6070,11 @@ static void ipw_debug_config(struct ipw_priv *priv)
                IPW_DEBUG_INFO("Channel unlocked.\n");
        if (priv->config & CFG_STATIC_ESSID)
                IPW_DEBUG_INFO("ESSID locked to '%s'\n",
-                              escape_essid(priv->essid, priv->essid_len));
+                              print_ssid(ssid, priv->essid, priv->essid_len));
        else
                IPW_DEBUG_INFO("ESSID unlocked.\n");
        if (priv->config & CFG_STATIC_BSSID)
-               IPW_DEBUG_INFO("BSSID locked to %s\n",
-                              print_mac(mac, priv->bssid));
+               IPW_DEBUG_INFO("BSSID locked to %pM\n", priv->bssid);
        else
                IPW_DEBUG_INFO("BSSID unlocked.\n");
        if (priv->capability & CAP_PRIVACY_ON)
@@ -6892,8 +6886,7 @@ static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
        if ((priv->status & STATUS_ASSOCIATED) &&
            (priv->ieee->iw_mode == IW_MODE_ADHOC) && (active_network == 0)) {
                if (memcmp(network->bssid, priv->bssid, ETH_ALEN))
-                       if ((network->capability & WLAN_CAPABILITY_IBSS) &&
-                           !(network->flags & NETWORK_EMPTY_ESSID))
+                       if (network->capability & WLAN_CAPABILITY_IBSS)
                                if ((network->ssid_len ==
                                     priv->assoc_network->ssid_len) &&
                                    !memcmp(network->ssid,
@@ -7295,7 +7288,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
                                 struct ipw_supported_rates *rates, int roaming)
 {
        int err;
-       DECLARE_MAC_BUF(mac);
+       DECLARE_SSID_BUF(ssid);
 
        if (priv->config & CFG_FIXED_RATE)
                ipw_set_fixed_rate(priv, network->mode);
@@ -7364,7 +7357,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
        IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, "
                        "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
                        roaming ? "Rea" : "A",
-                       escape_essid(priv->essid, priv->essid_len),
+                       print_ssid(ssid, priv->essid, priv->essid_len),
                        network->channel,
                        ipw_modes[priv->assoc_request.ieee_mode],
                        rates->num_rates,
@@ -7463,9 +7456,9 @@ static int ipw_associate_network(struct ipw_priv *priv,
                return err;
        }
 
-       IPW_DEBUG(IPW_DL_STATE, "associating: '%s' %s \n",
-                 escape_essid(priv->essid, priv->essid_len),
-                 print_mac(mac, priv->bssid));
+       IPW_DEBUG(IPW_DL_STATE, "associating: '%s' %pM \n",
+                 print_ssid(ssid, priv->essid, priv->essid_len),
+                 priv->bssid);
 
        return 0;
 }
@@ -7555,6 +7548,7 @@ static int ipw_associate(void *data)
        struct ipw_supported_rates *rates;
        struct list_head *element;
        unsigned long flags;
+       DECLARE_SSID_BUF(ssid);
 
        if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
                IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n");
@@ -7604,7 +7598,6 @@ static int ipw_associate(void *data)
                if (list_empty(&priv->ieee->network_free_list)) {
                        struct ieee80211_network *oldest = NULL;
                        struct ieee80211_network *target;
-                       DECLARE_MAC_BUF(mac);
 
                        list_for_each_entry(target, &priv->ieee->network_list, list) {
                                if ((oldest == NULL) ||
@@ -7615,11 +7608,11 @@ static int ipw_associate(void *data)
                        /* If there are no more slots, expire the oldest */
                        list_del(&oldest->list);
                        target = oldest;
-                       IPW_DEBUG_ASSOC("Expired '%s' (%s) from "
+                       IPW_DEBUG_ASSOC("Expired '%s' (%pM) from "
                                        "network list.\n",
-                                       escape_essid(target->ssid,
-                                                    target->ssid_len),
-                                       print_mac(mac, target->bssid));
+                                       print_ssid(ssid, target->ssid,
+                                                  target->ssid_len),
+                                       target->bssid);
                        list_add_tail(&target->list,
                                      &priv->ieee->network_free_list);
                }
@@ -7672,12 +7665,12 @@ static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
        u16 fc;
 
        hdr = (struct ieee80211_hdr *)skb->data;
-       fc = le16_to_cpu(hdr->frame_ctl);
+       fc = le16_to_cpu(hdr->frame_control);
        if (!(fc & IEEE80211_FCTL_PROTECTED))
                return;
 
        fc &= ~IEEE80211_FCTL_PROTECTED;
-       hdr->frame_ctl = cpu_to_le16(fc);
+       hdr->frame_control = cpu_to_le16(fc);
        switch (priv->ieee->sec.level) {
        case SEC_LEVEL_3:
                /* Remove CCMP HDR */
@@ -7989,17 +7982,17 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
        }
 
        hdr = (void *)rxb->skb->data + IPW_RX_FRAME_SIZE;
-       if (ieee80211_is_management(le16_to_cpu(hdr->frame_ctl))) {
+       if (ieee80211_is_management(le16_to_cpu(hdr->frame_control))) {
                if (filter & IPW_PROM_NO_MGMT)
                        return;
                if (filter & IPW_PROM_MGMT_HEADER_ONLY)
                        hdr_only = 1;
-       } else if (ieee80211_is_control(le16_to_cpu(hdr->frame_ctl))) {
+       } else if (ieee80211_is_control(le16_to_cpu(hdr->frame_control))) {
                if (filter & IPW_PROM_NO_CTL)
                        return;
                if (filter & IPW_PROM_CTL_HEADER_ONLY)
                        hdr_only = 1;
-       } else if (ieee80211_is_data(le16_to_cpu(hdr->frame_ctl))) {
+       } else if (ieee80211_is_data(le16_to_cpu(hdr->frame_control))) {
                if (filter & IPW_PROM_NO_DATA)
                        return;
                if (filter & IPW_PROM_DATA_HEADER_ONLY)
@@ -8017,7 +8010,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
        ipw_rt = (void *)skb->data;
 
        if (hdr_only)
-               len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+               len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
 
        memcpy(ipw_rt->payload, hdr, len);
 
@@ -8237,7 +8230,7 @@ static  int is_duplicate_packet(struct ipw_priv *priv,
        /* Comment this line now since we observed the card receives
         * duplicate packets but the FCTL_RETRY bit is not set in the
         * IBSS mode with fragmentation enabled.
-        BUG_ON(!(le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_RETRY)); */
+        BUG_ON(!(le16_to_cpu(header->frame_control) & IEEE80211_FCTL_RETRY)); */
        return 1;
 }
 
@@ -8301,9 +8294,6 @@ static void ipw_rx(struct ipw_priv *priv)
        u32 r, w, i;
        u8 network_packet;
        u8 fill_rx = 0;
-       DECLARE_MAC_BUF(mac);
-       DECLARE_MAC_BUF(mac2);
-       DECLARE_MAC_BUF(mac3);
 
        r = ipw_read32(priv, IPW_RX_READ_INDEX);
        w = ipw_read32(priv, IPW_RX_WRITE_INDEX);
@@ -8433,18 +8423,12 @@ static void ipw_rx(struct ipw_priv *priv)
                                                                         header)))
                                        {
                                                IPW_DEBUG_DROP("Dropping: "
-                                                              "%s, "
-                                                              "%s, "
-                                                              "%s\n",
-                                                              print_mac(mac,
-                                                                        header->
-                                                                      addr1),
-                                                              print_mac(mac2,
-                                                                        header->
-                                                                      addr2),
-                                                              print_mac(mac3,
-                                                                        header->
-                                                                      addr3));
+                                                              "%pM, "
+                                                              "%pM, "
+                                                              "%pM\n",
+                                                              header->addr1,
+                                                              header->addr2,
+                                                              header->addr3);
                                                break;
                                        }
 
@@ -8983,7 +8967,6 @@ static int ipw_wx_set_wap(struct net_device *dev,
                          union iwreq_data *wrqu, char *extra)
 {
        struct ipw_priv *priv = ieee80211_priv(dev);
-       DECLARE_MAC_BUF(mac);
 
        static const unsigned char any[] = {
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff
@@ -9014,8 +8997,8 @@ static int ipw_wx_set_wap(struct net_device *dev,
                return 0;
        }
 
-       IPW_DEBUG_WX("Setting mandatory BSSID to %s\n",
-                    print_mac(mac, wrqu->ap_addr.sa_data));
+       IPW_DEBUG_WX("Setting mandatory BSSID to %pM\n",
+                    wrqu->ap_addr.sa_data);
 
        memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
 
@@ -9033,7 +9016,6 @@ static int ipw_wx_get_wap(struct net_device *dev,
                          union iwreq_data *wrqu, char *extra)
 {
        struct ipw_priv *priv = ieee80211_priv(dev);
-       DECLARE_MAC_BUF(mac);
 
        /* If we are associated, trying to associate, or have a statically
         * configured BSSID then return that; otherwise return ANY */
@@ -9045,8 +9027,8 @@ static int ipw_wx_get_wap(struct net_device *dev,
        } else
                memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
 
-       IPW_DEBUG_WX("Getting WAP BSSID: %s\n",
-                    print_mac(mac, wrqu->ap_addr.sa_data));
+       IPW_DEBUG_WX("Getting WAP BSSID: %pM\n",
+                    wrqu->ap_addr.sa_data);
        mutex_unlock(&priv->mutex);
        return 0;
 }
@@ -9057,6 +9039,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
 {
        struct ipw_priv *priv = ieee80211_priv(dev);
         int length;
+       DECLARE_SSID_BUF(ssid);
 
         mutex_lock(&priv->mutex);
 
@@ -9081,8 +9064,8 @@ static int ipw_wx_set_essid(struct net_device *dev,
                return 0;
        }
 
-       IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", escape_essid(extra, length),
-                    length);
+       IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n",
+                    print_ssid(ssid, extra, length), length);
 
        priv->essid_len = length;
        memcpy(priv->essid, extra, priv->essid_len);
@@ -9101,6 +9084,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
                            union iwreq_data *wrqu, char *extra)
 {
        struct ipw_priv *priv = ieee80211_priv(dev);
+       DECLARE_SSID_BUF(ssid);
 
        /* If we are associated, trying to associate, or have a statically
         * configured ESSID then return that; otherwise return ANY */
@@ -9108,7 +9092,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
        if (priv->config & CFG_STATIC_ESSID ||
            priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
                IPW_DEBUG_WX("Getting essid: '%s'\n",
-                            escape_essid(priv->essid, priv->essid_len));
+                            print_ssid(ssid, priv->essid, priv->essid_len));
                memcpy(extra, priv->essid, priv->essid_len);
                wrqu->essid.length = priv->essid_len;
                wrqu->essid.flags = 1;  /* active */
@@ -10199,10 +10183,8 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
                        id = ipw_add_station(priv, hdr->addr1);
                        if (id == IPW_INVALID_STATION) {
                                IPW_WARNING("Attempt to send data to "
-                                           "invalid cell: " MAC_FMT "\n",
-                                           hdr->addr1[0], hdr->addr1[1],
-                                           hdr->addr1[2], hdr->addr1[3],
-                                           hdr->addr1[4], hdr->addr1[5]);
+                                           "invalid cell: %pM\n",
+                                           hdr->addr1);
                                goto drop;
                        }
                }
@@ -10399,17 +10381,17 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
 
        /* Filtering of fragment chains is done agains the first fragment */
        hdr = (void *)txb->fragments[0]->data;
-       if (ieee80211_is_management(le16_to_cpu(hdr->frame_ctl))) {
+       if (ieee80211_is_management(le16_to_cpu(hdr->frame_control))) {
                if (filter & IPW_PROM_NO_MGMT)
                        return;
                if (filter & IPW_PROM_MGMT_HEADER_ONLY)
                        hdr_only = 1;
-       } else if (ieee80211_is_control(le16_to_cpu(hdr->frame_ctl))) {
+       } else if (ieee80211_is_control(le16_to_cpu(hdr->frame_control))) {
                if (filter & IPW_PROM_NO_CTL)
                        return;
                if (filter & IPW_PROM_CTL_HEADER_ONLY)
                        hdr_only = 1;
-       } else if (ieee80211_is_data(le16_to_cpu(hdr->frame_ctl))) {
+       } else if (ieee80211_is_data(le16_to_cpu(hdr->frame_control))) {
                if (filter & IPW_PROM_NO_DATA)
                        return;
                if (filter & IPW_PROM_DATA_HEADER_ONLY)
@@ -10424,7 +10406,7 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
 
                if (hdr_only) {
                        hdr = (void *)src->data;
-                       len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+                       len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
                } else
                        len = src->len;
 
@@ -10505,15 +10487,14 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p)
 {
        struct ipw_priv *priv = ieee80211_priv(dev);
        struct sockaddr *addr = p;
-       DECLARE_MAC_BUF(mac);
 
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
        mutex_lock(&priv->mutex);
        priv->config |= CFG_CUSTOM_MAC;
        memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
-       printk(KERN_INFO "%s: Setting MAC to %s\n",
-              priv->net_dev->name, print_mac(mac, priv->mac_addr));
+       printk(KERN_INFO "%s: Setting MAC to %pM\n",
+              priv->net_dev->name, priv->mac_addr);
        queue_work(priv->workqueue, &priv->adapter_restart);
        mutex_unlock(&priv->mutex);
        return 0;
@@ -11648,7 +11629,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
        length = pci_resource_len(pdev, 0);
        priv->hw_len = length;
 
-       base = ioremap_nocache(pci_resource_start(pdev, 0), length);
+       base = pci_ioremap_bar(pdev, 0);
        if (!base) {
                err = -ENODEV;
                goto out_pci_release_regions;
@@ -11940,7 +11921,7 @@ module_param(disable, int, 0444);
 MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
 
 module_param(associate, int, 0444);
-MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
+MODULE_PARM_DESC(associate, "auto associate when scanning (default off)");
 
 module_param(auto_create, int, 0444);
 MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
index 0bad1ec3e7e0af7c9594d6cdc2deb0cce002811a..0a84d52147bd5cba7f4a012d1662d29d248172fe 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/jiffies.h>
 #include <asm/io.h>
 
+#include <net/lib80211.h>
 #include <net/ieee80211.h>
 #include <net/ieee80211_radiotap.h>
 
index b0ac0ce3fb9f6dfb4c8d126ded42f4621d9e2877..47bee0ee0a7c3b1a040f477f450a2ecd4692e4ee 100644 (file)
@@ -4,6 +4,7 @@ config IWLWIFI
 config IWLCORE
        tristate "Intel Wireless Wifi Core"
        depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
+       select LIB80211
        select IWLWIFI
        select MAC80211_LEDS if IWLWIFI_LEDS
        select LEDS_CLASS if IWLWIFI_LEDS
@@ -105,6 +106,7 @@ config IWL3945
        tristate "Intel PRO/Wireless 3945ABG/BG Network Connection"
        depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
        select FW_LOADER
+       select LIB80211
        select IWLWIFI
        select MAC80211_LEDS if IWL3945_LEDS
        select LEDS_CLASS if IWL3945_LEDS
index 817ece7736434f9645749c2e12940aca11f1106a..8772d9d7d6e79be1c913da5018033ca43eda6f67 100644 (file)
@@ -121,7 +121,7 @@ enum {
        REPLY_TX_PWR_TABLE_CMD = 0x97,
        MEASURE_ABORT_NOTIFICATION = 0x99,      /* not used */
 
-       /* Bluetooth device coexistance config command */
+       /* Bluetooth device coexistence config command */
        REPLY_BT_CONFIG = 0x9b,
 
        /* Statistics */
@@ -158,7 +158,7 @@ struct iwl3945_cmd_header {
        u8 cmd;         /* Command ID:  REPLY_RXON, etc. */
        u8 flags;       /* IWL_CMD_* */
        /*
-        * The driver sets up the sequence number to values of its chosing.
+        * The driver sets up the sequence number to values of its choosing.
         * uCode does not use this value, but passes it back to the driver
         * when sending the response to each driver-originated command, so
         * the driver can match the response to the command.  Since the values
@@ -991,7 +991,7 @@ struct iwl3945_rate_scaling_cmd {
  *
  * 3945 and 4965 support hardware handshake with Bluetooth device on
  * same platform.  Bluetooth device alerts wireless device when it will Tx;
- * wireless device can delay or kill its own Tx to accomodate.
+ * wireless device can delay or kill its own Tx to accommodate.
  */
 struct iwl3945_bt_cmd {
        u8 flags;
index b3fe48de3ae7b819d17bffd7cd7d01013cd632b1..1daa3f05a7757f5e4e960f584d6dad28ca1e0200 100644 (file)
@@ -53,7 +53,7 @@
  * _iwl3945_read32.)
  *
  * These declarations are *extremely* useful in quickly isolating code deltas
- * which result in misconfiguring of the hardware I/O.  In combination with
+ * which result in misconfiguration of the hardware I/O.  In combination with
  * git-bisect and the IO debug level you can quickly determine the specific
  * commit which breaks the IO sequence to the hardware.
  *
index 6fc5e7361f267dad0e01deb1a5c2a155cdc72bc6..bfeef701b1fd192b6de7a41c5d795ab96c08b260 100644 (file)
@@ -355,12 +355,6 @@ static void rs_free(void *priv)
        return;
 }
 
-static void rs_clear(void *priv)
-{
-       return;
-}
-
-
 static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
 {
        struct iwl3945_rs_sta *rs_sta;
@@ -422,34 +416,6 @@ static void rs_free_sta(void *priv, struct ieee80211_sta *sta,
 }
 
 
-/*
- * get ieee prev rate from rate scale table.
- * for A and B mode we need to overright prev
- * value
- */
-static int rs_adjust_next_rate(struct iwl3945_priv *priv, int rate)
-{
-       int next_rate = iwl3945_get_prev_ieee_rate(rate);
-
-       switch (priv->band) {
-       case IEEE80211_BAND_5GHZ:
-               if (rate == IWL_RATE_12M_INDEX)
-                       next_rate = IWL_RATE_9M_INDEX;
-               else if (rate == IWL_RATE_6M_INDEX)
-                       next_rate = IWL_RATE_6M_INDEX;
-               break;
-/* XXX cannot be invoked in current mac80211 so not a regression
-       case MODE_IEEE80211B:
-               if (rate == IWL_RATE_11M_INDEX_TABLE)
-                       next_rate = IWL_RATE_5M_INDEX_TABLE;
-               break;
- */
-       default:
-               break;
-       }
-
-       return next_rate;
-}
 /**
  * rs_tx_status - Update rate control values based on Tx results
  *
@@ -460,17 +426,21 @@ 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;
+       u8 retries = 0, current_count;
        int scale_rate_index, first_index, last_index;
        unsigned long flags;
        struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate;
        struct iwl3945_rs_sta *rs_sta = priv_sta;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       int i;
 
        IWL_DEBUG_RATE("enter\n");
 
-       retries = info->status.retry_count;
-       first_index = sband->bitrates[info->tx_rate_idx].hw_value;
+       for (i = 0; i < IEEE80211_TX_MAX_RATES; i++)
+               retries += info->status.rates[i].count;
+       retries--;
+
+       first_index = sband->bitrates[info->status.rates[0].idx].hw_value;
        if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) {
                IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index);
                return;
@@ -502,7 +472,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
                        last_index = scale_rate_index;
                } else {
                        current_count = priv->retry_rate;
-                       last_index = rs_adjust_next_rate(priv,
+                       last_index = iwl3945_rs_next_rate(priv,
                                                         scale_rate_index);
                }
 
@@ -518,7 +488,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
 
                if (retries)
                        scale_rate_index =
-                           rs_adjust_next_rate(priv, scale_rate_index);
+                           iwl3945_rs_next_rate(priv, scale_rate_index);
        }
 
 
@@ -630,10 +600,11 @@ 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_r, struct ieee80211_supported_band *sband,
-                       struct ieee80211_sta *sta, void *priv_sta,
-                       struct sk_buff *skb, struct rate_selection *sel)
+static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
+                       void *priv_sta, struct ieee80211_tx_rate_control *txrc)
 {
+       struct ieee80211_supported_band *sband = txrc->sband;
+       struct sk_buff *skb = txrc->skb;
        u8 low = IWL_RATE_INVALID;
        u8 high = IWL_RATE_INVALID;
        u16 high_low;
@@ -649,7 +620,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband,
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        u16 fc, rate_mask;
        struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
-       DECLARE_MAC_BUF(mac);
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
        IWL_DEBUG_RATE("enter\n");
 
@@ -660,7 +631,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband,
            is_multicast_ether_addr(hdr->addr1) ||
            !sta || !priv_sta) {
                IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
-               sel->rate_idx = rate_lowest_index(sband, sta);
+               info->control.rates[0].idx = rate_lowest_index(sband, sta);
                return;
        }
 
@@ -675,8 +646,8 @@ static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband,
                u8 sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
 
                if (sta_id == IWL_INVALID_STATION) {
-                       IWL_DEBUG_RATE("LQ: ADD station %s\n",
-                                      print_mac(mac, hdr->addr1));
+                       IWL_DEBUG_RATE("LQ: ADD station %pm\n",
+                                      hdr->addr1);
                        sta_id = iwl3945_add_station(priv,
                                    hdr->addr1, 0, CMD_ASYNC);
                }
@@ -793,9 +764,10 @@ static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband,
 
        rs_sta->last_txrate_idx = index;
        if (sband->band == IEEE80211_BAND_5GHZ)
-               sel->rate_idx = rs_sta->last_txrate_idx - IWL_FIRST_OFDM_RATE;
+               info->control.rates[0].idx = rs_sta->last_txrate_idx -
+                               IWL_FIRST_OFDM_RATE;
        else
-               sel->rate_idx = rs_sta->last_txrate_idx;
+               info->control.rates[0].idx = rs_sta->last_txrate_idx;
 
        IWL_DEBUG_RATE("leave: %d\n", index);
 }
@@ -806,7 +778,6 @@ static struct rate_control_ops rs_ops = {
        .tx_status = rs_tx_status,
        .get_rate = rs_get_rate,
        .rate_init = rs_rate_init,
-       .clear = rs_clear,
        .alloc = rs_alloc,
        .free = rs_free,
        .alloc_sta = rs_alloc_sta,
@@ -827,13 +798,12 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
        rcu_read_lock();
 
        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");
+       if (!sta) {
                rcu_read_unlock();
                return;
        }
 
+       psta = (void *) sta->drv_priv;
        rs_sta = psta->rs_sta;
 
        spin_lock_irqsave(&rs_sta->lock, flags);
@@ -857,7 +827,6 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
                break;
        }
 
-       rcu_read_unlock();
        spin_unlock_irqrestore(&rs_sta->lock, flags);
 
        rssi = priv->last_rx_rssi;
@@ -871,6 +840,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
        IWL_DEBUG_RATE("leave: rssi %d assign rate index: "
                       "%d (plcp 0x%x)\n", rssi, rs_sta->start_rate,
                       iwl3945_rates[rs_sta->start_rate].plcp);
+       rcu_read_unlock();
 }
 
 int iwl3945_rate_control_register(void)
index 7ca5627cc078bed3944190d36ab201c39b31c9e8..af77ea70d7377134fd3ea48bc635e4eba93060eb 100644 (file)
@@ -200,7 +200,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
  * priv->eeprom  is used to determine if antenna AUX/MAIN are reversed
  * priv->antenna specifies the antenna diversity mode:
  *
- * IWL_ANTENNA_DIVERISTY - NIC selects best antenna by itself
+ * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself
  * IWL_ANTENNA_MAIN      - Force MAIN antenna
  * IWL_ANTENNA_AUX       - Force AUX antenna
  */
@@ -261,6 +261,35 @@ static inline const char *iwl3945_get_tx_fail_reason(u32 status)
 }
 #endif
 
+/*
+ * get ieee prev rate from rate scale table.
+ * for A and B mode we need to overright prev
+ * value
+ */
+int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate)
+{
+       int next_rate = iwl3945_get_prev_ieee_rate(rate);
+
+       switch (priv->band) {
+       case IEEE80211_BAND_5GHZ:
+               if (rate == IWL_RATE_12M_INDEX)
+                       next_rate = IWL_RATE_9M_INDEX;
+               else if (rate == IWL_RATE_6M_INDEX)
+                       next_rate = IWL_RATE_6M_INDEX;
+               break;
+/* XXX cannot be invoked in current mac80211 so not a regression
+       case MODE_IEEE80211B:
+               if (rate == IWL_RATE_11M_INDEX_TABLE)
+                       next_rate = IWL_RATE_5M_INDEX_TABLE;
+               break;
+ */
+       default:
+               break;
+       }
+
+       return next_rate;
+}
+
 
 /**
  * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd
@@ -308,6 +337,7 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
        struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
        u32  status = le32_to_cpu(tx_resp->status);
        int rate_idx;
+       int fail, i;
 
        if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) {
                IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
@@ -318,9 +348,36 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
        }
 
        info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
-       memset(&info->status, 0, sizeof(info->status));
+       ieee80211_tx_info_clear_status(info);
+
+       /* Fill the MRR chain with some info about on-chip retransmissions */
+       rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate);
+       if (info->band == IEEE80211_BAND_5GHZ)
+               rate_idx -= IWL_FIRST_OFDM_RATE;
+
+       fail = tx_resp->failure_frame;
+       for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
+               int next = iwl3945_rs_next_rate(priv, rate_idx);
+
+               info->status.rates[i].idx = rate_idx;
+
+               /*
+                * Put remaining into the last count as best approximation
+                * of saying exactly what the hardware would have done...
+                */
+               if ((rate_idx == next) || (i == IEEE80211_TX_MAX_RATES - 1)) {
+                       info->status.rates[i].count = fail;
+                       break;
+               }
+
+               info->status.rates[i].count = priv->retry_rate;
+               fail -= priv->retry_rate;
+               rate_idx = next;
+               if (fail <= 0)
+                       break;
+       }
+       info->status.rates[i].count++; /* add final attempt */
 
-       info->status.retry_count = tx_resp->failure_frame;
        /* tx_status->rts_retry_count = tx_resp->failure_rts; */
        info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ?
                                IEEE80211_TX_STAT_ACK : 0;
@@ -329,10 +386,6 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
                        txq_id, iwl3945_get_tx_fail_reason(status), status,
                        tx_resp->rate, tx_resp->failure_frame);
 
-       rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate);
-       if (info->band == IEEE80211_BAND_5GHZ)
-               rate_idx -= IWL_FIRST_OFDM_RATE;
-       info->tx_rate_idx = rate_idx;
        IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
        iwl3945_tx_queue_reclaim(priv, txq_id, index);
 
@@ -759,7 +812,6 @@ u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
        int i;
        int ret = IWL_INVALID_STATION;
        unsigned long flags;
-       DECLARE_MAC_BUF(mac);
 
        spin_lock_irqsave(&priv->sta_lock, flags);
        for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++)
@@ -770,8 +822,8 @@ u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
                        goto out;
                }
 
-       IWL_DEBUG_INFO("can not find STA %s (total %d)\n",
-                      print_mac(mac, addr), priv->num_stations);
+       IWL_DEBUG_INFO("can not find STA %pM (total %d)\n",
+                      addr, priv->num_stations);
  out:
        spin_unlock_irqrestore(&priv->sta_lock, flags);
        return ret;
@@ -1830,7 +1882,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
                ref_temp = (s16)priv->eeprom.groups[ch_info->group_index].
                    temperature;
 
-               /* get power index adjustment based on curr and factory
+               /* get power index adjustment based on current and factory
                 * temps */
                delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature,
                                                              ref_temp);
index bdd32475b99ca6b0ca7ae1562f85b878edfa55fc..7187925bd0d5cce04f4cd0d4866beea80624f2da 100644 (file)
@@ -828,8 +828,6 @@ struct iwl3945_priv {
        unsigned long last_statistics_time;
 
        /* context information */
-       u8 essid[IW_ESSID_MAX_SIZE];
-       u8 essid_len;
        u16 rates_mask;
 
        u32 power_mode;
@@ -954,6 +952,8 @@ static inline int is_channel_ibss(const struct iwl3945_channel_info *ch)
 extern const struct iwl3945_channel_info *iwl3945_get_channel_info(
        const struct iwl3945_priv *priv, enum ieee80211_band band, u16 channel);
 
+extern int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate);
+
 /* Requires full declaration of iwl3945_priv before including */
 #include "iwl-3945-io.h"
 
index f4793a609443eca52ded350777ea0f0967deb130..9da7c7bea7525e072db9aa759b37fba422e26472 100644 (file)
@@ -71,7 +71,7 @@
 
 #include "iwl-fh.h"
 
-/* EERPROM */
+/* EEPROM */
 #define IWL4965_EEPROM_IMG_SIZE                        1024
 
 /*
 #define PCI_CFG_CMD_REG_INT_DIS_MSK    0x04
 #define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT         (0x80000000)
 
-#define TFD_QUEUE_SIZE_MAX      (256)
 
 #define IWL_NUM_SCAN_RATES         (2)
 
@@ -287,13 +286,13 @@ static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)
  *     that target txpower.
  *
  *
- * 3)  Determine (EEPROM) calibration subband for the target channel, by
- *     comparing against first and last channels in each subband
+ * 3)  Determine (EEPROM) calibration sub band for the target channel, by
+ *     comparing against first and last channels in each sub band
  *     (see struct iwl4965_eeprom_calib_subband_info).
  *
  *
  * 4)  Linearly interpolate (EEPROM) factory calibration measurement sets,
- *     referencing the 2 factory-measured (sample) channels within the subband.
+ *     referencing the 2 factory-measured (sample) channels within the sub band.
  *
  *     Interpolation is based on difference between target channel's frequency
  *     and the sample channels' frequencies.  Since channel numbers are based
@@ -301,7 +300,7 @@ static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)
  *     to interpolating based on channel number differences.
  *
  *     Note that the sample channels may or may not be the channels at the
- *     edges of the subband.  The target channel may be "outside" of the
+ *     edges of the sub band.  The target channel may be "outside" of the
  *     span of the sampled channels.
  *
  *     Driver may choose the pair (for 2 Tx chains) of measurements (see
@@ -345,7 +344,7 @@ static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)
  *     "4965 temperature calculation".
  *
  *     If current temperature is higher than factory temperature, driver must
- *     increase gain (lower gain table index), and vice versa.
+ *     increase gain (lower gain table index), and vice verse.
  *
  *     Temperature affects gain differently for different channels:
  *
@@ -815,125 +814,72 @@ enum {
  * up to 7 DMA channels (FIFOs).  Each Tx queue is supported by a circular array
  * in DRAM containing 256 Transmit Frame Descriptors (TFDs).
  */
-#define IWL49_MAX_WIN_SIZE     64
-#define IWL49_QUEUE_SIZE       256
 #define IWL49_NUM_FIFOS        7
 #define IWL49_CMD_FIFO_NUM     4
 #define IWL49_NUM_QUEUES       16
 #define IWL49_NUM_AMPDU_QUEUES 8
 
+#define IWL_TX_DMA_MASK        (DMA_BIT_MASK(36) & ~0x3)
+#define IWL_NUM_OF_TBS         20
+
+static inline u8 iwl_get_dma_hi_addr(dma_addr_t addr)
+{
+       return (sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0) & 0xF;
+}
 /**
- * struct iwl_tfd_frame_data
- *
- * Describes up to 2 buffers containing (contiguous) portions of a Tx frame.
- * Each buffer must be on dword boundary.
- * Up to 10 iwl_tfd_frame_data structures, describing up to 20 buffers,
- * may be filled within a TFD (iwl_tfd_frame).
- *
- * Bit fields in tb1_addr:
- * 31- 0: Tx buffer 1 address bits [31:0]
+ * struct iwl_tfd_tb transmit buffer descriptor within transmit frame descriptor
  *
- * Bit fields in val1:
- * 31-16: Tx buffer 2 address bits [15:0]
- * 15- 4: Tx buffer 1 length (bytes)
- *  3- 0: Tx buffer 1 address bits [32:32]
+ * This structure contains dma address and length of transmission address
  *
- * Bit fields in val2:
- * 31-20: Tx buffer 2 length (bytes)
- * 19- 0: Tx buffer 2 address bits [35:16]
+ * @lo: low [31:0] portion of the dma address of TX buffer
+ *     every even is unaligned on 16 bit boundary
+ * @hi_n_len 0-3 [35:32] portion of dma
+ *          4-16 length of the tx buffer
  */
-struct iwl_tfd_frame_data {
-       __le32 tb1_addr;
-
-       __le32 val1;
-       /* __le32 ptb1_32_35:4; */
-#define IWL_tb1_addr_hi_POS 0
-#define IWL_tb1_addr_hi_LEN 4
-#define IWL_tb1_addr_hi_SYM val1
-       /* __le32 tb_len1:12; */
-#define IWL_tb1_len_POS 4
-#define IWL_tb1_len_LEN 12
-#define IWL_tb1_len_SYM val1
-       /* __le32 ptb2_0_15:16; */
-#define IWL_tb2_addr_lo16_POS 16
-#define IWL_tb2_addr_lo16_LEN 16
-#define IWL_tb2_addr_lo16_SYM val1
-
-       __le32 val2;
-       /* __le32 ptb2_16_35:20; */
-#define IWL_tb2_addr_hi20_POS 0
-#define IWL_tb2_addr_hi20_LEN 20
-#define IWL_tb2_addr_hi20_SYM val2
-       /* __le32 tb_len2:12; */
-#define IWL_tb2_len_POS 20
-#define IWL_tb2_len_LEN 12
-#define IWL_tb2_len_SYM val2
-} __attribute__ ((packed));
-
+struct iwl_tfd_tb {
+       __le32 lo;
+       __le16 hi_n_len;
+} __attribute__((packed));
 
 /**
- * struct iwl_tfd_frame
+ * struct iwl_tfd
  *
  * Transmit Frame Descriptor (TFD)
  *
- * 4965 supports up to 16 Tx queues resident in host DRAM.
+ * @ __reserved1[3] reserved
+ * @ num_tbs 0-5 number of active tbs
+ *          6-7 padding (not used)
+ * @ tbs[20]   transmit frame buffer descriptors
+ * @ __pad     padding
+ *
  * Each Tx queue uses a circular buffer of 256 TFDs stored in host DRAM.
  * Both driver and device share these circular buffers, each of which must be
- * contiguous 256 TFDs x 128 bytes-per-TFD = 32 KBytes for 4965.
+ * contiguous 256 TFDs x 128 bytes-per-TFD = 32 KBytes
  *
  * Driver must indicate the physical address of the base of each
- * circular buffer via the 4965's FH_MEM_CBBC_QUEUE registers.
+ * circular buffer via the FH_MEM_CBBC_QUEUE registers.
  *
  * Each TFD contains pointer/size information for up to 20 data buffers
  * in host DRAM.  These buffers collectively contain the (one) frame described
  * by the TFD.  Each buffer must be a single contiguous block of memory within
  * itself, but buffers may be scattered in host DRAM.  Each buffer has max size
- * of (4K - 4).  The 4965 concatenates all of a TFD's buffers into a single
+ * of (4K - 4).  The concatenates all of a TFD's buffers into a single
  * Tx frame, up to 8 KBytes in size.
  *
- * Bit fields in the control dword (val0):
- * 31-30: # dwords (0-3) of padding required at end of frame for 16-byte bound
- *    29: reserved
- * 28-24: # Transmit Buffer Descriptors in TFD
- * 23- 0: reserved
- *
  * A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx.
- */
-struct iwl_tfd_frame {
-       __le32 val0;
-       /* __le32 rsvd1:24; */
-       /* __le32 num_tbs:5; */
-#define IWL_num_tbs_POS 24
-#define IWL_num_tbs_LEN 5
-#define IWL_num_tbs_SYM val0
-       /* __le32 rsvd2:1; */
-       /* __le32 padding:2; */
-       struct iwl_tfd_frame_data pa[10];
-       __le32 reserved;
-} __attribute__ ((packed));
-
-
-/**
- * struct iwl4965_queue_byte_cnt_entry
  *
- * Byte Count Table Entry
- *
- * Bit fields:
- * 15-12: reserved
- * 11- 0: total to-be-transmitted byte count of frame (does not include command)
+ * Bit fields in the control dword (val0):
  */
-struct iwl4965_queue_byte_cnt_entry {
-       __le16 val;
-       /* __le16 byte_cnt:12; */
-#define IWL_byte_cnt_POS 0
-#define IWL_byte_cnt_LEN 12
-#define IWL_byte_cnt_SYM val
-       /* __le16 rsvd:4; */
+struct iwl_tfd {
+       u8 __reserved1[3];
+       u8 num_tbs;
+       struct iwl_tfd_tb tbs[IWL_NUM_OF_TBS];
+       __le32 __pad;
 } __attribute__ ((packed));
 
 
 /**
- * struct iwl4965_sched_queue_byte_cnt_tbl
+ * struct iwl4965_schedq_bc_tbl
  *
  * Byte Count table
  *
@@ -947,15 +893,12 @@ struct iwl4965_queue_byte_cnt_entry {
  * count table for the chosen Tx queue.  If the TFD index is 0-63, the driver
  * must duplicate the byte count entry in corresponding index 256-319.
  *
- * "dont_care" padding puts each byte count table on a 1024-byte boundary;
+ * padding puts each byte count table on a 1024-byte boundary;
  * 4965 assumes tables are separated by 1024 bytes.
  */
-struct iwl4965_sched_queue_byte_cnt_tbl {
-       struct iwl4965_queue_byte_cnt_entry tfd_offset[IWL49_QUEUE_SIZE +
-                                                      IWL49_MAX_WIN_SIZE];
-       u8 dont_care[1024 -
-                    (IWL49_QUEUE_SIZE + IWL49_MAX_WIN_SIZE) *
-                    sizeof(__le16)];
+struct iwl4965_schedq_bc_tbl {
+       __le16 tfd_offset[TFD_QUEUE_BC_SIZE];
+       u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)];
 } __attribute__ ((packed));
 
 
@@ -983,8 +926,7 @@ struct iwl4965_sched_queue_byte_cnt_tbl {
  * 31- 0:  Not used
  */
 struct iwl4965_shared {
-       struct iwl4965_sched_queue_byte_cnt_tbl
-        queues_byte_cnt_tbls[IWL49_NUM_QUEUES];
+       struct iwl4965_schedq_bc_tbl queues_bc_tbls[IWL49_NUM_QUEUES];
        __le32 rb_closed;
 
        /* __le32 rb_closed_stts_rb_num:12; */
index 9838de5f436918762c0fafdca82102ea01993094..157cad4e9da038bb78fac200fffa406d4c7abea7 100644 (file)
@@ -246,7 +246,7 @@ static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
        iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
                                 priv->ucode_data.len);
 
-       /* Inst bytecount must be last to set up, bit 31 signals uCode
+       /* Inst byte count must be last to set up, bit 31 signals uCode
         *   that all new ptr/size info is in place */
        iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
                                 priv->ucode_code.len | BSM_DRAM_INST_LOAD);
@@ -318,31 +318,13 @@ static int is_fat_channel(__le32 rxon_flags)
 /*
  * EEPROM handlers
  */
-
-static int iwl4965_eeprom_check_version(struct iwl_priv *priv)
+static u16 iwl4965_eeprom_calib_version(struct iwl_priv *priv)
 {
-       u16 eeprom_ver;
-       u16 calib_ver;
-
-       eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
-
-       calib_ver = iwl_eeprom_query16(priv, EEPROM_4965_CALIB_VERSION_OFFSET);
-
-       if (eeprom_ver < EEPROM_4965_EEPROM_VERSION ||
-           calib_ver < EEPROM_4965_TX_POWER_VERSION)
-               goto err;
-
-       return 0;
-err:
-       IWL_ERROR("Unsuported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
-                 eeprom_ver, EEPROM_4965_EEPROM_VERSION,
-                 calib_ver, EEPROM_4965_TX_POWER_VERSION);
-       return -EINVAL;
-
+       return iwl_eeprom_query16(priv, EEPROM_4965_CALIB_VERSION_OFFSET);
 }
 
 /*
- * Activate/Deactivat Tx DMA/FIFO channels according tx fifos mask
+ * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
  * must be called under priv->lock and mac access
  */
 static void iwl4965_txq_set_sched(struct iwl_priv *priv, u32 mask)
@@ -414,7 +396,7 @@ static void iwl4965_nic_config(struct iwl_priv *priv)
 
        /* L1 is enabled by BIOS */
        if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
-               /* diable L0S disabled L1A enabled */
+               /* disable L0S disabled L1A enabled */
                iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
        else
                /* L0S enabled L1A disabled */
@@ -537,10 +519,10 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv)
        struct iwl_chain_noise_data *data = &(priv->chain_noise_data);
 
        if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) {
-               struct iwl4965_calibration_cmd cmd;
+               struct iwl_calib_diff_gain_cmd cmd;
 
                memset(&cmd, 0, sizeof(cmd));
-               cmd.opCode = PHY_CALIBRATE_DIFF_GAIN_CMD;
+               cmd.opCode = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD;
                cmd.diff_gain_a = 0;
                cmd.diff_gain_b = 0;
                cmd.diff_gain_c = 0;
@@ -587,11 +569,11 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
 
        /* Differential gain gets sent to uCode only once */
        if (!data->radio_write) {
-               struct iwl4965_calibration_cmd cmd;
+               struct iwl_calib_diff_gain_cmd cmd;
                data->radio_write = 1;
 
                memset(&cmd, 0, sizeof(cmd));
-               cmd.opCode = PHY_CALIBRATE_DIFF_GAIN_CMD;
+               cmd.opCode = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD;
                cmd.diff_gain_a = data->delta_gain_code[0];
                cmd.diff_gain_b = data->delta_gain_code[1];
                cmd.diff_gain_c = data->delta_gain_code[2];
@@ -619,10 +601,10 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
 static void iwl4965_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
                        __le32 *tx_flags)
 {
-       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
+       if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
                *tx_flags |= TX_CMD_FLG_RTS_MSK;
                *tx_flags &= ~TX_CMD_FLG_CTS_MSK;
-       } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
+       } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
                *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
                *tx_flags |= TX_CMD_FLG_CTS_MSK;
        }
@@ -643,7 +625,7 @@ static void iwl4965_bg_txpower_work(struct work_struct *work)
 
        mutex_lock(&priv->mutex);
 
-       /* Regardless of if we are assocaited, we must reconfigure the
+       /* Regardless of if we are associated, we must reconfigure the
         * TX power since frames can be sent on non-radar channels while
         * not associated */
        iwl4965_send_tx_power(priv);
@@ -734,7 +716,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
        /* Tel 4965 where to find Tx byte count tables */
        iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR,
                (priv->shared_phys +
-                offsetof(struct iwl4965_shared, queues_byte_cnt_tbls)) >> 10);
+                offsetof(struct iwl4965_shared, queues_bc_tbls)) >> 10);
 
        /* Disable chain mode for all queues */
        iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0);
@@ -822,7 +804,6 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
        }
 
        priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
-       priv->hw_params.first_ampdu_q = IWL49_FIRST_AMPDU_QUEUE;
        priv->hw_params.max_stations = IWL4965_STATION_COUNT;
        priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
        priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
@@ -1687,21 +1668,22 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
                                            struct iwl_tx_queue *txq,
                                            u16 byte_cnt)
 {
-       int len;
-       int txq_id = txq->q.id;
        struct iwl4965_shared *shared_data = priv->shared_virt;
+       int txq_id = txq->q.id;
+       int write_ptr = txq->q.write_ptr;
+       int len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
+       __le16 bc_ent;
 
-       len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
+       WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
 
+       bc_ent = cpu_to_le16(len & 0xFFF);
        /* Set up byte count within first 256 entries */
-       IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id].
-                      tfd_offset[txq->q.write_ptr], byte_cnt, len);
+       shared_data->queues_bc_tbls[txq_id].tfd_offset[write_ptr] = bc_ent;
 
        /* If within first 64 entries, duplicate at end */
-       if (txq->q.write_ptr < IWL49_MAX_WIN_SIZE)
-               IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id].
-                       tfd_offset[IWL49_QUEUE_SIZE + txq->q.write_ptr],
-                       byte_cnt, len);
+       if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
+               shared_data->queues_bc_tbls[txq_id].
+                       tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
 }
 
 /**
@@ -2037,7 +2019,7 @@ static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
 }
 
 /**
- * iwl4965_tx_status_reply_tx - Handle Tx rspnse for frames in aggregation queue
+ * iwl4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue
  */
 static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
                                      struct iwl_ht_agg *agg,
@@ -2059,7 +2041,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
        agg->rate_n_flags = rate_n_flags;
        agg->bitmap = 0;
 
-       /* # frames attempted by Tx command */
+       /* num frames attempted by Tx command */
        if (agg->frame_count == 1) {
                /* Only one frame was attempted; no block-ack will arrive */
                status = le16_to_cpu(frame_status[0].status);
@@ -2070,7 +2052,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
                                   agg->frame_count, agg->start_idx, idx);
 
                info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
-               info->status.retry_count = tx_resp->failure_frame;
+               info->status.rates[0].count = tx_resp->failure_frame + 1;
                info->flags &= ~IEEE80211_TX_CTL_AMPDU;
                info->flags |= iwl_is_tx_success(status)?
                        IEEE80211_TX_STAT_ACK : 0;
@@ -2158,12 +2140,13 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
        int txq_id = SEQ_TO_QUEUE(sequence);
        int index = SEQ_TO_INDEX(sequence);
        struct iwl_tx_queue *txq = &priv->txq[txq_id];
+       struct ieee80211_hdr *hdr;
        struct ieee80211_tx_info *info;
        struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
        u32  status = le32_to_cpu(tx_resp->u.status);
-       int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
-       __le16 fc;
-       struct ieee80211_hdr *hdr;
+       int tid = MAX_TID_COUNT;
+       int sta_id;
+       int freed;
        u8 *qc = NULL;
 
        if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
@@ -2178,8 +2161,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
        memset(&info->status, 0, sizeof(info->status));
 
        hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
-       fc = hdr->frame_control;
-       if (ieee80211_is_data_qos(fc)) {
+       if (ieee80211_is_data_qos(hdr->frame_control)) {
                qc = ieee80211_get_qos_ctl(hdr);
                tid = qc[0] & 0xf;
        }
@@ -2194,8 +2176,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
                const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
                struct iwl_ht_agg *agg = NULL;
 
-               if (!qc)
-                       return;
+               WARN_ON(!qc);
 
                agg = &priv->stations[sta_id].tid[tid].agg;
 
@@ -2206,54 +2187,49 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
                        info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
 
                if (txq->q.read_ptr != (scd_ssn & 0xff)) {
-                       int freed, ampdu_q;
                        index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
                        IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
                                           "%d index %d\n", scd_ssn , index);
                        freed = iwl_tx_queue_reclaim(priv, txq_id, index);
                        priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
 
-                       if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
-                           txq_id >= 0 && priv->mac80211_registered &&
-                           agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) {
-                               /* calculate mac80211 ampdu sw queue to wake */
-                               ampdu_q = txq_id - IWL49_FIRST_AMPDU_QUEUE +
-                                         priv->hw->queues;
+                       if (priv->mac80211_registered &&
+                           (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
+                           (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
                                if (agg->state == IWL_AGG_OFF)
                                        ieee80211_wake_queue(priv->hw, txq_id);
                                else
-                                       ieee80211_wake_queue(priv->hw, ampdu_q);
+                                       ieee80211_wake_queue(priv->hw,
+                                                            txq->swq_id);
                        }
-                       iwl_txq_check_empty(priv, sta_id, tid, txq_id);
                }
        } else {
-               info->status.retry_count = tx_resp->failure_frame;
-               info->flags |=
-                       iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
+               info->status.rates[0].count = tx_resp->failure_frame + 1;
+               info->flags |= iwl_is_tx_success(status) ?
+                                       IEEE80211_TX_STAT_ACK : 0;
                iwl_hwrate_to_tx_control(priv,
                                        le32_to_cpu(tx_resp->rate_n_flags),
                                        info);
 
-               IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags "
-                            "0x%x retries %d\n", txq_id,
-                               iwl_get_tx_fail_reason(status),
-                               status, le32_to_cpu(tx_resp->rate_n_flags),
-                               tx_resp->failure_frame);
-
-               IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
+               IWL_DEBUG_TX_REPLY("TXQ %d status %s (0x%08x) "
+                                  "rate_n_flags 0x%x retries %d\n",
+                                  txq_id,
+                                  iwl_get_tx_fail_reason(status), status,
+                                  le32_to_cpu(tx_resp->rate_n_flags),
+                                  tx_resp->failure_frame);
 
-               if (index != -1) {
-                   int freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-                   if (tid != MAX_TID_COUNT)
+               freed = iwl_tx_queue_reclaim(priv, txq_id, index);
+               if (qc && likely(sta_id != IWL_INVALID_STATION))
                        priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
-                   if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
-                       (txq_id >= 0) && priv->mac80211_registered)
+
+               if (priv->mac80211_registered &&
+                   (iwl_queue_space(&txq->q) > txq->q.low_mark))
                        ieee80211_wake_queue(priv->hw, txq_id);
-                   if (tid != MAX_TID_COUNT)
-                       iwl_txq_check_empty(priv, sta_id, tid, txq_id);
-               }
        }
 
+       if (qc && likely(sta_id != IWL_INVALID_STATION))
+               iwl_txq_check_empty(priv, sta_id, tid, txq_id);
+
        if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
                IWL_ERROR("TODO:  Implement Tx ABORT REQUIRED!!!\n");
 }
@@ -2347,7 +2323,7 @@ static struct iwl_lib_ops iwl4965_lib = {
                .reset = iwl4965_apm_reset,
                .stop = iwl4965_apm_stop,
                .config = iwl4965_nic_config,
-               .set_pwr_src = iwl4965_set_pwr_src,
+               .set_pwr_src = iwl_set_pwr_src,
        },
        .eeprom_ops = {
                .regulatory_bands = {
@@ -2362,11 +2338,11 @@ static struct iwl_lib_ops iwl4965_lib = {
                .verify_signature  = iwlcore_eeprom_verify_signature,
                .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
                .release_semaphore = iwlcore_eeprom_release_semaphore,
-               .check_version = iwl4965_eeprom_check_version,
+               .calib_version = iwl4965_eeprom_calib_version,
                .query_addr = iwlcore_eeprom_query_addr,
        },
        .send_tx_power  = iwl4965_send_tx_power,
-       .update_chain_flags = iwl4965_update_chain_flags,
+       .update_chain_flags = iwl_update_chain_flags,
        .temperature = iwl4965_temperature_calib,
 };
 
@@ -2381,6 +2357,8 @@ struct iwl_cfg iwl4965_agn_cfg = {
        .fw_name = "iwlwifi-4965" IWL4965_UCODE_API ".ucode",
        .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
        .eeprom_size = IWL4965_EEPROM_IMG_SIZE,
+       .eeprom_ver = EEPROM_4965_EEPROM_VERSION,
+       .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
        .ops = &iwl4965_ops,
        .mod_params = &iwl4965_mod_params,
 };
index c479ee211c5cf14d322db770c0c9e91a17a9e27a..12c74048a396683c9cef1fc446f0ace0c0847aa5 100644 (file)
 #define IWL50_RTC_INST_SIZE (IWL50_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
 #define IWL50_RTC_DATA_SIZE (IWL50_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
 
-/* EERPROM */
+/* EEPROM */
 #define IWL_5000_EEPROM_IMG_SIZE                       2048
 
-
-#define IWL50_MAX_WIN_SIZE                64
-#define IWL50_QUEUE_SIZE                 256
 #define IWL50_CMD_FIFO_NUM                 7
 #define IWL50_NUM_QUEUES                  20
 #define IWL50_NUM_AMPDU_QUEUES           10
 #define IWL50_FIRST_AMPDU_QUEUE                  10
 
-#define IWL_sta_id_POS 12
-#define IWL_sta_id_LEN 4
-#define IWL_sta_id_SYM val
-
 /* Fixed (non-configurable) rx data from phy */
 
-/* Base physical address of iwl5000_shared is provided to SCD_DRAM_BASE_ADDR
- * and &iwl5000_shared.val0 is provided to FH_RSCSR_CHNL0_STTS_WPTR_REG */
-struct iwl5000_sched_queue_byte_cnt_tbl {
-       struct iwl4965_queue_byte_cnt_entry tfd_offset[IWL50_QUEUE_SIZE +
-                                                      IWL50_MAX_WIN_SIZE];
+/**
+ * struct iwl5000_schedq_bc_tbl scheduler byte count table
+ *     base physical address of iwl5000_shared
+ *     is provided to SCD_DRAM_BASE_ADDR
+ * @tfd_offset  0-12 - tx command byte count
+ *            12-16 - station index
+ */
+struct iwl5000_schedq_bc_tbl {
+       __le16 tfd_offset[TFD_QUEUE_BC_SIZE];
 } __attribute__ ((packed));
 
+/**
+ * struct iwl5000_shared
+ * @rb_closed
+ *     address is provided to FH_RSCSR_CHNL0_STTS_WPTR_REG
+ */
 struct iwl5000_shared {
-       struct iwl5000_sched_queue_byte_cnt_tbl
-        queues_byte_cnt_tbls[IWL50_NUM_QUEUES];
+       struct iwl5000_schedq_bc_tbl queues_bc_tbls[IWL50_NUM_QUEUES];
        __le32 rb_closed;
 
        /* __le32 rb_closed_stts_rb_num:12; */
@@ -129,13 +130,5 @@ struct iwl5000_shared {
        __le32 padding2;
 } __attribute__ ((packed));
 
-/* calibrations defined for 5000 */
-/* defines the order in which results should be sent to the runtime uCode */
-enum iwl5000_calib {
-       IWL5000_CALIB_LO,
-       IWL5000_CALIB_TX_IQ,
-       IWL5000_CALIB_TX_IQ_PERD,
-};
-
 #endif /* __iwl_5000_hw_h__ */
 
index 5155b8a760a7299cd5b01ae139821ec3c5dd0fe1..31e62a838ad40696236ce9ebaef4ea2b94d1d979 100644 (file)
@@ -46,6 +46,8 @@
 
 #define IWL5000_UCODE_API  "-1"
 
+#define IWL5000_MODULE_FIRMWARE "iwlwifi-5000" IWL5000_UCODE_API ".ucode"
+
 static const u16 iwl5000_default_queue_to_tx_fifo[] = {
        IWL_TX_FIFO_AC3,
        IWL_TX_FIFO_AC2,
@@ -92,7 +94,7 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
        iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
                    CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
 
-       /* Set FH wait treshold to maximum (HW error during stress W/A) */
+       /* Set FH wait threshold to maximum (HW error during stress W/A) */
        iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
 
        /* enable HAP INTA to move device L1a -> L0s */
@@ -132,7 +134,7 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
        return ret;
 }
 
-/* FIXME: this is indentical to 4965 */
+/* FIXME: this is identical to 4965 */
 static void iwl5000_apm_stop(struct iwl_priv *priv)
 {
        unsigned long flags;
@@ -217,7 +219,7 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
 
        /* L1 is enabled by BIOS */
        if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
-               /* diable L0S disabled L1A enabled */
+               /* disable L0S disabled L1A enabled */
                iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
        else
                /* L0S enabled L1A disabled */
@@ -291,30 +293,17 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
        return (address & ADDRESS_MSK) + (offset << 1);
 }
 
-static int iwl5000_eeprom_check_version(struct iwl_priv *priv)
+static u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv)
 {
-       u16 eeprom_ver;
        struct iwl_eeprom_calib_hdr {
                u8 version;
                u8 pa_type;
                u16 voltage;
        } *hdr;
 
-       eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
-
        hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv,
                                                        EEPROM_5000_CALIB_ALL);
-
-       if (eeprom_ver < EEPROM_5000_EEPROM_VERSION ||
-           hdr->version < EEPROM_5000_TX_POWER_VERSION)
-               goto err;
-
-       return 0;
-err:
-       IWL_ERROR("Unsuported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
-                 eeprom_ver, EEPROM_5000_EEPROM_VERSION,
-                 hdr->version, EEPROM_5000_TX_POWER_VERSION);
-       return -EINVAL;
+       return hdr->version;
 
 }
 
@@ -348,10 +337,10 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
                        data->delta_gain_code[1], data->delta_gain_code[2]);
 
        if (!data->radio_write) {
-               struct iwl5000_calibration_chain_noise_gain_cmd cmd;
+               struct iwl_calib_chain_noise_gain_cmd cmd;
                memset(&cmd, 0, sizeof(cmd));
 
-               cmd.op_code = IWL5000_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD;
+               cmd.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD;
                cmd.delta_gain_1 = data->delta_gain_code[1];
                cmd.delta_gain_2 = data->delta_gain_code[2];
                iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD,
@@ -375,10 +364,10 @@ static void iwl5000_chain_noise_reset(struct iwl_priv *priv)
        struct iwl_chain_noise_data *data = &priv->chain_noise_data;
 
        if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) {
-               struct iwl5000_calibration_chain_noise_reset_cmd cmd;
+               struct iwl_calib_chain_noise_reset_cmd cmd;
 
                memset(&cmd, 0, sizeof(cmd));
-               cmd.op_code = IWL5000_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD;
+               cmd.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD;
                if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
                        sizeof(cmd), &cmd))
                        IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n");
@@ -390,8 +379,8 @@ static void iwl5000_chain_noise_reset(struct iwl_priv *priv)
 static void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
                        __le32 *tx_flags)
 {
-       if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
-           (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT))
+       if ((info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
+           (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
                *tx_flags |= TX_CMD_FLG_RTS_CTS_MSK;
        else
                *tx_flags &= ~TX_CMD_FLG_RTS_CTS_MSK;
@@ -429,28 +418,27 @@ static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
 /*
  *  Calibration
  */
-static int iwl5000_send_Xtal_calib(struct iwl_priv *priv)
+static int iwl5000_set_Xtal_calib(struct iwl_priv *priv)
 {
+       u8 data[sizeof(struct iwl_calib_hdr) +
+               sizeof(struct iwl_cal_xtal_freq)];
+       struct iwl_calib_cmd *cmd = (struct iwl_calib_cmd *)data;
+       struct iwl_cal_xtal_freq *xtal = (struct iwl_cal_xtal_freq *)cmd->data;
        u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
 
-       struct iwl5000_calibration cal_cmd = {
-               .op_code = IWL5000_PHY_CALIBRATE_CRYSTAL_FRQ_CMD,
-               .data = {
-                       (u8)xtal_calib[0],
-                       (u8)xtal_calib[1],
-               }
-       };
-
-       return iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
-                               sizeof(cal_cmd), &cal_cmd);
+       cmd->hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD;
+       xtal->cap_pin1 = (u8)xtal_calib[0];
+       xtal->cap_pin2 = (u8)xtal_calib[1];
+       return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL],
+                            data, sizeof(data));
 }
 
 static int iwl5000_send_calib_cfg(struct iwl_priv *priv)
 {
-       struct iwl5000_calib_cfg_cmd calib_cfg_cmd;
+       struct iwl_calib_cfg_cmd calib_cfg_cmd;
        struct iwl_host_cmd cmd = {
                .id = CALIBRATION_CFG_CMD,
-               .len = sizeof(struct iwl5000_calib_cfg_cmd),
+               .len = sizeof(struct iwl_calib_cfg_cmd),
                .data = &calib_cfg_cmd,
        };
 
@@ -467,7 +455,7 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
                             struct iwl_rx_mem_buffer *rxb)
 {
        struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl5000_calib_hdr *hdr = (struct iwl5000_calib_hdr *)pkt->u.raw;
+       struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
        int len = le32_to_cpu(pkt->len) & FH_RSCSR_FRAME_SIZE_MSK;
        int index;
 
@@ -478,14 +466,14 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
         * uCode. iwl_send_calib_results sends them in a row according to their
         * index. We sort them here */
        switch (hdr->op_code) {
-       case IWL5000_PHY_CALIBRATE_LO_CMD:
-               index = IWL5000_CALIB_LO;
+       case IWL_PHY_CALIBRATE_LO_CMD:
+               index = IWL_CALIB_LO;
                break;
-       case IWL5000_PHY_CALIBRATE_TX_IQ_CMD:
-               index = IWL5000_CALIB_TX_IQ;
+       case IWL_PHY_CALIBRATE_TX_IQ_CMD:
+               index = IWL_CALIB_TX_IQ;
                break;
-       case IWL5000_PHY_CALIBRATE_TX_IQ_PERD_CMD:
-               index = IWL5000_CALIB_TX_IQ_PERD;
+       case IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD:
+               index = IWL_CALIB_TX_IQ_PERD;
                break;
        default:
                IWL_ERROR("Unknown calibration notification %d\n",
@@ -535,7 +523,7 @@ static int iwl5000_load_section(struct iwl_priv *priv,
 
        iwl_write_direct32(priv,
                FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
-               (iwl_get_dma_hi_address(phy_addr)
+               (iwl_get_dma_hi_addr(phy_addr)
                        << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
 
        iwl_write_direct32(priv,
@@ -547,7 +535,7 @@ static int iwl5000_load_section(struct iwl_priv *priv,
        iwl_write_direct32(priv,
                FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
                FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE       |
-               FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL |
+               FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE    |
                FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
 
        iwl_release_nic_access(priv);
@@ -561,14 +549,13 @@ static int iwl5000_load_given_ucode(struct iwl_priv *priv,
 {
        int ret = 0;
 
-       ret = iwl5000_load_section(
-               priv, inst_image, RTC_INST_LOWER_BOUND);
+       ret = iwl5000_load_section(priv, inst_image, RTC_INST_LOWER_BOUND);
        if (ret)
                return ret;
 
        IWL_DEBUG_INFO("INST uCode section being loaded...\n");
        ret = wait_event_interruptible_timeout(priv->wait_command_queue,
-                               priv->ucode_write_complete, 5 * HZ);
+                                       priv->ucode_write_complete, 5 * HZ);
        if (ret == -ERESTARTSYS) {
                IWL_ERROR("Could not load the INST uCode section due "
                        "to interrupt\n");
@@ -682,7 +669,7 @@ static void iwl5000_tx_queue_set_status(struct iwl_priv *priv,
                                        int tx_fifo_id, int scd_retry)
 {
        int txq_id = txq->q.id;
-       int active = test_bit(txq_id, &priv->txq_ctx_active_msk)?1:0;
+       int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0;
 
        iwl_write_prph(priv, IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
                        (active << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
@@ -735,7 +722,7 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
 
        iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
                (priv->shared_phys +
-                offsetof(struct iwl5000_shared, queues_byte_cnt_tbls)) >> 10);
+                offsetof(struct iwl5000_shared, queues_bc_tbls)) >> 10);
        iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL,
                IWL50_SCD_QUEUECHAIN_SEL_ALL(
                        priv->hw_params.max_txq_num));
@@ -765,6 +752,7 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
        priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7));
 
        iwl5000_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
+
        /* map qos queues to fifos one-to-one */
        for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) {
                int ac = iwl5000_default_queue_to_tx_fifo[i];
@@ -784,10 +772,8 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
 
        iwl5000_send_wimax_coex(priv);
 
-       iwl5000_send_Xtal_calib(priv);
-
-       if (priv->ucode_type == UCODE_RT)
-               iwl_send_calib_results(priv);
+       iwl5000_set_Xtal_calib(priv);
+       iwl_send_calib_results(priv);
 
        return 0;
 }
@@ -802,7 +788,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
        }
 
        priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
-       priv->hw_params.first_ampdu_q = IWL50_FIRST_AMPDU_QUEUE;
        priv->hw_params.max_stations = IWL5000_STATION_COUNT;
        priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
        priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
@@ -814,10 +799,14 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 
        switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
        case CSR_HW_REV_TYPE_5100:
+               priv->hw_params.tx_chains_num = 1;
+               priv->hw_params.rx_chains_num = 2;
+               priv->hw_params.valid_tx_ant = ANT_B;
+               priv->hw_params.valid_rx_ant = ANT_AB;
+               break;
        case CSR_HW_REV_TYPE_5150:
                priv->hw_params.tx_chains_num = 1;
                priv->hw_params.rx_chains_num = 2;
-               /* FIXME: move to ANT_A, ANT_B, ANT_C enum */
                priv->hw_params.valid_tx_ant = ANT_A;
                priv->hw_params.valid_rx_ant = ANT_AB;
                break;
@@ -844,6 +833,23 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
                break;
        }
 
+       /* Set initial calibration set */
+       switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+       case CSR_HW_REV_TYPE_5100:
+       case CSR_HW_REV_TYPE_5300:
+       case CSR_HW_REV_TYPE_5350:
+               priv->hw_params.calib_init_cfg =
+                       BIT(IWL_CALIB_XTAL)             |
+                       BIT(IWL_CALIB_LO)               |
+                       BIT(IWL_CALIB_TX_IQ)    |
+                       BIT(IWL_CALIB_TX_IQ_PERD);
+               break;
+       case CSR_HW_REV_TYPE_5150:
+               priv->hw_params.calib_init_cfg = 0;
+               break;
+       }
+
+
        return 0;
 }
 
@@ -885,15 +891,17 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
                                            u16 byte_cnt)
 {
        struct iwl5000_shared *shared_data = priv->shared_virt;
+       int write_ptr = txq->q.write_ptr;
        int txq_id = txq->q.id;
        u8 sec_ctl = 0;
-       u8 sta = 0;
-       int len;
+       u8 sta_id = 0;
+       u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
+       __le16 bc_ent;
 
-       len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
+       WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
 
        if (txq_id != IWL_CMD_QUEUE_NUM) {
-               sta = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
+               sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
                sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
 
                switch (sec_ctl & TX_CMD_SEC_MSK) {
@@ -909,40 +917,36 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
                }
        }
 
-       IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id].
-                      tfd_offset[txq->q.write_ptr], byte_cnt, len);
+       bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
 
-       IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id].
-                      tfd_offset[txq->q.write_ptr], sta_id, sta);
+       shared_data->queues_bc_tbls[txq_id].tfd_offset[write_ptr] = bc_ent;
 
-       if (txq->q.write_ptr < IWL50_MAX_WIN_SIZE) {
-               IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id].
-                       tfd_offset[IWL50_QUEUE_SIZE + txq->q.write_ptr],
-                       byte_cnt, len);
-               IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id].
-                       tfd_offset[IWL50_QUEUE_SIZE + txq->q.write_ptr],
-                       sta_id, sta);
-       }
+       if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
+               shared_data->queues_bc_tbls[txq_id].
+                       tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
 }
 
 static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
                                           struct iwl_tx_queue *txq)
 {
-       int txq_id = txq->q.id;
        struct iwl5000_shared *shared_data = priv->shared_virt;
-       u8 sta = 0;
+       int txq_id = txq->q.id;
+       int read_ptr = txq->q.read_ptr;
+       u8 sta_id = 0;
+       __le16 bc_ent;
+
+       WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
 
        if (txq_id != IWL_CMD_QUEUE_NUM)
-               sta = txq->cmd[txq->q.read_ptr]->cmd.tx.sta_id;
+               sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
 
-       shared_data->queues_byte_cnt_tbls[txq_id].tfd_offset[txq->q.read_ptr].
-                                       val = cpu_to_le16(1 | (sta << 12));
+       bc_ent =  cpu_to_le16(1 | (sta_id << 12));
+       shared_data->queues_bc_tbls[txq_id].
+                       tfd_offset[read_ptr] = bc_ent;
 
-       if (txq->q.write_ptr < IWL50_MAX_WIN_SIZE) {
-               shared_data->queues_byte_cnt_tbls[txq_id].
-                       tfd_offset[IWL50_QUEUE_SIZE + txq->q.read_ptr].
-                               val = cpu_to_le16(1 | (sta << 12));
-       }
+       if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
+               shared_data->queues_bc_tbls[txq_id].
+                       tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] =  bc_ent;
 }
 
 static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
@@ -1089,7 +1093,7 @@ static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
 
 
 /*
- * Activate/Deactivat Tx DMA/FIFO channels according tx fifos mask
+ * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
  * must be called under priv->lock and mac access
  */
 static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)
@@ -1136,10 +1140,10 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
                                   agg->frame_count, agg->start_idx, idx);
 
                info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
-               info->status.retry_count = tx_resp->failure_frame;
+               info->status.rates[0].count = tx_resp->failure_frame + 1;
                info->flags &= ~IEEE80211_TX_CTL_AMPDU;
                info->flags |= iwl_is_tx_success(status)?
-                       IEEE80211_TX_STAT_ACK : 0;
+                                       IEEE80211_TX_STAT_ACK : 0;
                iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
 
                /* FIXME: code repetition end */
@@ -1225,9 +1229,9 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
        struct ieee80211_tx_info *info;
        struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
        u32  status = le16_to_cpu(tx_resp->status.status);
-       int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
-       struct ieee80211_hdr *hdr;
-       u8 *qc = NULL;
+       int tid;
+       int sta_id;
+       int freed;
 
        if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
                IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
@@ -1240,25 +1244,13 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
        info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
        memset(&info->status, 0, sizeof(info->status));
 
-       hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
-       if (ieee80211_is_data_qos(hdr->frame_control)) {
-               qc = ieee80211_get_qos_ctl(hdr);
-               tid = qc[0] & 0xf;
-       }
-
-       sta_id = iwl_get_ra_sta_id(priv, hdr);
-       if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) {
-               IWL_ERROR("Station not known\n");
-               return;
-       }
+       tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS;
+       sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS;
 
        if (txq->sched_retry) {
                const u32 scd_ssn = iwl5000_get_scd_ssn(tx_resp);
                struct iwl_ht_agg *agg = NULL;
 
-               if (!qc)
-                       return;
-
                agg = &priv->stations[sta_id].tid[tid].agg;
 
                iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
@@ -1268,58 +1260,58 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
                        info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
 
                if (txq->q.read_ptr != (scd_ssn & 0xff)) {
-                       int freed, ampdu_q;
                        index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
-                       IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
-                                          "%d index %d\n", scd_ssn , index);
+                       IWL_DEBUG_TX_REPLY("Retry scheduler reclaim "
+                                       "scd_ssn=%d idx=%d txq=%d swq=%d\n",
+                                       scd_ssn , index, txq_id, txq->swq_id);
+
                        freed = iwl_tx_queue_reclaim(priv, txq_id, index);
                        priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
 
-                       if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
-                           txq_id >= 0 && priv->mac80211_registered &&
-                           agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) {
-                               /* calculate mac80211 ampdu sw queue to wake */
-                               ampdu_q = txq_id - IWL50_FIRST_AMPDU_QUEUE +
-                                         priv->hw->queues;
+                       if (priv->mac80211_registered &&
+                           (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
+                           (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
                                if (agg->state == IWL_AGG_OFF)
                                        ieee80211_wake_queue(priv->hw, txq_id);
                                else
-                                       ieee80211_wake_queue(priv->hw, ampdu_q);
+                                       ieee80211_wake_queue(priv->hw,
+                                                            txq->swq_id);
                        }
-                       iwl_txq_check_empty(priv, sta_id, tid, txq_id);
                }
        } else {
-               info->status.retry_count = tx_resp->failure_frame;
-               info->flags =
-                       iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
+               BUG_ON(txq_id != txq->swq_id);
+
+               info->status.rates[0].count = tx_resp->failure_frame + 1;
+               info->flags |= iwl_is_tx_success(status) ?
+                                       IEEE80211_TX_STAT_ACK : 0;
                iwl_hwrate_to_tx_control(priv,
                                        le32_to_cpu(tx_resp->rate_n_flags),
                                        info);
 
-               IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags "
-                            "0x%x retries %d\n", txq_id,
-                               iwl_get_tx_fail_reason(status),
-                               status, le32_to_cpu(tx_resp->rate_n_flags),
-                               tx_resp->failure_frame);
+               IWL_DEBUG_TX_REPLY("TXQ %d status %s (0x%08x) rate_n_flags "
+                                  "0x%x retries %d\n",
+                                  txq_id,
+                                  iwl_get_tx_fail_reason(status), status,
+                                  le32_to_cpu(tx_resp->rate_n_flags),
+                                  tx_resp->failure_frame);
 
-               IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
-               if (index != -1) {
-                   int freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-                   if (tid != MAX_TID_COUNT)
+               freed = iwl_tx_queue_reclaim(priv, txq_id, index);
+               if (ieee80211_is_data_qos(tx_resp->frame_ctrl))
                        priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
-                   if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
-                       (txq_id >= 0) && priv->mac80211_registered)
+
+               if (priv->mac80211_registered &&
+                   (iwl_queue_space(&txq->q) > txq->q.low_mark))
                        ieee80211_wake_queue(priv->hw, txq_id);
-                   if (tid != MAX_TID_COUNT)
-                       iwl_txq_check_empty(priv, sta_id, tid, txq_id);
-               }
        }
 
+       if (ieee80211_is_data_qos(tx_resp->frame_ctrl))
+               iwl_txq_check_empty(priv, sta_id, tid, txq_id);
+
        if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
                IWL_ERROR("TODO:  Implement Tx ABORT REQUIRED!!!\n");
 }
 
-/* Currently 5000 is the supperset of everything */
+/* Currently 5000 is the superset of everything */
 static u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len)
 {
        return len;
@@ -1482,13 +1474,13 @@ static struct iwl_lib_ops iwl5000_lib = {
        .alive_notify = iwl5000_alive_notify,
        .send_tx_power = iwl5000_send_tx_power,
        .temperature = iwl5000_temperature,
-       .update_chain_flags = iwl4965_update_chain_flags,
+       .update_chain_flags = iwl_update_chain_flags,
        .apm_ops = {
                .init = iwl5000_apm_init,
                .reset = iwl5000_apm_reset,
                .stop = iwl5000_apm_stop,
                .config = iwl5000_nic_config,
-               .set_pwr_src = iwl4965_set_pwr_src,
+               .set_pwr_src = iwl_set_pwr_src,
        },
        .eeprom_ops = {
                .regulatory_bands = {
@@ -1503,7 +1495,7 @@ static struct iwl_lib_ops iwl5000_lib = {
                .verify_signature  = iwlcore_eeprom_verify_signature,
                .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
                .release_semaphore = iwlcore_eeprom_release_semaphore,
-               .check_version  = iwl5000_eeprom_check_version,
+               .calib_version  = iwl5000_eeprom_calib_version,
                .query_addr = iwl5000_eeprom_query_addr,
        },
 };
@@ -1526,50 +1518,60 @@ static struct iwl_mod_params iwl50_mod_params = {
 
 struct iwl_cfg iwl5300_agn_cfg = {
        .name = "5300AGN",
-       .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode",
+       .fw_name = IWL5000_MODULE_FIRMWARE,
        .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
        .ops = &iwl5000_ops,
        .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+       .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+       .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
        .mod_params = &iwl50_mod_params,
 };
 
 struct iwl_cfg iwl5100_bg_cfg = {
        .name = "5100BG",
-       .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode",
+       .fw_name = IWL5000_MODULE_FIRMWARE,
        .sku = IWL_SKU_G,
        .ops = &iwl5000_ops,
        .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+       .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+       .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
        .mod_params = &iwl50_mod_params,
 };
 
 struct iwl_cfg iwl5100_abg_cfg = {
        .name = "5100ABG",
-       .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode",
+       .fw_name = IWL5000_MODULE_FIRMWARE,
        .sku = IWL_SKU_A|IWL_SKU_G,
        .ops = &iwl5000_ops,
        .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+       .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+       .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
        .mod_params = &iwl50_mod_params,
 };
 
 struct iwl_cfg iwl5100_agn_cfg = {
        .name = "5100AGN",
-       .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode",
+       .fw_name = IWL5000_MODULE_FIRMWARE,
        .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
        .ops = &iwl5000_ops,
        .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+       .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+       .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
        .mod_params = &iwl50_mod_params,
 };
 
 struct iwl_cfg iwl5350_agn_cfg = {
        .name = "5350AGN",
-       .fw_name = "iwlwifi-5000" IWL5000_UCODE_API ".ucode",
+       .fw_name = IWL5000_MODULE_FIRMWARE,
        .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
        .ops = &iwl5000_ops,
        .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+       .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
+       .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
        .mod_params = &iwl50_mod_params,
 };
 
-MODULE_FIRMWARE("iwlwifi-5000" IWL5000_UCODE_API ".ucode");
+MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE);
 
 module_param_named(disable50, iwl50_mod_params.disable, int, 0444);
 MODULE_PARM_DESC(disable50,
index e2a58e477036e611da5ffc78abeda5748f7392ce..0332805cc6306e9d06ea101ad9b1d866a2db0863 100644 (file)
@@ -188,7 +188,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
  * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits
  * "G" is the only table that supports CCK (the first 4 rates).
  */
-/*FIXME:RS:need to spearate tables for MIMO2/MIMO3*/
+/*FIXME:RS:need to separate tables for MIMO2/MIMO3*/
 static s32 expected_tpt_A[IWL_RATE_COUNT] = {
        0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186
 };
@@ -357,11 +357,9 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
                                      struct iwl_lq_sta *lq_data, u8 tid,
                                      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->addr), tid);
+               IWL_DEBUG_HT("Starting Tx agg: STA: %pM tid: %d\n",
+                               sta->addr, tid);
                ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid);
        }
 }
@@ -800,7 +798,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
            !(info->flags & IEEE80211_TX_STAT_AMPDU))
                return;
 
-       retries = info->status.retry_count;
+       retries = info->status.rates[0].count - 1;
 
        if (retries > 15)
                retries = 15;
@@ -832,20 +830,15 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
        if (priv->band == IEEE80211_BAND_5GHZ)
                rs_index -= IWL_FIRST_OFDM_RATE;
 
-       if ((info->tx_rate_idx < 0) ||
-           (tbl_type.is_SGI ^
-               !!(info->flags & IEEE80211_TX_CTL_SHORT_GI)) ||
-           (tbl_type.is_fat ^
-               !!(info->flags & IEEE80211_TX_CTL_40_MHZ_WIDTH)) ||
-           (tbl_type.is_dup ^
-               !!(info->flags & IEEE80211_TX_CTL_DUP_DATA)) ||
-           (tbl_type.ant_type ^ info->antenna_sel_tx) ||
-           (!!(tx_rate & RATE_MCS_HT_MSK) ^
-               !!(info->flags & IEEE80211_TX_CTL_OFDM_HT)) ||
-           (!!(tx_rate & RATE_MCS_GF_MSK) ^
-               !!(info->flags & IEEE80211_TX_CTL_GREEN_FIELD)) ||
+       if ((info->status.rates[0].idx < 0) ||
+           (tbl_type.is_SGI != !!(info->status.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)) ||
+           (tbl_type.is_fat != !!(info->status.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) ||
+           (tbl_type.is_dup != !!(info->status.rates[0].flags & IEEE80211_TX_RC_DUP_DATA)) ||
+           (tbl_type.ant_type != info->antenna_sel_tx) ||
+           (!!(tx_rate & RATE_MCS_HT_MSK) != !!(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) ||
+           (!!(tx_rate & RATE_MCS_GF_MSK) != !!(info->status.rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
            (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate !=
-            hw->wiphy->bands[info->band]->bitrates[info->tx_rate_idx].bitrate)) {
+            hw->wiphy->bands[info->band]->bitrates[info->status.rates[0].idx].bitrate)) {
                IWL_DEBUG_RATE("initial rate does not match 0x%x\n", tx_rate);
                goto out;
        }
@@ -1135,11 +1128,10 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
        s32 rate;
        s8 is_green = lq_sta->is_green;
 
-       if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) ||
-           !sta->ht_info.ht_supported)
+       if (!conf->ht.enabled || !sta->ht_cap.ht_supported)
                return -1;
 
-       if (((sta->ht_info.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
+       if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
                                                == WLAN_HT_CAP_SM_PS_STATIC)
                return -1;
 
@@ -1203,8 +1195,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
        u8 is_green = lq_sta->is_green;
        s32 rate;
 
-       if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) ||
-           !sta->ht_info.ht_supported)
+       if (!conf->ht.enabled || !sta->ht_cap.ht_supported)
                return -1;
 
        IWL_DEBUG_RATE("LQ: try to switch to SISO\n");
@@ -2003,9 +1994,8 @@ lq_update:
                 * stay with best antenna legacy modulation for a while
                 * before next round of mode comparisons. */
                tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
-               if (is_legacy(tbl1->lq_type) &&
-                  (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) &&
-                   (lq_sta->action_counter >= 1)) {
+               if (is_legacy(tbl1->lq_type) && !conf->ht.enabled &&
+                   lq_sta->action_counter >= 1) {
                        lq_sta->action_counter = 0;
                        IWL_DEBUG_RATE("LQ: STAY in legacy table\n");
                        rs_set_stay_in_table(priv, 1, lq_sta);
@@ -2081,15 +2071,13 @@ static void rs_initialize_lq(struct iwl_priv *priv,
        if ((i < 0) || (i >= IWL_RATE_COUNT))
                i = 0;
 
-       /* FIXME:RS: This is also wrong in 4965 */
        rate = iwl_rates[i].plcp;
-       rate |= RATE_MCS_ANT_B_MSK;
-       rate &= ~RATE_MCS_ANT_A_MSK;
+       tbl->ant_type = first_antenna(valid_tx_ant);
+       rate |= tbl->ant_type << RATE_MCS_ANT_POS;
 
        if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE)
                rate |= RATE_MCS_CCK_MSK;
 
-       tbl->ant_type = ANT_B;
        rs_get_tbl_info_from_mcs(rate, priv->band, tbl, &rate_idx);
        if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type))
            rs_toggle_antenna(valid_tx_ant, &rate, tbl);
@@ -2103,15 +2091,17 @@ static void rs_initialize_lq(struct iwl_priv *priv,
        return;
 }
 
-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)
+static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
+                       struct ieee80211_tx_rate_control *txrc)
 {
 
        int i;
+       struct sk_buff *skb = txrc->skb;
+       struct ieee80211_supported_band *sband = txrc->sband;
        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 ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        __le16 fc;
        struct iwl_lq_sta *lq_sta;
 
@@ -2122,7 +2112,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband,
        fc = hdr->frame_control;
        if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
            !sta || !priv_sta) {
-               sel->rate_idx = rate_lowest_index(sband, sta);
+               info->control.rates[0].idx = rate_lowest_index(sband, sta);
                return;
        }
 
@@ -2132,11 +2122,10 @@ static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband,
        if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
            !lq_sta->ibss_sta_added) {
                u8 sta_id = iwl_find_station(priv, hdr->addr1);
-               DECLARE_MAC_BUF(mac);
 
                if (sta_id == IWL_INVALID_STATION) {
-                       IWL_DEBUG_RATE("LQ: ADD station %s\n",
-                                      print_mac(mac, hdr->addr1));
+                       IWL_DEBUG_RATE("LQ: ADD station %pM\n",
+                                      hdr->addr1);
                        sta_id = iwl_add_station_flags(priv, hdr->addr1,
                                                        0, CMD_ASYNC, NULL);
                }
@@ -2149,13 +2138,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband,
        }
 
        if ((i < 0) || (i > IWL_RATE_COUNT)) {
-               sel->rate_idx = rate_lowest_index(sband, sta);
+               info->control.rates[0].idx = rate_lowest_index(sband, sta);
                return;
        }
 
        if (sband->band == IEEE80211_BAND_5GHZ)
                i -= IWL_FIRST_OFDM_RATE;
-       sel->rate_idx = i;
+       info->control.rates[0].idx = i;
 }
 
 static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
@@ -2205,15 +2194,12 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
        lq_sta->ibss_sta_added = 0;
        if (priv->iw_mode == NL80211_IFTYPE_AP) {
                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->addr));
+               IWL_DEBUG_RATE("LQ: ADD station %pM\n", sta->addr);
 
                if (sta_id == IWL_INVALID_STATION) {
-                       IWL_DEBUG_RATE("LQ: ADD station %s\n",
-                                      print_mac(mac, sta->addr));
+                       IWL_DEBUG_RATE("LQ: ADD station %pM\n", sta->addr);
                        sta_id = iwl_add_station_flags(priv, sta->addr,
                                                        0, CMD_ASYNC, NULL);
                }
@@ -2244,19 +2230,19 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
         * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
         * supp_rates[] does not; shift to convert format, force 9 MBits off.
         */
-       lq_sta->active_siso_rate = conf->ht_conf.supp_mcs_set[0] << 1;
-       lq_sta->active_siso_rate |= conf->ht_conf.supp_mcs_set[0] & 0x1;
+       lq_sta->active_siso_rate = sta->ht_cap.mcs.rx_mask[0] << 1;
+       lq_sta->active_siso_rate |= sta->ht_cap.mcs.rx_mask[0] & 0x1;
        lq_sta->active_siso_rate &= ~((u16)0x2);
        lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;
 
        /* Same here */
-       lq_sta->active_mimo2_rate = conf->ht_conf.supp_mcs_set[1] << 1;
-       lq_sta->active_mimo2_rate |= conf->ht_conf.supp_mcs_set[1] & 0x1;
+       lq_sta->active_mimo2_rate = sta->ht_cap.mcs.rx_mask[1] << 1;
+       lq_sta->active_mimo2_rate |= sta->ht_cap.mcs.rx_mask[1] & 0x1;
        lq_sta->active_mimo2_rate &= ~((u16)0x2);
        lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
 
-       lq_sta->active_mimo3_rate = conf->ht_conf.supp_mcs_set[2] << 1;
-       lq_sta->active_mimo3_rate |= conf->ht_conf.supp_mcs_set[2] & 0x1;
+       lq_sta->active_mimo3_rate = sta->ht_cap.mcs.rx_mask[2] << 1;
+       lq_sta->active_mimo3_rate |= sta->ht_cap.mcs.rx_mask[2] & 0x1;
        lq_sta->active_mimo3_rate &= ~((u16)0x2);
        lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;
 
@@ -2265,7 +2251,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
                     lq_sta->active_mimo2_rate,
                     lq_sta->active_mimo3_rate);
 
-       /* These values will be overriden later */
+       /* These values will be overridden later */
        lq_sta->lq.general_params.single_stream_ant_msk = ANT_A;
        lq_sta->lq.general_params.dual_stream_ant_msk = ANT_AB;
 
@@ -2405,19 +2391,6 @@ static void rs_free(void *priv_rate)
        return;
 }
 
-static void rs_clear(void *priv_rate)
-{
-#ifdef CONFIG_IWLWIFI_DEBUG
-       struct iwl_priv *priv = (struct iwl_priv *) priv_rate;
-
-       IWL_DEBUG_RATE("enter\n");
-
-       /* TODO - add rate scale state reset */
-
-       IWL_DEBUG_RATE("leave\n");
-#endif /* CONFIG_IWLWIFI_DEBUG */
-}
-
 static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
                        void *priv_sta)
 {
@@ -2605,7 +2578,6 @@ static struct rate_control_ops rs_ops = {
        .tx_status = rs_tx_status,
        .get_rate = rs_get_rate,
        .rate_init = rs_rate_init,
-       .clear = rs_clear,
        .alloc = rs_alloc,
        .free = rs_free,
        .alloc_sta = rs_alloc_sta,
index d148d73635eb5ddec4669fc1fe0bf185959a5d04..adcbf538ed54054321f5f56e48dab3a73382d1c4 100644 (file)
@@ -229,7 +229,7 @@ enum {
 #define IWL_MIMO2_SWITCH_SISO_C         4
 #define IWL_MIMO2_SWITCH_GI             5
 
-/*FIXME:RS:add posible acctions for MIMO3*/
+/*FIXME:RS:add possible actions for MIMO3*/
 
 #define IWL_ACTION_LIMIT               3       /* # possible actions */
 
@@ -284,7 +284,17 @@ static inline u8 num_of_ant(u8 mask)
                !!((mask) & ANT_C);
 }
 
-static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
+static inline u8 first_antenna(u8 mask)
+{
+       if (mask & ANT_A)
+               return ANT_A;
+       if (mask & ANT_B)
+               return ANT_B;
+       return ANT_C;
+}
+
+
+static inline u8 iwl_get_prev_ieee_rate(u8 rate_index)
 {
        u8 rate = iwl_rates[rate_index].prev_ieee;
 
@@ -294,11 +304,11 @@ static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
 }
 
 /**
- * iwl4965_rate_control_register - Register the rate control algorithm callbacks
+ * iwl_rate_control_register - Register the rate control algorithm callbacks
  *
  * Since the rate control algorithm is hardware specific, there is no need
  * or reason to place it as a stand alone module.  The driver can call
- * iwl4965_rate_control_register in order to register the rate control callbacks
+ * iwl_rate_control_register in order to register the rate control callbacks
  * with the mac80211 subsystem.  This should be performed prior to calling
  * ieee80211_register_hw
  *
@@ -306,7 +316,7 @@ static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
 extern int iwlagn_rate_control_register(void);
 
 /**
- * iwl4965_rate_control_unregister - Unregister the rate control callbacks
+ * iwl_rate_control_unregister - Unregister the rate control callbacks
  *
  * This should be called after calling ieee80211_unregister_hw, but before
  * the driver is unloaded.
index 8d690a0eb1a967722508942d9fdd90225c98be47..8264d3742d0881c28cd079276a9794f60fac8e10 100644 (file)
@@ -96,7 +96,7 @@ MODULE_ALIAS("iwl4965");
 
 
 
-static void iwl4965_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
+static void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
 {
        struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
 
@@ -108,13 +108,13 @@ static void iwl4965_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
 }
 
 /**
- * iwl4965_check_rxon_cmd - validate RXON structure is valid
+ * iwl_check_rxon_cmd - validate RXON structure is valid
  *
  * NOTE:  This is really only useful during development and can eventually
  * be #ifdef'd out once the driver is stable and folks aren't actively
  * making changes
  */
-static int iwl4965_check_rxon_cmd(struct iwl_rxon_cmd *rxon)
+static int iwl_check_rxon_cmd(struct iwl_rxon_cmd *rxon)
 {
        int error = 0;
        int counter = 1;
@@ -174,7 +174,7 @@ static int iwl4965_check_rxon_cmd(struct iwl_rxon_cmd *rxon)
                            le16_to_cpu(rxon->channel));
 
        if (error) {
-               IWL_ERROR("Not a valid iwl4965_rxon_assoc_cmd field values\n");
+               IWL_ERROR("Not a valid iwl_rxon_assoc_cmd field values\n");
                return -1;
        }
        return 0;
@@ -228,18 +228,17 @@ static int iwl_full_rxon_required(struct iwl_priv *priv)
 }
 
 /**
- * iwl4965_commit_rxon - commit staging_rxon to hardware
+ * iwl_commit_rxon - commit staging_rxon to hardware
  *
  * The RXON command in staging_rxon is committed to the hardware and
  * the active_rxon structure is updated with the new data.  This
  * function correctly transitions out of the RXON_ASSOC_MSK state if
  * a HW tune is required based on the RXON structure changes.
  */
-static int iwl4965_commit_rxon(struct iwl_priv *priv)
+static int iwl_commit_rxon(struct iwl_priv *priv)
 {
        /* cast away the const for active_rxon in this function */
        struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
-       DECLARE_MAC_BUF(mac);
        int ret;
        bool new_assoc =
                !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
@@ -253,14 +252,14 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv)
         * 5000, but will not damage 4965 */
        priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
 
-       ret = iwl4965_check_rxon_cmd(&priv->staging_rxon);
+       ret = iwl_check_rxon_cmd(&priv->staging_rxon);
        if (ret) {
                IWL_ERROR("Invalid RXON configuration.  Not committing.\n");
                return -EINVAL;
        }
 
        /* If we don't need to send a full RXON, we can use
-        * iwl4965_rxon_assoc_cmd which is used to reconfigure filter
+        * iwl_rxon_assoc_cmd which is used to reconfigure filter
         * and other flags for the current radio configuration. */
        if (!iwl_full_rxon_required(priv)) {
                ret = iwl_send_rxon_assoc(priv);
@@ -300,12 +299,12 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv)
        IWL_DEBUG_INFO("Sending RXON\n"
                       "* with%s RXON_FILTER_ASSOC_MSK\n"
                       "* channel = %d\n"
-                      "* bssid = %s\n",
+                      "* bssid = %pM\n",
                       (new_assoc ? "" : "out"),
                       le16_to_cpu(priv->staging_rxon.channel),
-                      print_mac(mac, priv->staging_rxon.bssid_addr));
+                      priv->staging_rxon.bssid_addr);
 
-       iwl4965_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
+       iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
 
        /* Apply the new configuration
         * RXON unassoc clears the station table in uCode, send it before
@@ -375,14 +374,14 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv)
        return 0;
 }
 
-void iwl4965_update_chain_flags(struct iwl_priv *priv)
+void iwl_update_chain_flags(struct iwl_priv *priv)
 {
 
        iwl_set_rxon_chain(priv);
-       iwl4965_commit_rxon(priv);
+       iwl_commit_rxon(priv);
 }
 
-static int iwl4965_send_bt_config(struct iwl_priv *priv)
+static int iwl_send_bt_config(struct iwl_priv *priv)
 {
        struct iwl4965_bt_cmd bt_cmd = {
                .flags = 3,
@@ -460,7 +459,7 @@ static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
        return priv->ibss_beacon->len;
 }
 
-static u8 iwl4965_rate_get_lowest_plcp(struct iwl_priv *priv)
+static u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv)
 {
        int i;
        int rate_mask;
@@ -485,7 +484,7 @@ static u8 iwl4965_rate_get_lowest_plcp(struct iwl_priv *priv)
                return IWL_RATE_6M_PLCP;
 }
 
-static unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
+static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
                                       struct iwl_frame *frame, u8 rate)
 {
        struct iwl_tx_beacon_cmd *tx_beacon_cmd;
@@ -517,7 +516,7 @@ static unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
 
        return sizeof(*tx_beacon_cmd) + frame_size;
 }
-static int iwl4965_send_beacon_cmd(struct iwl_priv *priv)
+static int iwl_send_beacon_cmd(struct iwl_priv *priv)
 {
        struct iwl_frame *frame;
        unsigned int frame_size;
@@ -532,9 +531,9 @@ static int iwl4965_send_beacon_cmd(struct iwl_priv *priv)
                return -ENOMEM;
        }
 
-       rate = iwl4965_rate_get_lowest_plcp(priv);
+       rate = iwl_rate_get_lowest_plcp(priv);
 
-       frame_size = iwl4965_hw_get_beacon_cmd(priv, frame, rate);
+       frame_size = iwl_hw_get_beacon_cmd(priv, frame, rate);
 
        rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
                              &frame->u.cmd[0]);
@@ -550,20 +549,33 @@ static int iwl4965_send_beacon_cmd(struct iwl_priv *priv)
  *
  ******************************************************************************/
 
-static void iwl4965_ht_conf(struct iwl_priv *priv,
+static void iwl_ht_conf(struct iwl_priv *priv,
                            struct ieee80211_bss_conf *bss_conf)
 {
-       struct ieee80211_ht_info *ht_conf = bss_conf->ht_conf;
-       struct ieee80211_ht_bss_info *ht_bss_conf = bss_conf->ht_bss_conf;
+       struct ieee80211_sta_ht_cap *ht_conf;
        struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
+       struct ieee80211_sta *sta;
 
        IWL_DEBUG_MAC80211("enter: \n");
 
-       iwl_conf->is_ht = bss_conf->assoc_ht;
-
        if (!iwl_conf->is_ht)
                return;
 
+
+       /*
+        * It is totally wrong to base global information on something
+        * that is valid only when associated, alas, this driver works
+        * that way and I don't know how to fix it.
+        */
+
+       rcu_read_lock();
+       sta = ieee80211_find_sta(priv->hw, priv->bssid);
+       if (!sta) {
+               rcu_read_unlock();
+               return;
+       }
+       ht_conf = &sta->ht_cap;
+
        if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
                iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
        if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
@@ -574,29 +586,28 @@ static void iwl4965_ht_conf(struct iwl_priv *priv,
                !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
 
        iwl_conf->supported_chan_width =
-               !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH);
-       iwl_conf->extension_chan_offset =
-               ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET;
+               !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
+
+       iwl_conf->extension_chan_offset = bss_conf->ht.secondary_channel_offset;
        /* If no above or below channel supplied disable FAT channel */
-       if (iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_ABOVE &&
-           iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_BELOW) {
-               iwl_conf->extension_chan_offset = IEEE80211_HT_IE_CHA_SEC_NONE;
+       if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE &&
+           iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW) {
+               iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
                iwl_conf->supported_chan_width = 0;
        }
 
        iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
 
-       memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16);
+       memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16);
 
-       iwl_conf->control_channel = ht_bss_conf->primary_channel;
-       iwl_conf->tx_chan_width =
-               !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH);
+       iwl_conf->tx_chan_width = bss_conf->ht.width_40_ok;
        iwl_conf->ht_protection =
-               ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_HT_PROTECTION;
+               bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
        iwl_conf->non_GF_STA_present =
-               !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_NON_GF_STA_PRSNT);
+               !!(bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+
+       rcu_read_unlock();
 
-       IWL_DEBUG_MAC80211("control channel %d\n", iwl_conf->control_channel);
        IWL_DEBUG_MAC80211("leave\n");
 }
 
@@ -637,23 +648,22 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
 
 #define MAX_UCODE_BEACON_INTERVAL      4096
 
-static __le16 iwl4965_adjust_beacon_interval(u16 beacon_val)
+static u16 iwl_adjust_beacon_interval(u16 beacon_val)
 {
        u16 new_val = 0;
        u16 beacon_factor = 0;
 
-       beacon_factor =
-           (beacon_val + MAX_UCODE_BEACON_INTERVAL)
-               / MAX_UCODE_BEACON_INTERVAL;
+       beacon_factor = (beacon_val + MAX_UCODE_BEACON_INTERVAL)
+                                       / MAX_UCODE_BEACON_INTERVAL;
        new_val = beacon_val / beacon_factor;
 
-       return cpu_to_le16(new_val);
+       return new_val;
 }
 
-static void iwl4965_setup_rxon_timing(struct iwl_priv *priv)
+static void iwl_setup_rxon_timing(struct iwl_priv *priv)
 {
-       u64 interval_tm_unit;
-       u64 tsf, result;
+       u64 tsf;
+       s32 interval_tm, rem;
        unsigned long flags;
        struct ieee80211_conf *conf = NULL;
        u16 beacon_int = 0;
@@ -661,49 +671,32 @@ static void iwl4965_setup_rxon_timing(struct iwl_priv *priv)
        conf = ieee80211_get_hw_conf(priv->hw);
 
        spin_lock_irqsave(&priv->lock, flags);
-       priv->rxon_timing.timestamp.dw[1] = cpu_to_le32(priv->timestamp >> 32);
-       priv->rxon_timing.timestamp.dw[0] =
-                               cpu_to_le32(priv->timestamp & 0xFFFFFFFF);
-
+       priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
        priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);
 
-       tsf = priv->timestamp;
-
-       beacon_int = priv->beacon_int;
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        if (priv->iw_mode == NL80211_IFTYPE_STATION) {
-               if (beacon_int == 0) {
-                       priv->rxon_timing.beacon_interval = cpu_to_le16(100);
-                       priv->rxon_timing.beacon_init_val = cpu_to_le32(102400);
-               } else {
-                       priv->rxon_timing.beacon_interval =
-                               cpu_to_le16(beacon_int);
-                       priv->rxon_timing.beacon_interval =
-                           iwl4965_adjust_beacon_interval(
-                               le16_to_cpu(priv->rxon_timing.beacon_interval));
-               }
-
+               beacon_int = iwl_adjust_beacon_interval(priv->beacon_int);
                priv->rxon_timing.atim_window = 0;
        } else {
-               priv->rxon_timing.beacon_interval =
-                       iwl4965_adjust_beacon_interval(conf->beacon_int);
+               beacon_int = iwl_adjust_beacon_interval(conf->beacon_int);
+
                /* TODO: we need to get atim_window from upper stack
                 * for now we set to 0 */
                priv->rxon_timing.atim_window = 0;
        }
 
-       interval_tm_unit =
-               (le16_to_cpu(priv->rxon_timing.beacon_interval) * 1024);
-       result = do_div(tsf, interval_tm_unit);
-       priv->rxon_timing.beacon_init_val =
-           cpu_to_le32((u32) ((u64) interval_tm_unit - result));
+       priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int);
+
+       tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
+       interval_tm = beacon_int * 1024;
+       rem = do_div(tsf, interval_tm);
+       priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
 
-       IWL_DEBUG_ASSOC
-           ("beacon interval %d beacon timer %d beacon tim %d\n",
-               le16_to_cpu(priv->rxon_timing.beacon_interval),
-               le32_to_cpu(priv->rxon_timing.beacon_init_val),
-               le16_to_cpu(priv->rxon_timing.atim_window));
+       spin_unlock_irqrestore(&priv->lock, flags);
+       IWL_DEBUG_ASSOC("beacon interval %d beacon timer %d beacon tim %d\n",
+                       le16_to_cpu(priv->rxon_timing.beacon_interval),
+                       le32_to_cpu(priv->rxon_timing.beacon_init_val),
+                       le16_to_cpu(priv->rxon_timing.atim_window));
 }
 
 static void iwl_set_flags_for_band(struct iwl_priv *priv,
@@ -715,7 +708,7 @@ static void iwl_set_flags_for_band(struct iwl_priv *priv,
                      | RXON_FLG_CCK_MSK);
                priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
        } else {
-               /* Copied from iwl4965_post_associate() */
+               /* Copied from iwl_post_associate() */
                if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
                        priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
                else
@@ -733,13 +726,13 @@ static void iwl_set_flags_for_band(struct iwl_priv *priv,
 /*
  * initialize rxon structure with default values from eeprom
  */
-static void iwl4965_connection_init_rx_config(struct iwl_priv *priv)
+static void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
 {
        const struct iwl_channel_info *ch_info;
 
        memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
 
-       switch (priv->iw_mode) {
+       switch (mode) {
        case NL80211_IFTYPE_AP:
                priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
                break;
@@ -762,7 +755,7 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv)
                    RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
                break;
        default:
-               IWL_ERROR("Unsupported interface type %d\n", priv->iw_mode);
+               IWL_ERROR("Unsupported interface type %d\n", mode);
                break;
        }
 
@@ -808,11 +801,9 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv)
        iwl_set_rxon_chain(priv);
 }
 
-static int iwl4965_set_mode(struct iwl_priv *priv, int mode)
+static int iwl_set_mode(struct iwl_priv *priv, int mode)
 {
-       priv->iw_mode = mode;
-
-       iwl4965_connection_init_rx_config(priv);
+       iwl_connection_init_rx_config(priv, mode);
        memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
 
        iwl_clear_stations_table(priv);
@@ -828,12 +819,12 @@ static int iwl4965_set_mode(struct iwl_priv *priv, int mode)
                return -EAGAIN;
        }
 
-       iwl4965_commit_rxon(priv);
+       iwl_commit_rxon(priv);
 
        return 0;
 }
 
-static void iwl4965_set_rate(struct iwl_priv *priv)
+static void iwl_set_rate(struct iwl_priv *priv)
 {
        const struct ieee80211_supported_band *hw = NULL;
        struct ieee80211_rate *rate;
@@ -895,7 +886,7 @@ static void iwl4965_set_rate(struct iwl_priv *priv)
  * the lower 3 bytes is the time in usec within one beacon interval
  */
 
-static u32 iwl4965_usecs_to_beacons(u32 usec, u32 beacon_interval)
+static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
 {
        u32 quot;
        u32 rem;
@@ -914,7 +905,7 @@ static u32 iwl4965_usecs_to_beacons(u32 usec, u32 beacon_interval)
  * the same as HW timer counter counting down
  */
 
-static __le32 iwl4965_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
+static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
 {
        u32 base_low = base & BEACON_TIME_MASK_LOW;
        u32 addon_low = addon & BEACON_TIME_MASK_LOW;
@@ -933,7 +924,7 @@ static __le32 iwl4965_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
        return cpu_to_le32(res);
 }
 
-static int iwl4965_get_measurement(struct iwl_priv *priv,
+static int iwl_get_measurement(struct iwl_priv *priv,
                               struct ieee80211_measurement_params *params,
                               u8 type)
 {
@@ -951,7 +942,7 @@ static int iwl4965_get_measurement(struct iwl_priv *priv,
 
        if (iwl_is_associated(priv))
                add_time =
-                   iwl4965_usecs_to_beacons(
+                   iwl_usecs_to_beacons(
                        le64_to_cpu(params->start_time) - priv->last_tsf,
                        le16_to_cpu(priv->rxon_timing.beacon_interval));
 
@@ -966,7 +957,7 @@ static int iwl4965_get_measurement(struct iwl_priv *priv,
 
        if (iwl_is_associated(priv))
                spectrum.start_time =
-                   iwl4965_add_beacon_time(priv->last_beacon_time,
+                   iwl_add_beacon_time(priv->last_beacon_time,
                                add_time,
                                le16_to_cpu(priv->rxon_timing.beacon_interval));
        else
@@ -1054,7 +1045,7 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv,
                IWL_WARNING("uCode did not respond OK.\n");
 }
 
-static void iwl4965_rx_reply_error(struct iwl_priv *priv,
+static void iwl_rx_reply_error(struct iwl_priv *priv,
                                   struct iwl_rx_mem_buffer *rxb)
 {
        struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
@@ -1070,7 +1061,7 @@ static void iwl4965_rx_reply_error(struct iwl_priv *priv,
 
 #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
 
-static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
+static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 {
        struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
        struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
@@ -1081,7 +1072,7 @@ static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
        priv->staging_rxon.channel = csa->channel;
 }
 
-static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv,
+static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
                                          struct iwl_rx_mem_buffer *rxb)
 {
 #ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
@@ -1099,7 +1090,7 @@ static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv,
 #endif
 }
 
-static void iwl4965_rx_pm_sleep_notif(struct iwl_priv *priv,
+static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
                                      struct iwl_rx_mem_buffer *rxb)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -1110,7 +1101,7 @@ static void iwl4965_rx_pm_sleep_notif(struct iwl_priv *priv,
 #endif
 }
 
-static void iwl4965_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
+static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
                                             struct iwl_rx_mem_buffer *rxb)
 {
        struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
@@ -1120,7 +1111,7 @@ static void iwl4965_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
        iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
 }
 
-static void iwl4965_bg_beacon_update(struct work_struct *work)
+static void iwl_bg_beacon_update(struct work_struct *work)
 {
        struct iwl_priv *priv =
                container_of(work, struct iwl_priv, beacon_update);
@@ -1142,11 +1133,11 @@ static void iwl4965_bg_beacon_update(struct work_struct *work)
        priv->ibss_beacon = beacon;
        mutex_unlock(&priv->mutex);
 
-       iwl4965_send_beacon_cmd(priv);
+       iwl_send_beacon_cmd(priv);
 }
 
 /**
- * iwl4965_bg_statistics_periodic - Timer callback to queue statistics
+ * iwl_bg_statistics_periodic - Timer callback to queue statistics
  *
  * This callback is provided in order to send a statistics request.
  *
@@ -1155,17 +1146,21 @@ static void iwl4965_bg_beacon_update(struct work_struct *work)
  * was received.  We need to ensure we receive the statistics in order
  * to update the temperature used for calibrating the TXPOWER.
  */
-static void iwl4965_bg_statistics_periodic(unsigned long data)
+static void iwl_bg_statistics_periodic(unsigned long data)
 {
        struct iwl_priv *priv = (struct iwl_priv *)data;
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
+       /* dont send host command if rf-kill is on */
+       if (!iwl_is_ready_rf(priv))
+               return;
+
        iwl_send_statistics_request(priv, CMD_ASYNC);
 }
 
-static void iwl4965_rx_beacon_notif(struct iwl_priv *priv,
+static void iwl_rx_beacon_notif(struct iwl_priv *priv,
                                struct iwl_rx_mem_buffer *rxb)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -1189,7 +1184,7 @@ static void iwl4965_rx_beacon_notif(struct iwl_priv *priv,
 
 /* Handle notification from uCode that card's power state is changing
  * due to software, hardware, or critical temperature RFKILL */
-static void iwl4965_rx_card_state_notif(struct iwl_priv *priv,
+static void iwl_rx_card_state_notif(struct iwl_priv *priv,
                                    struct iwl_rx_mem_buffer *rxb)
 {
        struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
@@ -1258,7 +1253,7 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv,
                wake_up_interruptible(&priv->wait_command_queue);
 }
 
-int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
+int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
 {
        int ret;
        unsigned long flags;
@@ -1290,7 +1285,7 @@ err:
 }
 
 /**
- * iwl4965_setup_rx_handlers - Initialize Rx handler callbacks
+ * iwl_setup_rx_handlers - Initialize Rx handler callbacks
  *
  * Setup the RX handlers for each of the reply types sent from the uCode
  * to the host.
@@ -1301,14 +1296,14 @@ err:
 static void iwl_setup_rx_handlers(struct iwl_priv *priv)
 {
        priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
-       priv->rx_handlers[REPLY_ERROR] = iwl4965_rx_reply_error;
-       priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl4965_rx_csa;
+       priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
+       priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
        priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
-           iwl4965_rx_spectrum_measure_notif;
-       priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl4965_rx_pm_sleep_notif;
+           iwl_rx_spectrum_measure_notif;
+       priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
        priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
-           iwl4965_rx_pm_debug_statistics_notif;
-       priv->rx_handlers[BEACON_NOTIFICATION] = iwl4965_rx_beacon_notif;
+           iwl_rx_pm_debug_statistics_notif;
+       priv->rx_handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif;
 
        /*
         * The same handler is used for both the REPLY to a discrete
@@ -1321,7 +1316,7 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
        iwl_setup_rx_scan_handlers(priv);
 
        /* status change handler */
-       priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl4965_rx_card_state_notif;
+       priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif;
 
        priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] =
            iwl_rx_missed_beacon_notif;
@@ -1398,13 +1393,14 @@ void iwl_rx_handle(struct iwl_priv *priv)
                reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
                        (pkt->hdr.cmd != REPLY_RX_PHY_CMD) &&
                        (pkt->hdr.cmd != REPLY_RX) &&
+                       (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) &&
                        (pkt->hdr.cmd != REPLY_COMPRESSED_BA) &&
                        (pkt->hdr.cmd != STATISTICS_NOTIFICATION) &&
                        (pkt->hdr.cmd != REPLY_TX);
 
                /* Based on type of command response or notification,
                 *   handle those that need handling via function in
-                *   rx_handlers table.  See iwl4965_setup_rx_handlers() */
+                *   rx_handlers table.  See iwl_setup_rx_handlers() */
                if (priv->rx_handlers[pkt->hdr.cmd]) {
                        IWL_DEBUG(IWL_DL_RX, "r = %d, i = %d, %s, 0x%02x\n", r,
                                i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
@@ -1461,10 +1457,9 @@ void iwl_rx_handle(struct iwl_priv *priv)
 }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-static void iwl4965_print_rx_config_cmd(struct iwl_priv *priv)
+static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
 {
        struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
-       DECLARE_MAC_BUF(mac);
 
        IWL_DEBUG_RADIO("RX CONFIG:\n");
        iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
@@ -1476,15 +1471,13 @@ static void iwl4965_print_rx_config_cmd(struct iwl_priv *priv)
        IWL_DEBUG_RADIO("u8 ofdm_basic_rates: 0x%02x\n",
                        rxon->ofdm_basic_rates);
        IWL_DEBUG_RADIO("u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
-       IWL_DEBUG_RADIO("u8[6] node_addr: %s\n",
-                       print_mac(mac, rxon->node_addr));
-       IWL_DEBUG_RADIO("u8[6] bssid_addr: %s\n",
-                       print_mac(mac, rxon->bssid_addr));
+       IWL_DEBUG_RADIO("u8[6] node_addr: %pM\n", rxon->node_addr);
+       IWL_DEBUG_RADIO("u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
        IWL_DEBUG_RADIO("u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
 }
 #endif
 
-static void iwl4965_enable_interrupts(struct iwl_priv *priv)
+static void iwl_enable_interrupts(struct iwl_priv *priv)
 {
        IWL_DEBUG_ISR("Enabling interrupts\n");
        set_bit(STATUS_INT_ENABLED, &priv->status);
@@ -1494,12 +1487,12 @@ static void iwl4965_enable_interrupts(struct iwl_priv *priv)
 /* call this function to flush any scheduled tasklet */
 static inline void iwl_synchronize_irq(struct iwl_priv *priv)
 {
-       /* wait to make sure we flush pedding tasklet*/
+       /* wait to make sure we flush pending tasklet*/
        synchronize_irq(priv->pci_dev->irq);
        tasklet_kill(&priv->irq_tasklet);
 }
 
-static inline void iwl4965_disable_interrupts(struct iwl_priv *priv)
+static inline void iwl_disable_interrupts(struct iwl_priv *priv)
 {
        clear_bit(STATUS_INT_ENABLED, &priv->status);
 
@@ -1515,11 +1508,11 @@ static inline void iwl4965_disable_interrupts(struct iwl_priv *priv)
 
 
 /**
- * iwl4965_irq_handle_error - called for HW or SW error interrupt from card
+ * iwl_irq_handle_error - called for HW or SW error interrupt from card
  */
-static void iwl4965_irq_handle_error(struct iwl_priv *priv)
+static void iwl_irq_handle_error(struct iwl_priv *priv)
 {
-       /* Set the FW error flag -- cleared on iwl4965_down */
+       /* Set the FW error flag -- cleared on iwl_down */
        set_bit(STATUS_FW_ERROR, &priv->status);
 
        /* Cancel currently queued command. */
@@ -1529,7 +1522,7 @@ static void iwl4965_irq_handle_error(struct iwl_priv *priv)
        if (priv->debug_level & IWL_DL_FW_ERRORS) {
                iwl_dump_nic_error_log(priv);
                iwl_dump_nic_event_log(priv);
-               iwl4965_print_rx_config_cmd(priv);
+               iwl_print_rx_config_cmd(priv);
        }
 #endif
 
@@ -1553,14 +1546,14 @@ static void iwl4965_irq_handle_error(struct iwl_priv *priv)
        }
 }
 
-static void iwl4965_error_recovery(struct iwl_priv *priv)
+static void iwl_error_recovery(struct iwl_priv *priv)
 {
        unsigned long flags;
 
        memcpy(&priv->staging_rxon, &priv->recovery_rxon,
               sizeof(priv->staging_rxon));
        priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       iwl4965_commit_rxon(priv);
+       iwl_commit_rxon(priv);
 
        iwl_rxon_add_station(priv, priv->bssid, 1);
 
@@ -1570,7 +1563,7 @@ static void iwl4965_error_recovery(struct iwl_priv *priv)
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static void iwl4965_irq_tasklet(struct iwl_priv *priv)
+static void iwl_irq_tasklet(struct iwl_priv *priv)
 {
        u32 inta, handled = 0;
        u32 inta_fh;
@@ -1616,9 +1609,9 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
                IWL_ERROR("Microcode HW error detected.  Restarting.\n");
 
                /* Tell the device to stop sending interrupts */
-               iwl4965_disable_interrupts(priv);
+               iwl_disable_interrupts(priv);
 
-               iwl4965_irq_handle_error(priv);
+               iwl_irq_handle_error(priv);
 
                handled |= CSR_INT_BIT_HW_ERR;
 
@@ -1672,7 +1665,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
        if (inta & CSR_INT_BIT_SW_ERR) {
                IWL_ERROR("Microcode SW error detected.  Restarting 0x%X.\n",
                          inta);
-               iwl4965_irq_handle_error(priv);
+               iwl_irq_handle_error(priv);
                handled |= CSR_INT_BIT_SW_ERR;
        }
 
@@ -1718,7 +1711,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
        /* Re-enable all interrupts */
        /* only Re-enable if diabled by irq */
        if (test_bit(STATUS_INT_ENABLED, &priv->status))
-               iwl4965_enable_interrupts(priv);
+               iwl_enable_interrupts(priv);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
        if (priv->debug_level & (IWL_DL_ISR)) {
@@ -1732,7 +1725,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static irqreturn_t iwl4965_isr(int irq, void *data)
+static irqreturn_t iwl_isr(int irq, void *data)
 {
        struct iwl_priv *priv = data;
        u32 inta, inta_mask;
@@ -1773,7 +1766,7 @@ static irqreturn_t iwl4965_isr(int irq, void *data)
 
        inta &= ~CSR_INT_BIT_SCD;
 
-       /* iwl4965_irq_tasklet() will service interrupts and re-enable them */
+       /* iwl_irq_tasklet() will service interrupts and re-enable them */
        if (likely(inta || inta_fh))
                tasklet_schedule(&priv->irq_tasklet);
 
@@ -1785,7 +1778,7 @@ static irqreturn_t iwl4965_isr(int irq, void *data)
        /* re-enable interrupts here since we don't have anything to service. */
        /* only Re-enable if diabled by irq */
        if (test_bit(STATUS_INT_ENABLED, &priv->status))
-               iwl4965_enable_interrupts(priv);
+               iwl_enable_interrupts(priv);
        spin_unlock(&priv->lock);
        return IRQ_NONE;
 }
@@ -1796,7 +1789,7 @@ static irqreturn_t iwl4965_isr(int irq, void *data)
  *
  ******************************************************************************/
 
-static void iwl4965_dealloc_ucode_pci(struct iwl_priv *priv)
+static void iwl_dealloc_ucode_pci(struct iwl_priv *priv)
 {
        iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code);
        iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data);
@@ -1806,7 +1799,7 @@ static void iwl4965_dealloc_ucode_pci(struct iwl_priv *priv)
        iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot);
 }
 
-static void iwl4965_nic_start(struct iwl_priv *priv)
+static void iwl_nic_start(struct iwl_priv *priv)
 {
        /* Remove all resets to allow NIC to operate */
        iwl_write32(priv, CSR_RESET, 0);
@@ -1814,11 +1807,11 @@ static void iwl4965_nic_start(struct iwl_priv *priv)
 
 
 /**
- * iwl4965_read_ucode - Read uCode images from disk file.
+ * iwl_read_ucode - Read uCode images from disk file.
  *
  * Copy into buffers for card to fetch via bus-mastering
  */
-static int iwl4965_read_ucode(struct iwl_priv *priv)
+static int iwl_read_ucode(struct iwl_priv *priv)
 {
        struct iwl_ucode *ucode;
        int ret;
@@ -1962,7 +1955,7 @@ static int iwl4965_read_ucode(struct iwl_priv *priv)
                priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
 
        /* Runtime data (2nd block)
-        * NOTE:  Copy into backup buffer will be done in iwl4965_up()  */
+        * NOTE:  Copy into backup buffer will be done in iwl_up()  */
        src = &ucode->data[inst_size];
        len = priv->ucode_data.len;
        IWL_DEBUG_INFO("Copying (but not loading) uCode data len %Zd\n", len);
@@ -2000,7 +1993,7 @@ static int iwl4965_read_ucode(struct iwl_priv *priv)
  err_pci_alloc:
        IWL_ERROR("failed to allocate pci memory\n");
        ret = -ENOMEM;
-       iwl4965_dealloc_ucode_pci(priv);
+       iwl_dealloc_ucode_pci(priv);
 
  err_release:
        release_firmware(ucode_raw);
@@ -2045,7 +2038,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
                goto restart;
        }
 
-       /* After the ALIVE response, we can send host commands to 4965 uCode */
+       /* After the ALIVE response, we can send host commands to the uCode */
        set_bit(STATUS_ALIVE, &priv->status);
 
        if (iwl_is_rfkill(priv))
@@ -2065,17 +2058,17 @@ static void iwl_alive_start(struct iwl_priv *priv)
                active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
        } else {
                /* Initialize our rx_config data */
-               iwl4965_connection_init_rx_config(priv);
+               iwl_connection_init_rx_config(priv, priv->iw_mode);
                memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
        }
 
        /* Configure Bluetooth device coexistence support */
-       iwl4965_send_bt_config(priv);
+       iwl_send_bt_config(priv);
 
        iwl_reset_run_time_calib(priv);
 
        /* Configure the adapter for unassociated operation */
-       iwl4965_commit_rxon(priv);
+       iwl_commit_rxon(priv);
 
        /* At this point, the NIC is initialized and operational */
        iwl_rf_kill_ct_config(priv);
@@ -2087,12 +2080,12 @@ static void iwl_alive_start(struct iwl_priv *priv)
        wake_up_interruptible(&priv->wait_command_queue);
 
        if (priv->error_recovering)
-               iwl4965_error_recovery(priv);
+               iwl_error_recovery(priv);
 
        iwl_power_update_mode(priv, 1);
 
        if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
-               iwl4965_set_mode(priv, priv->iw_mode);
+               iwl_set_mode(priv, priv->iw_mode);
 
        return;
 
@@ -2102,7 +2095,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
 
 static void iwl_cancel_deferred_work(struct iwl_priv *priv);
 
-static void __iwl4965_down(struct iwl_priv *priv)
+static void __iwl_down(struct iwl_priv *priv)
 {
        unsigned long flags;
        int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
@@ -2129,14 +2122,14 @@ static void __iwl4965_down(struct iwl_priv *priv)
 
        /* tell the device to stop sending interrupts */
        spin_lock_irqsave(&priv->lock, flags);
-       iwl4965_disable_interrupts(priv);
+       iwl_disable_interrupts(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
        iwl_synchronize_irq(priv);
 
        if (priv->mac80211_registered)
                ieee80211_stop_queues(priv->hw);
 
-       /* If we have not previously called iwl4965_init() then
+       /* If we have not previously called iwl_init() then
         * clear all bits but the RF Kill and SUSPEND bits and return */
        if (!iwl_is_init(priv)) {
                priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
@@ -2203,10 +2196,10 @@ static void __iwl4965_down(struct iwl_priv *priv)
        iwl_clear_free_frames(priv);
 }
 
-static void iwl4965_down(struct iwl_priv *priv)
+static void iwl_down(struct iwl_priv *priv)
 {
        mutex_lock(&priv->mutex);
-       __iwl4965_down(priv);
+       __iwl_down(priv);
        mutex_unlock(&priv->mutex);
 
        iwl_cancel_deferred_work(priv);
@@ -2214,7 +2207,7 @@ static void iwl4965_down(struct iwl_priv *priv)
 
 #define MAX_HW_RESTARTS 5
 
-static int __iwl4965_up(struct iwl_priv *priv)
+static int __iwl_up(struct iwl_priv *priv)
 {
        int i;
        int ret;
@@ -2236,7 +2229,7 @@ static int __iwl4965_up(struct iwl_priv *priv)
                set_bit(STATUS_RF_KILL_HW, &priv->status);
 
        if (iwl_is_rfkill(priv)) {
-               iwl4965_enable_interrupts(priv);
+               iwl_enable_interrupts(priv);
                IWL_WARNING("Radio disabled by %s RF Kill switch\n",
                    test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
                return 0;
@@ -2263,7 +2256,7 @@ static int __iwl4965_up(struct iwl_priv *priv)
 
        /* clear (again), then enable host interrupts */
        iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
-       iwl4965_enable_interrupts(priv);
+       iwl_enable_interrupts(priv);
 
        /* really make sure rfkill handshake bits are cleared */
        iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
@@ -2293,7 +2286,7 @@ static int __iwl4965_up(struct iwl_priv *priv)
                clear_bit(STATUS_FW_ERROR, &priv->status);
 
                /* start card; "initialize" will load runtime ucode */
-               iwl4965_nic_start(priv);
+               iwl_nic_start(priv);
 
                IWL_DEBUG_INFO(DRV_NAME " is coming up\n");
 
@@ -2301,7 +2294,7 @@ static int __iwl4965_up(struct iwl_priv *priv)
        }
 
        set_bit(STATUS_EXIT_PENDING, &priv->status);
-       __iwl4965_down(priv);
+       __iwl_down(priv);
        clear_bit(STATUS_EXIT_PENDING, &priv->status);
 
        /* tried to restart and config the device for as long as our
@@ -2344,7 +2337,7 @@ static void iwl_bg_alive_start(struct work_struct *data)
        ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
 }
 
-static void iwl4965_bg_rf_kill(struct work_struct *work)
+static void iwl_bg_rf_kill(struct work_struct *work)
 {
        struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill);
 
@@ -2378,7 +2371,7 @@ static void iwl4965_bg_rf_kill(struct work_struct *work)
        iwl_rfkill_set_hw_state(priv);
 }
 
-static void iwl4965_bg_set_monitor(struct work_struct *work)
+static void iwl_bg_set_monitor(struct work_struct *work)
 {
        struct iwl_priv *priv = container_of(work,
                                struct iwl_priv, set_monitor);
@@ -2388,16 +2381,16 @@ static void iwl4965_bg_set_monitor(struct work_struct *work)
 
        mutex_lock(&priv->mutex);
 
-       ret = iwl4965_set_mode(priv, NL80211_IFTYPE_MONITOR);
-
+       ret = iwl_set_mode(priv, NL80211_IFTYPE_MONITOR);
        if (ret) {
                if (ret == -EAGAIN)
                        IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n");
                else
-                       IWL_ERROR("iwl4965_set_mode() failed ret = %d\n", ret);
+                       IWL_ERROR("iwl_set_mode() failed ret = %d\n", ret);
        }
 
        mutex_unlock(&priv->mutex);
+       ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
 }
 
 static void iwl_bg_run_time_calib_work(struct work_struct *work)
@@ -2423,7 +2416,7 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
        return;
 }
 
-static void iwl4965_bg_up(struct work_struct *data)
+static void iwl_bg_up(struct work_struct *data)
 {
        struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
 
@@ -2431,23 +2424,23 @@ static void iwl4965_bg_up(struct work_struct *data)
                return;
 
        mutex_lock(&priv->mutex);
-       __iwl4965_up(priv);
+       __iwl_up(priv);
        mutex_unlock(&priv->mutex);
        iwl_rfkill_set_hw_state(priv);
 }
 
-static void iwl4965_bg_restart(struct work_struct *data)
+static void iwl_bg_restart(struct work_struct *data)
 {
        struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       iwl4965_down(priv);
+       iwl_down(priv);
        queue_work(priv->workqueue, &priv->up);
 }
 
-static void iwl4965_bg_rx_replenish(struct work_struct *data)
+static void iwl_bg_rx_replenish(struct work_struct *data)
 {
        struct iwl_priv *priv =
            container_of(data, struct iwl_priv, rx_replenish);
@@ -2462,11 +2455,10 @@ static void iwl4965_bg_rx_replenish(struct work_struct *data)
 
 #define IWL_DELAY_NEXT_SCAN (HZ*2)
 
-static void iwl4965_post_associate(struct iwl_priv *priv)
+static void iwl_post_associate(struct iwl_priv *priv)
 {
        struct ieee80211_conf *conf = NULL;
        int ret = 0;
-       DECLARE_MAC_BUF(mac);
        unsigned long flags;
 
        if (priv->iw_mode == NL80211_IFTYPE_AP) {
@@ -2474,9 +2466,8 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
                return;
        }
 
-       IWL_DEBUG_ASSOC("Associated as %d to: %s\n",
-                       priv->assoc_id,
-                       print_mac(mac, priv->active_rxon.bssid_addr));
+       IWL_DEBUG_ASSOC("Associated as %d to: %pM\n",
+                       priv->assoc_id, priv->active_rxon.bssid_addr);
 
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -2492,10 +2483,9 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
        conf = ieee80211_get_hw_conf(priv->hw);
 
        priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       iwl4965_commit_rxon(priv);
+       iwl_commit_rxon(priv);
 
-       memset(&priv->rxon_timing, 0, sizeof(struct iwl4965_rxon_time_cmd));
-       iwl4965_setup_rxon_timing(priv);
+       iwl_setup_rxon_timing(priv);
        ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
                              sizeof(priv->rxon_timing), &priv->rxon_timing);
        if (ret)
@@ -2528,7 +2518,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
 
        }
 
-       iwl4965_commit_rxon(priv);
+       iwl_commit_rxon(priv);
 
        switch (priv->iw_mode) {
        case NL80211_IFTYPE_STATION:
@@ -2540,7 +2530,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
                priv->assoc_id = 1;
 
                iwl_rxon_add_station(priv, priv->bssid, 0);
-               iwl4965_send_beacon_cmd(priv);
+               iwl_send_beacon_cmd(priv);
 
                break;
 
@@ -2577,7 +2567,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
 
 #define UCODE_READY_TIMEOUT    (4 * HZ)
 
-static int iwl4965_mac_start(struct ieee80211_hw *hw)
+static int iwl_mac_start(struct ieee80211_hw *hw)
 {
        struct iwl_priv *priv = hw->priv;
        int ret;
@@ -2599,7 +2589,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
                pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
        }
 
-       ret = request_irq(priv->pci_dev->irq, iwl4965_isr, IRQF_SHARED,
+       ret = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
                          DRV_NAME, priv);
        if (ret) {
                IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq);
@@ -2614,7 +2604,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
         * ucode filename and max sizes are card-specific. */
 
        if (!priv->ucode_code.len) {
-               ret = iwl4965_read_ucode(priv);
+               ret = iwl_read_ucode(priv);
                if (ret) {
                        IWL_ERROR("Could not read microcode: %d\n", ret);
                        mutex_unlock(&priv->mutex);
@@ -2622,7 +2612,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
                }
        }
 
-       ret = __iwl4965_up(priv);
+       ret = __iwl_up(priv);
 
        mutex_unlock(&priv->mutex);
 
@@ -2668,7 +2658,7 @@ out_disable_msi:
        return ret;
 }
 
-static void iwl4965_mac_stop(struct ieee80211_hw *hw)
+static void iwl_mac_stop(struct ieee80211_hw *hw)
 {
        struct iwl_priv *priv = hw->priv;
 
@@ -2690,7 +2680,7 @@ static void iwl4965_mac_stop(struct ieee80211_hw *hw)
                mutex_unlock(&priv->mutex);
        }
 
-       iwl4965_down(priv);
+       iwl_down(priv);
 
        flush_workqueue(priv->workqueue);
        free_irq(priv->pci_dev->irq, priv);
@@ -2701,7 +2691,7 @@ static void iwl4965_mac_stop(struct ieee80211_hw *hw)
        IWL_DEBUG_MAC80211("leave\n");
 }
 
-static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct iwl_priv *priv = hw->priv;
 
@@ -2717,12 +2707,11 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        return 0;
 }
 
-static int iwl4965_mac_add_interface(struct ieee80211_hw *hw,
+static int iwl_mac_add_interface(struct ieee80211_hw *hw,
                                 struct ieee80211_if_init_conf *conf)
 {
        struct iwl_priv *priv = hw->priv;
        unsigned long flags;
-       DECLARE_MAC_BUF(mac);
 
        IWL_DEBUG_MAC80211("enter: type %d\n", conf->type);
 
@@ -2733,17 +2722,18 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw,
 
        spin_lock_irqsave(&priv->lock, flags);
        priv->vif = conf->vif;
+       priv->iw_mode = conf->type;
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
        mutex_lock(&priv->mutex);
 
        if (conf->mac_addr) {
-               IWL_DEBUG_MAC80211("Set %s\n", print_mac(mac, conf->mac_addr));
+               IWL_DEBUG_MAC80211("Set %pM\n", conf->mac_addr);
                memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
        }
 
-       if (iwl4965_set_mode(priv, conf->type) == -EAGAIN)
+       if (iwl_set_mode(priv, conf->type) == -EAGAIN)
                /* we are not ready, will run again when ready */
                set_bit(STATUS_MODE_PENDING, &priv->status);
 
@@ -2754,16 +2744,17 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw,
 }
 
 /**
- * iwl4965_mac_config - mac80211 config callback
+ * iwl_mac_config - mac80211 config callback
  *
  * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to
  * be set inappropriately and the driver currently sets the hardware up to
  * use it whenever needed.
  */
-static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct iwl_priv *priv = hw->priv;
        const struct iwl_channel_info *ch_info;
+       struct ieee80211_conf *conf = &hw->conf;
        unsigned long flags;
        int ret = 0;
        u16 channel;
@@ -2771,6 +2762,8 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
        mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value);
 
+       priv->current_ht_config.is_ht = conf->ht.enabled;
+
        if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) {
                IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n");
                goto out;
@@ -2828,13 +2821,13 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
        /* The list of supported rates and rate mask can be different
         * for each band; since the band may have changed, reset
         * the rate mask to what mac80211 lists */
-       iwl4965_set_rate(priv);
+       iwl_set_rate(priv);
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
 #ifdef IEEE80211_CONF_CHANNEL_SWITCH
        if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) {
-               iwl4965_hw_channel_switch(priv, conf->channel);
+               iwl_hw_channel_switch(priv, conf->channel);
                goto out;
        }
 #endif
@@ -2862,11 +2855,11 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
 
        iwl_set_tx_power(priv, conf->power_level, false);
 
-       iwl4965_set_rate(priv);
+       iwl_set_rate(priv);
 
        if (memcmp(&priv->active_rxon,
                   &priv->staging_rxon, sizeof(priv->staging_rxon)))
-               iwl4965_commit_rxon(priv);
+               iwl_commit_rxon(priv);
        else
                IWL_DEBUG_INFO("No re-sending same RXON configuration.\n");
 
@@ -2877,7 +2870,7 @@ out:
        return ret;
 }
 
-static void iwl4965_config_ap(struct iwl_priv *priv)
+static void iwl_config_ap(struct iwl_priv *priv)
 {
        int ret = 0;
        unsigned long flags;
@@ -2886,15 +2879,14 @@ static void iwl4965_config_ap(struct iwl_priv *priv)
                return;
 
        /* The following should be done only at AP bring up */
-       if (!(iwl_is_associated(priv))) {
+       if (!iwl_is_associated(priv)) {
 
                /* RXON - unassoc (to set timing command) */
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl4965_commit_rxon(priv);
+               iwl_commit_rxon(priv);
 
                /* RXON Timing */
-               memset(&priv->rxon_timing, 0, sizeof(struct iwl4965_rxon_time_cmd));
-               iwl4965_setup_rxon_timing(priv);
+               iwl_setup_rxon_timing(priv);
                ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
                                sizeof(priv->rxon_timing), &priv->rxon_timing);
                if (ret)
@@ -2927,13 +2919,13 @@ static void iwl4965_config_ap(struct iwl_priv *priv)
                }
                /* restore RXON assoc */
                priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
-               iwl4965_commit_rxon(priv);
+               iwl_commit_rxon(priv);
                spin_lock_irqsave(&priv->lock, flags);
                iwl_activate_qos(priv, 1);
                spin_unlock_irqrestore(&priv->lock, flags);
                iwl_rxon_add_station(priv, iwl_bcast_addr, 0);
        }
-       iwl4965_send_beacon_cmd(priv);
+       iwl_send_beacon_cmd(priv);
 
        /* FIXME - we need to add code here to detect a totally new
         * configuration, reset the AP, unassoc, rxon timing, assoc,
@@ -2941,15 +2933,13 @@ static void iwl4965_config_ap(struct iwl_priv *priv)
 }
 
 /* temporary */
-static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
+static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
 
-static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
+static int iwl_mac_config_interface(struct ieee80211_hw *hw,
                                        struct ieee80211_vif *vif,
                                    struct ieee80211_if_conf *conf)
 {
        struct iwl_priv *priv = hw->priv;
-       DECLARE_MAC_BUF(mac);
-       unsigned long flags;
        int rc;
 
        if (conf == NULL)
@@ -2965,26 +2955,18 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
                struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
                if (!beacon)
                        return -ENOMEM;
-               rc = iwl4965_mac_beacon_update(hw, beacon);
+               rc = iwl_mac_beacon_update(hw, beacon);
                if (rc)
                        return rc;
        }
 
-       if ((priv->iw_mode == NL80211_IFTYPE_AP) &&
-           (!conf->ssid_len)) {
-               IWL_DEBUG_MAC80211
-                   ("Leaving in AP mode because HostAPD is not ready.\n");
-               return 0;
-       }
-
        if (!iwl_is_alive(priv))
                return -EAGAIN;
 
        mutex_lock(&priv->mutex);
 
        if (conf->bssid)
-               IWL_DEBUG_MAC80211("bssid: %s\n",
-                                  print_mac(mac, conf->bssid));
+               IWL_DEBUG_MAC80211("bssid: %pM\n", conf->bssid);
 
 /*
  * very dubious code was here; the probe filtering flag is never set:
@@ -2997,8 +2979,8 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
                if (!conf->bssid) {
                        conf->bssid = priv->mac_addr;
                        memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
-                       IWL_DEBUG_MAC80211("bssid was set to: %s\n",
-                                          print_mac(mac, conf->bssid));
+                       IWL_DEBUG_MAC80211("bssid was set to: %pM\n",
+                                          conf->bssid);
                }
                if (priv->ibss_beacon)
                        dev_kfree_skb(priv->ibss_beacon);
@@ -3029,9 +3011,9 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
                memcpy(priv->bssid, conf->bssid, ETH_ALEN);
 
                if (priv->iw_mode == NL80211_IFTYPE_AP)
-                       iwl4965_config_ap(priv);
+                       iwl_config_ap(priv);
                else {
-                       rc = iwl4965_commit_rxon(priv);
+                       rc = iwl_commit_rxon(priv);
                        if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
                                iwl_rxon_add_station(
                                        priv, priv->active_rxon.bssid_addr, 1);
@@ -3040,26 +3022,17 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
        } else {
                iwl_scan_cancel_timeout(priv, 100);
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl4965_commit_rxon(priv);
+               iwl_commit_rxon(priv);
        }
 
  done:
-       spin_lock_irqsave(&priv->lock, flags);
-       if (!conf->ssid_len)
-               memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
-       else
-               memcpy(priv->essid, conf->ssid, conf->ssid_len);
-
-       priv->essid_len = conf->ssid_len;
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        IWL_DEBUG_MAC80211("leave\n");
        mutex_unlock(&priv->mutex);
 
        return 0;
 }
 
-static void iwl4965_configure_filter(struct ieee80211_hw *hw,
+static void iwl_configure_filter(struct ieee80211_hw *hw,
                                 unsigned int changed_flags,
                                 unsigned int *total_flags,
                                 int mc_count, struct dev_addr_list *mc_list)
@@ -3078,7 +3051,7 @@ static void iwl4965_configure_filter(struct ieee80211_hw *hw,
                        FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
 }
 
-static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw,
+static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
                                     struct ieee80211_if_init_conf *conf)
 {
        struct iwl_priv *priv = hw->priv;
@@ -3090,13 +3063,11 @@ static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw,
        if (iwl_is_ready_rf(priv)) {
                iwl_scan_cancel_timeout(priv, 100);
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl4965_commit_rxon(priv);
+               iwl_commit_rxon(priv);
        }
        if (priv->vif == conf->vif) {
                priv->vif = NULL;
                memset(priv->bssid, 0, ETH_ALEN);
-               memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
-               priv->essid_len = 0;
        }
        mutex_unlock(&priv->mutex);
 
@@ -3105,7 +3076,7 @@ static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw,
 }
 
 #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
-static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
+static void iwl_bss_info_changed(struct ieee80211_hw *hw,
                                     struct ieee80211_vif *vif,
                                     struct ieee80211_bss_conf *bss_conf,
                                     u32 changes)
@@ -3132,8 +3103,7 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
        }
 
        if (changes & BSS_CHANGED_HT) {
-               IWL_DEBUG_MAC80211("HT %d\n", bss_conf->assoc_ht);
-               iwl4965_ht_conf(priv, bss_conf);
+               iwl_ht_conf(priv, bss_conf);
                iwl_set_rxon_chain(priv);
        }
 
@@ -3156,7 +3126,7 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
                        priv->next_scan_jiffies = jiffies +
                                        IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
                        mutex_lock(&priv->mutex);
-                       iwl4965_post_associate(priv);
+                       iwl_post_associate(priv);
                        mutex_unlock(&priv->mutex);
                } else {
                        priv->assoc_id = 0;
@@ -3232,7 +3202,7 @@ out_unlock:
        return ret;
 }
 
-static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw,
+static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
                        struct ieee80211_key_conf *keyconf, const u8 *addr,
                        u32 iv32, u16 *phase1key)
 {
@@ -3241,14 +3211,13 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw,
        unsigned long flags;
        __le16 key_flags = 0;
        int i;
-       DECLARE_MAC_BUF(mac);
 
        IWL_DEBUG_MAC80211("enter\n");
 
        sta_id = iwl_find_station(priv, addr);
        if (sta_id == IWL_INVALID_STATION) {
-               IWL_DEBUG_MAC80211("leave - %s not in station map.\n",
-                                  print_mac(mac, addr));
+               IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
+                                  addr);
                return;
        }
 
@@ -3284,12 +3253,11 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw,
        IWL_DEBUG_MAC80211("leave\n");
 }
 
-static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                           const u8 *local_addr, const u8 *addr,
                           struct ieee80211_key_conf *key)
 {
        struct iwl_priv *priv = hw->priv;
-       DECLARE_MAC_BUF(mac);
        int ret = 0;
        u8 sta_id = IWL_INVALID_STATION;
        u8 is_default_wep_key = 0;
@@ -3307,8 +3275,8 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
        sta_id = iwl_find_station(priv, addr);
        if (sta_id == IWL_INVALID_STATION) {
-               IWL_DEBUG_MAC80211("leave - %s not in station map.\n",
-                                  print_mac(mac, addr));
+               IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
+                                  addr);
                return -EINVAL;
 
        }
@@ -3356,7 +3324,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        return ret;
 }
 
-static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
+static int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
                           const struct ieee80211_tx_queue_params *params)
 {
        struct iwl_priv *priv = hw->priv;
@@ -3404,15 +3372,14 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
        return 0;
 }
 
-static int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
+static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
                             enum ieee80211_ampdu_mlme_action action,
                             struct ieee80211_sta *sta, u16 tid, u16 *ssn)
 {
        struct iwl_priv *priv = hw->priv;
-       DECLARE_MAC_BUF(mac);
 
-       IWL_DEBUG_HT("A-MPDU action on addr %s tid %d\n",
-                    print_mac(mac, sta->addr), tid);
+       IWL_DEBUG_HT("A-MPDU action on addr %pM tid %d\n",
+                    sta->addr, tid);
 
        if (!(priv->cfg->sku & IWL_SKU_N))
                return -EACCES;
@@ -3437,7 +3404,7 @@ static int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
        }
        return 0;
 }
-static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw,
+static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
                                struct ieee80211_tx_queue_stats *stats)
 {
        struct iwl_priv *priv = hw->priv;
@@ -3472,7 +3439,7 @@ static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw,
        return 0;
 }
 
-static int iwl4965_mac_get_stats(struct ieee80211_hw *hw,
+static int iwl_mac_get_stats(struct ieee80211_hw *hw,
                             struct ieee80211_low_level_stats *stats)
 {
        struct iwl_priv *priv = hw->priv;
@@ -3484,7 +3451,7 @@ static int iwl4965_mac_get_stats(struct ieee80211_hw *hw,
        return 0;
 }
 
-static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
+static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
 {
        struct iwl_priv *priv = hw->priv;
        unsigned long flags;
@@ -3528,7 +3495,7 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
        if (priv->iw_mode != NL80211_IFTYPE_AP) {
                iwl_scan_cancel_timeout(priv, 100);
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl4965_commit_rxon(priv);
+               iwl_commit_rxon(priv);
        }
 
        iwl_power_update_mode(priv, 0);
@@ -3551,14 +3518,14 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
                return;
        }
 
-       iwl4965_set_rate(priv);
+       iwl_set_rate(priv);
 
        mutex_unlock(&priv->mutex);
 
        IWL_DEBUG_MAC80211("leave\n");
 }
 
-static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
+static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        struct iwl_priv *priv = hw->priv;
        unsigned long flags;
@@ -3595,7 +3562,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
 
        iwl_reset_qos(priv);
 
-       iwl4965_post_associate(priv);
+       iwl_post_associate(priv);
 
        mutex_unlock(&priv->mutex);
 
@@ -3749,7 +3716,7 @@ static ssize_t store_flags(struct device *d,
                else {
                        IWL_DEBUG_INFO("Commit rxon.flags = 0x%04X\n", flags);
                        priv->staging_rxon.flags = cpu_to_le32(flags);
-                       iwl4965_commit_rxon(priv);
+                       iwl_commit_rxon(priv);
                }
        }
        mutex_unlock(&priv->mutex);
@@ -3790,7 +3757,7 @@ static ssize_t store_filter_flags(struct device *d,
                                       "0x%04X\n", filter_flags);
                        priv->staging_rxon.filter_flags =
                                cpu_to_le32(filter_flags);
-                       iwl4965_commit_rxon(priv);
+                       iwl_commit_rxon(priv);
                }
        }
        mutex_unlock(&priv->mutex);
@@ -3865,7 +3832,7 @@ static ssize_t store_measurement(struct device *d,
 
        IWL_DEBUG_INFO("Invoking measurement of type %d on "
                       "channel %d (for '%s')\n", type, params.channel, buf);
-       iwl4965_get_measurement(priv, &params, type);
+       iwl_get_measurement(priv, &params, type);
 
        return count;
 }
@@ -4085,12 +4052,12 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
 
        init_waitqueue_head(&priv->wait_command_queue);
 
-       INIT_WORK(&priv->up, iwl4965_bg_up);
-       INIT_WORK(&priv->restart, iwl4965_bg_restart);
-       INIT_WORK(&priv->rx_replenish, iwl4965_bg_rx_replenish);
-       INIT_WORK(&priv->rf_kill, iwl4965_bg_rf_kill);
-       INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update);
-       INIT_WORK(&priv->set_monitor, iwl4965_bg_set_monitor);
+       INIT_WORK(&priv->up, iwl_bg_up);
+       INIT_WORK(&priv->restart, iwl_bg_restart);
+       INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
+       INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
+       INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
+       INIT_WORK(&priv->set_monitor, iwl_bg_set_monitor);
        INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
        INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
        INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
@@ -4103,10 +4070,10 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
 
        init_timer(&priv->statistics_periodic);
        priv->statistics_periodic.data = (unsigned long)priv;
-       priv->statistics_periodic.function = iwl4965_bg_statistics_periodic;
+       priv->statistics_periodic.function = iwl_bg_statistics_periodic;
 
        tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
-                    iwl4965_irq_tasklet, (unsigned long)priv);
+                    iwl_irq_tasklet, (unsigned long)priv);
 }
 
 static void iwl_cancel_deferred_work(struct iwl_priv *priv)
@@ -4122,7 +4089,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
        del_timer_sync(&priv->statistics_periodic);
 }
 
-static struct attribute *iwl4965_sysfs_entries[] = {
+static struct attribute *iwl_sysfs_entries[] = {
        &dev_attr_channels.attr,
        &dev_attr_flags.attr,
        &dev_attr_filter_flags.attr,
@@ -4143,39 +4110,38 @@ static struct attribute *iwl4965_sysfs_entries[] = {
        NULL
 };
 
-static struct attribute_group iwl4965_attribute_group = {
+static struct attribute_group iwl_attribute_group = {
        .name = NULL,           /* put in device directory */
-       .attrs = iwl4965_sysfs_entries,
+       .attrs = iwl_sysfs_entries,
 };
 
-static struct ieee80211_ops iwl4965_hw_ops = {
-       .tx = iwl4965_mac_tx,
-       .start = iwl4965_mac_start,
-       .stop = iwl4965_mac_stop,
-       .add_interface = iwl4965_mac_add_interface,
-       .remove_interface = iwl4965_mac_remove_interface,
-       .config = iwl4965_mac_config,
-       .config_interface = iwl4965_mac_config_interface,
-       .configure_filter = iwl4965_configure_filter,
-       .set_key = iwl4965_mac_set_key,
-       .update_tkip_key = iwl4965_mac_update_tkip_key,
-       .get_stats = iwl4965_mac_get_stats,
-       .get_tx_stats = iwl4965_mac_get_tx_stats,
-       .conf_tx = iwl4965_mac_conf_tx,
-       .reset_tsf = iwl4965_mac_reset_tsf,
-       .bss_info_changed = iwl4965_bss_info_changed,
-       .ampdu_action = iwl4965_mac_ampdu_action,
+static struct ieee80211_ops iwl_hw_ops = {
+       .tx = iwl_mac_tx,
+       .start = iwl_mac_start,
+       .stop = iwl_mac_stop,
+       .add_interface = iwl_mac_add_interface,
+       .remove_interface = iwl_mac_remove_interface,
+       .config = iwl_mac_config,
+       .config_interface = iwl_mac_config_interface,
+       .configure_filter = iwl_configure_filter,
+       .set_key = iwl_mac_set_key,
+       .update_tkip_key = iwl_mac_update_tkip_key,
+       .get_stats = iwl_mac_get_stats,
+       .get_tx_stats = iwl_mac_get_tx_stats,
+       .conf_tx = iwl_mac_conf_tx,
+       .reset_tsf = iwl_mac_reset_tsf,
+       .bss_info_changed = iwl_bss_info_changed,
+       .ampdu_action = iwl_mac_ampdu_action,
        .hw_scan = iwl_mac_hw_scan
 };
 
-static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        int err = 0;
        struct iwl_priv *priv;
        struct ieee80211_hw *hw;
        struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
        unsigned long flags;
-       DECLARE_MAC_BUF(mac);
 
        /************************
         * 1. Allocating HW data
@@ -4187,10 +4153,10 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
                if (cfg->mod_params->debug & IWL_DL_INFO)
                        dev_printk(KERN_DEBUG, &(pdev->dev),
                                   "Disabling hw_scan\n");
-               iwl4965_hw_ops.hw_scan = NULL;
+               iwl_hw_ops.hw_scan = NULL;
        }
 
-       hw = iwl_alloc_all(cfg, &iwl4965_hw_ops);
+       hw = iwl_alloc_all(cfg, &iwl_hw_ops);
        if (!hw) {
                err = -ENOMEM;
                goto out;
@@ -4284,7 +4250,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 
        /* extract MAC Address */
        iwl_eeprom_get_mac(priv, priv->mac_addr);
-       IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
+       IWL_DEBUG_INFO("MAC address: %pM\n", priv->mac_addr);
        SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
 
        /************************
@@ -4318,10 +4284,10 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
         * 8. Setup services
         ********************/
        spin_lock_irqsave(&priv->lock, flags);
-       iwl4965_disable_interrupts(priv);
+       iwl_disable_interrupts(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group);
+       err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group);
        if (err) {
                IWL_ERROR("failed to create sysfs device attributes\n");
                goto out_uninit_drv;
@@ -4357,7 +4323,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        return 0;
 
  out_remove_sysfs:
-       sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
+       sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
  out_uninit_drv:
        iwl_uninit_drv(priv);
  out_free_eeprom:
@@ -4375,7 +4341,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        return err;
 }
 
-static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
+static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 {
        struct iwl_priv *priv = pci_get_drvdata(pdev);
        unsigned long flags;
@@ -4386,10 +4352,10 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
        IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n");
 
        iwl_dbgfs_unregister(priv);
-       sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
+       sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
 
-       /* ieee80211_unregister_hw call wil cause iwl4965_mac_stop to
-        * to be called and iwl4965_down since we are removing the device
+       /* ieee80211_unregister_hw call wil cause iwl_mac_stop to
+        * to be called and iwl_down since we are removing the device
         * we need to set STATUS_EXIT_PENDING bit.
         */
        set_bit(STATUS_EXIT_PENDING, &priv->status);
@@ -4397,20 +4363,20 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
                ieee80211_unregister_hw(priv->hw);
                priv->mac80211_registered = 0;
        } else {
-               iwl4965_down(priv);
+               iwl_down(priv);
        }
 
        /* make sure we flush any pending irq or
         * tasklet for the driver
         */
        spin_lock_irqsave(&priv->lock, flags);
-       iwl4965_disable_interrupts(priv);
+       iwl_disable_interrupts(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        iwl_synchronize_irq(priv);
 
        iwl_rfkill_unregister(priv);
-       iwl4965_dealloc_ucode_pci(priv);
+       iwl_dealloc_ucode_pci(priv);
 
        if (priv->rxq.bd)
                iwl_rx_queue_free(priv, &priv->rxq);
@@ -4423,7 +4389,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
        /*netif_stop_queue(dev); */
        flush_workqueue(priv->workqueue);
 
-       /* ieee80211_unregister_hw calls iwl4965_mac_stop, which flushes
+       /* ieee80211_unregister_hw calls iwl_mac_stop, which flushes
         * priv->workqueue... so we can't take down the workqueue
         * until now... */
        destroy_workqueue(priv->workqueue);
@@ -4444,13 +4410,13 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
 
 #ifdef CONFIG_PM
 
-static int iwl4965_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct iwl_priv *priv = pci_get_drvdata(pdev);
 
        if (priv->is_open) {
                set_bit(STATUS_IN_SUSPEND, &priv->status);
-               iwl4965_mac_stop(priv->hw);
+               iwl_mac_stop(priv->hw);
                priv->is_open = 1;
        }
 
@@ -4459,14 +4425,14 @@ static int iwl4965_pci_suspend(struct pci_dev *pdev, pm_message_t state)
        return 0;
 }
 
-static int iwl4965_pci_resume(struct pci_dev *pdev)
+static int iwl_pci_resume(struct pci_dev *pdev)
 {
        struct iwl_priv *priv = pci_get_drvdata(pdev);
 
        pci_set_power_state(pdev, PCI_D0);
 
        if (priv->is_open)
-               iwl4965_mac_start(priv->hw);
+               iwl_mac_start(priv->hw);
 
        clear_bit(STATUS_IN_SUSPEND, &priv->status);
        return 0;
@@ -4509,15 +4475,15 @@ MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
 static struct pci_driver iwl_driver = {
        .name = DRV_NAME,
        .id_table = iwl_hw_card_ids,
-       .probe = iwl4965_pci_probe,
-       .remove = __devexit_p(iwl4965_pci_remove),
+       .probe = iwl_pci_probe,
+       .remove = __devexit_p(iwl_pci_remove),
 #ifdef CONFIG_PM
-       .suspend = iwl4965_pci_suspend,
-       .resume = iwl4965_pci_resume,
+       .suspend = iwl_pci_suspend,
+       .resume = iwl_pci_resume,
 #endif
 };
 
-static int __init iwl4965_init(void)
+static int __init iwl_init(void)
 {
 
        int ret;
@@ -4543,11 +4509,11 @@ error_register:
        return ret;
 }
 
-static void __exit iwl4965_exit(void)
+static void __exit iwl_exit(void)
 {
        pci_unregister_driver(&iwl_driver);
        iwlagn_rate_control_unregister();
 }
 
-module_exit(iwl4965_exit);
-module_init(iwl4965_init);
+module_exit(iwl_exit);
+module_init(iwl_init);
index 72fbf47229db7da9832c3eb05a6c2722df651b7e..25f4658f1a76b7a2a9a92c98893ac7bc66c93c27 100644 (file)
@@ -70,7 +70,7 @@
  * INIT calibrations framework
  *****************************************************************************/
 
- int iwl_send_calib_results(struct iwl_priv *priv)
+int iwl_send_calib_results(struct iwl_priv *priv)
 {
        int ret = 0;
        int i = 0;
                .meta.flags = CMD_SIZE_HUGE,
        };
 
-       for (i = 0; i < IWL_CALIB_MAX; i++)
-               if (priv->calib_results[i].buf) {
+       for (i = 0; i < IWL_CALIB_MAX; i++) {
+               if ((BIT(i) & priv->hw_params.calib_init_cfg) &&
+                   priv->calib_results[i].buf) {
                        hcmd.len = priv->calib_results[i].buf_len;
                        hcmd.data = priv->calib_results[i].buf;
                        ret = iwl_send_cmd_sync(priv, &hcmd);
                        if (ret)
                                goto err;
                }
+       }
 
        return 0;
 err:
index 8d04e966ad48fe31bc3cad9fbc0d5e010895e54b..8aade00e165a5c1c1dd8e0d8d724b15e3252f737 100644 (file)
@@ -66,8 +66,8 @@
  * Please use iwl-dev.h for driver implementation definitions.
  */
 
-#ifndef __iwl4965_commands_h__
-#define __iwl4965_commands_h__
+#ifndef __iwl_commands_h__
+#define __iwl_commands_h__
 
 enum {
        REPLY_ALIVE = 0x1,
@@ -98,6 +98,11 @@ enum {
        COEX_MEDIUM_NOTIFICATION = 0x5b,
        COEX_EVENT_CMD = 0x5c,
 
+       /* Calibration */
+       CALIBRATION_CFG_CMD = 0x65,
+       CALIBRATION_RES_NOTIFICATION = 0x66,
+       CALIBRATION_COMPLETE_NOTIFICATION = 0x67,
+
        /* 802.11h related */
        RADAR_NOTIFICATION = 0x70,      /* not used */
        REPLY_QUIET_CMD = 0x71,         /* not used */
@@ -129,7 +134,7 @@ enum {
        REPLY_TX_POWER_DBM_CMD = 0x98,
        MEASURE_ABORT_NOTIFICATION = 0x99,      /* not used */
 
-       /* Bluetooth device coexistance config command */
+       /* Bluetooth device coexistence config command */
        REPLY_BT_CONFIG = 0x9b,
 
        /* Statistics */
@@ -180,7 +185,7 @@ struct iwl_cmd_header {
        u8 cmd;         /* Command ID:  REPLY_RXON, etc. */
        u8 flags;       /* 0:5 reserved, 6 abort, 7 internal */
        /*
-        * The driver sets up the sequence number to values of its chosing.
+        * The driver sets up the sequence number to values of its choosing.
         * uCode does not use this value, but passes it back to the driver
         * when sending the response to each driver-originated command, so
         * the driver can match the response to the command.  Since the values
@@ -278,18 +283,20 @@ struct iwl_cmd_header {
 #define RATE_MCS_SGI_MSK 0x2000
 
 /**
- * rate_n_flags Tx antenna masks (4965 has 2 transmitters):
- * bit14:15 01 B inactive, A active
- *          10 B active, A inactive
- *          11 Both active
+ * rate_n_flags Tx antenna masks
+ * 4965 has 2 transmitters
+ * 5100 has 1 transmitter B
+ * 5150 has 1 transmitter A
+ * 5300 has 3 transmitters
+ * 5350 has 3 transmitters
+ * bit14:16
  */
 #define RATE_MCS_ANT_POS      14
 #define RATE_MCS_ANT_A_MSK    0x04000
 #define RATE_MCS_ANT_B_MSK    0x08000
 #define RATE_MCS_ANT_C_MSK    0x10000
 #define RATE_MCS_ANT_ABC_MSK  0x1C000
-
-#define RATE_MCS_ANT_INIT_IND   1
+#define RATE_ANT_NUM 3
 
 #define POWER_TABLE_NUM_ENTRIES                        33
 #define POWER_TABLE_NUM_HT_OFDM_ENTRIES                32
@@ -340,7 +347,7 @@ struct iwl4965_tx_power_db {
 } __attribute__ ((packed));
 
 /**
- * Commad REPLY_TX_POWER_DBM_CMD = 0x98
+ * Command REPLY_TX_POWER_DBM_CMD = 0x98
  * struct iwl5000_tx_power_dbm_cmd
  */
 #define IWL50_TX_POWER_AUTO 0x7f
@@ -376,7 +383,7 @@ struct iwl5000_tx_power_dbm_cmd {
  * calculating txpower settings:
  *
  * 1)  Power supply voltage indication.  The voltage sensor outputs higher
- *     values for lower voltage, and vice versa.
+ *     values for lower voltage, and vice verse.
  *
  * 2)  Temperature measurement parameters, for each of two channel widths
  *     (20 MHz and 40 MHz) supported by the radios.  Temperature sensing
@@ -477,11 +484,6 @@ struct iwl_alive_resp {
 } __attribute__ ((packed));
 
 
-union tsf {
-       u8 byte[8];
-       __le16 word[4];
-       __le32 dw[2];
-};
 
 /*
  * REPLY_ERROR = 0x2 (response only, not a command)
@@ -492,7 +494,7 @@ struct iwl_error_resp {
        u8 reserved1;
        __le16 bad_cmd_seq_num;
        __le32 error_info;
-       union tsf timestamp;
+       __le64 timestamp;
 } __attribute__ ((packed));
 
 /******************************************************************************
@@ -620,7 +622,7 @@ struct iwl4965_rxon_cmd {
        u8 ofdm_ht_dual_stream_basic_rates;
 } __attribute__ ((packed));
 
-/* 5000 HW just extend this cmmand */
+/* 5000 HW just extend this command */
 struct iwl_rxon_cmd {
        u8 node_addr[6];
        __le16 reserved1;
@@ -679,8 +681,8 @@ struct iwl4965_rxon_assoc_cmd {
 /*
  * REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
  */
-struct iwl4965_rxon_time_cmd {
-       union tsf timestamp;
+struct iwl_rxon_time_cmd {
+       __le64 timestamp;
        __le16 beacon_interval;
        __le16 atim_window;
        __le32 beacon_init_val;
@@ -1111,7 +1113,7 @@ struct iwl4965_rx_non_cfg_phy {
 #define IWL50_OFDM_RSSI_C_BIT_POS 0
 
 struct iwl5000_non_cfg_phy {
-       __le32 non_cfg_phy[IWL50_RX_RES_PHY_CNT];  /* upto 8 phy entries */
+       __le32 non_cfg_phy[IWL50_RX_RES_PHY_CNT];  /* up to 8 phy entries */
 } __attribute__ ((packed));
 
 
@@ -1167,7 +1169,7 @@ struct iwl4965_rx_mpdu_res_start {
 
 /* REPLY_TX Tx flags field */
 
-/* 1: Use RTS/CTS protocol or CTS-to-self if spec alows it
+/* 1: Use RTS/CTS protocol or CTS-to-self if spec allows it
  * before this frame. if CTS-to-self required check
  * RXON_FLG_SELF_CTS_EN status. */
 #define TX_CMD_FLG_RTS_CTS_MSK __constant_cpu_to_le32(1 << 0)
@@ -1411,21 +1413,21 @@ enum {
 };
 
 enum {
-       TX_STATUS_MSK = 0x000000ff,     /* bits 0:7 */
+       TX_STATUS_MSK = 0x000000ff,             /* bits 0:7 */
        TX_STATUS_DELAY_MSK = 0x00000040,
        TX_STATUS_ABORT_MSK = 0x00000080,
        TX_PACKET_MODE_MSK = 0x0000ff00,        /* bits 8:15 */
        TX_FIFO_NUMBER_MSK = 0x00070000,        /* bits 16:18 */
-       TX_RESERVED = 0x00780000,       /* bits 19:22 */
+       TX_RESERVED = 0x00780000,               /* bits 19:22 */
        TX_POWER_PA_DETECT_MSK = 0x7f800000,    /* bits 23:30 */
        TX_ABORT_REQUIRED_MSK = 0x80000000,     /* bits 31:31 */
 };
 
-static inline int iwl_is_tx_success(u32 status)
+static inline bool iwl_is_tx_success(u32 status)
 {
        status &= TX_STATUS_MSK;
-       return (status == TX_STATUS_SUCCESS)
-           || (status == TX_STATUS_DIRECT_DONE);
+       return (status == TX_STATUS_SUCCESS) ||
+              (status == TX_STATUS_DIRECT_DONE);
 }
 
 
@@ -1450,10 +1452,9 @@ enum {
        AGG_TX_STATE_DELAY_TX_MSK = 0x400
 };
 
-#define AGG_TX_STATE_LAST_SENT_MSK \
-(AGG_TX_STATE_LAST_SENT_TTL_MSK | \
- AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \
- AGG_TX_STATE_LAST_SENT_BT_KILL_MSK)
+#define AGG_TX_STATE_LAST_SENT_MSK  (AGG_TX_STATE_LAST_SENT_TTL_MSK | \
+                                    AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \
+                                    AGG_TX_STATE_LAST_SENT_BT_KILL_MSK)
 
 /* # tx attempts for first frame in aggregation */
 #define AGG_TX_STATE_TRY_CNT_POS 12
@@ -1526,6 +1527,28 @@ struct iwl4965_tx_resp {
        } u;
 } __attribute__ ((packed));
 
+/*
+ * definitions for initial rate index field
+ * bits [3:0] initial rate index
+ * bits [6:4] rate table color, used for the initial rate
+ * bit-7 invalid rate indication
+ *   i.e. rate was not chosen from rate table
+ *   or rate table color was changed during frame retries
+ * refer tlc rate info
+ */
+
+#define IWL50_TX_RES_INIT_RATE_INDEX_POS       0
+#define IWL50_TX_RES_INIT_RATE_INDEX_MSK       0x0f
+#define IWL50_TX_RES_RATE_TABLE_COLOR_POS      4
+#define IWL50_TX_RES_RATE_TABLE_COLOR_MSK      0x70
+#define IWL50_TX_RES_INV_RATE_INDEX_MSK        0x80
+
+/* refer to ra_tid */
+#define IWL50_TX_RES_TID_POS   0
+#define IWL50_TX_RES_TID_MSK   0x0f
+#define IWL50_TX_RES_RA_POS    4
+#define IWL50_TX_RES_RA_MSK    0xf0
+
 struct iwl5000_tx_resp {
        u8 frame_count;         /* 1 no aggregation, >1 aggregation */
        u8 bt_kill_count;       /* # blocked by bluetooth (unused for agg) */
@@ -1540,14 +1563,17 @@ struct iwl5000_tx_resp {
         * For agg:  RTS + CTS + aggregation tx time + block-ack time. */
        __le16 wireless_media_time;     /* uSecs */
 
-       __le16 reserved;
-       __le32 pa_power1;       /* RF power amplifier measurement (not used) */
-       __le32 pa_power2;
+       u8 pa_status;           /* RF power amplifier measurement (not used) */
+       u8 pa_integ_res_a[3];
+       u8 pa_integ_res_b[3];
+       u8 pa_integ_res_C[3];
 
        __le32 tfd_info;
        __le16 seq_ctl;
        __le16 byte_cnt;
-       __le32 tlc_info;
+       u8 tlc_info;
+       u8 ra_tid;              /* tid (0:3), sta_id (4:7) */
+       __le16 frame_ctrl;
        /*
         * For non-agg:  frame status TX_STATUS_*
         * For agg:  status of 1st frame, AGG_TX_STATE_*; other frame status
@@ -1742,7 +1768,7 @@ struct iwl_link_qual_agg_params {
  * match the modulation characteristics of the history set.
  *
  * When using block-ack (aggregation), all frames are transmitted at the same
- * rate, since there is no per-attempt acknowledgement from the destination
+ * rate, since there is no per-attempt acknowledgment from the destination
  * station.  The Tx response struct iwl_tx_resp indicates the Tx rate in
  * rate_n_flags field.  After receiving a block-ack, the driver can update
  * history for the entire block all at once.
@@ -1881,7 +1907,7 @@ struct iwl_link_quality_cmd {
  *
  * 3945 and 4965 support hardware handshake with Bluetooth device on
  * same platform.  Bluetooth device alerts wireless device when it will Tx;
- * wireless device can delay or kill its own Tx to accomodate.
+ * wireless device can delay or kill its own Tx to accommodate.
  */
 struct iwl4965_bt_cmd {
        u8 flags;
@@ -2043,7 +2069,7 @@ struct iwl4965_spectrum_notification {
  *              '11' Illegal set
  *
  * NOTE: if sleep_interval[SLEEP_INTRVL_TABLE_SIZE-1] > DTIM period then
- * ucode assume sleep over DTIM is allowed and we don't need to wakeup
+ * ucode assume sleep over DTIM is allowed and we don't need to wake up
  * for every DTIM.
  */
 #define IWL_POWER_VEC_SIZE 5
@@ -2849,55 +2875,30 @@ struct iwl_sensitivity_cmd {
  * 1-0: amount of gain, units of 1.5 dB
  */
 
-/* "Differential Gain" opcode used in REPLY_PHY_CALIBRATION_CMD. */
-#define PHY_CALIBRATE_DIFF_GAIN_CMD (7)
-
-struct iwl4965_calibration_cmd {
-       u8 opCode;              /* PHY_CALIBRATE_DIFF_GAIN_CMD (7) */
-       u8 flags;               /* not used */
-       __le16 reserved;
-       s8 diff_gain_a;         /* see above */
-       s8 diff_gain_b;
-       s8 diff_gain_c;
-       u8 reserved1;
-} __attribute__ ((packed));
-
-/* Phy calibration command for 5000 series */
+/* Phy calibration command for series */
 
 enum {
-       IWL5000_PHY_CALIBRATE_DC_CMD            = 8,
-       IWL5000_PHY_CALIBRATE_LO_CMD            = 9,
-       IWL5000_PHY_CALIBRATE_RX_BB_CMD         = 10,
-       IWL5000_PHY_CALIBRATE_TX_IQ_CMD         = 11,
-       IWL5000_PHY_CALIBRATE_RX_IQ_CMD         = 12,
-       IWL5000_PHY_CALIBRATION_NOISE_CMD       = 13,
-       IWL5000_PHY_CALIBRATE_AGC_TABLE_CMD     = 14,
-       IWL5000_PHY_CALIBRATE_CRYSTAL_FRQ_CMD   = 15,
-       IWL5000_PHY_CALIBRATE_BASE_BAND_CMD     = 16,
-       IWL5000_PHY_CALIBRATE_TX_IQ_PERD_CMD    = 17,
-       IWL5000_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD = 18,
-       IWL5000_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD = 19,
+       IWL_PHY_CALIBRATE_DIFF_GAIN_CMD         = 7,
+       IWL_PHY_CALIBRATE_DC_CMD                = 8,
+       IWL_PHY_CALIBRATE_LO_CMD                = 9,
+       IWL_PHY_CALIBRATE_RX_BB_CMD             = 10,
+       IWL_PHY_CALIBRATE_TX_IQ_CMD             = 11,
+       IWL_PHY_CALIBRATE_RX_IQ_CMD             = 12,
+       IWL_PHY_CALIBRATION_NOISE_CMD           = 13,
+       IWL_PHY_CALIBRATE_AGC_TABLE_CMD         = 14,
+       IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD       = 15,
+       IWL_PHY_CALIBRATE_BASE_BAND_CMD         = 16,
+       IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD        = 17,
+       IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD = 18,
+       IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD  = 19,
 };
 
-enum {
-       CALIBRATION_CFG_CMD = 0x65,
-       CALIBRATION_RES_NOTIFICATION = 0x66,
-       CALIBRATION_COMPLETE_NOTIFICATION = 0x67
-};
 
-struct iwl_cal_crystal_freq_cmd {
+struct iwl_cal_xtal_freq {
        u8 cap_pin1;
        u8 cap_pin2;
 } __attribute__ ((packed));
 
-struct iwl5000_calibration {
-       u8 op_code;
-       u8 first_group;
-       u8 num_groups;
-       u8 all_data_valid;
-       struct iwl_cal_crystal_freq_cmd data;
-} __attribute__ ((packed));
-
 #define IWL_CALIB_INIT_CFG_ALL __constant_cpu_to_le32(0xffffffff)
 
 struct iwl_calib_cfg_elmnt_s {
@@ -2914,27 +2915,44 @@ struct iwl_calib_cfg_status_s {
        __le32 flags;
 } __attribute__ ((packed));
 
-struct iwl5000_calib_cfg_cmd {
+struct iwl_calib_cfg_cmd {
        struct iwl_calib_cfg_status_s ucd_calib_cfg;
        struct iwl_calib_cfg_status_s drv_calib_cfg;
        __le32 reserved1;
 } __attribute__ ((packed));
 
-struct iwl5000_calib_hdr {
+struct iwl_calib_hdr {
        u8 op_code;
        u8 first_group;
        u8 groups_num;
        u8 data_valid;
 } __attribute__ ((packed));
 
-struct iwl5000_calibration_chain_noise_reset_cmd {
-       u8 op_code;     /* IWL5000_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */
+struct iwl_calib_cmd {
+       struct iwl_calib_hdr hdr;
+       u8 data[0];
+} __attribute__ ((packed));
+
+/* "Differential Gain" opcode used in REPLY_PHY_CALIBRATION_CMD. */
+
+struct iwl_calib_diff_gain_cmd {
+       u8 opCode;              /* IWL_PHY_CALIBRATE_DIFF_GAIN_CMD (7) */
+       u8 flags;               /* not used */
+       __le16 reserved;
+       s8 diff_gain_a;         /* see above */
+       s8 diff_gain_b;
+       s8 diff_gain_c;
+       u8 reserved1;
+} __attribute__ ((packed));
+
+struct iwl_calib_chain_noise_reset_cmd {
+       u8 op_code;     /* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */
        u8 flags;       /* not used */
        __le16 reserved;
 } __attribute__ ((packed));
 
-struct iwl5000_calibration_chain_noise_gain_cmd {
-       u8 op_code;     /* IWL5000_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD */
+struct iwl_calib_chain_noise_gain_cmd {
+       u8 op_code;     /* IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD */
        u8 flags;       /* not used */
        __le16 reserved;
        u8 delta_gain_1;
@@ -2999,11 +3017,11 @@ struct iwl_wimax_coex_event_entry {
 
 /* COEX flag masks */
 
-/* Staion table is valid */
+/* Station table is valid */
 #define COEX_FLAGS_STA_TABLE_VALID_MSK      (0x1)
-/* UnMask wakeup src at unassociated sleep */
+/* UnMask wake up src at unassociated sleep */
 #define COEX_FLAGS_UNASSOC_WA_UNMASK_MSK    (0x4)
-/* UnMask wakeup src at associated sleep */
+/* UnMask wake up src at associated sleep */
 #define COEX_FLAGS_ASSOC_WA_UNMASK_MSK      (0x8)
 /* Enable CoEx feature. */
 #define COEX_FLAGS_COEX_ENABLE_MSK          (0x80)
@@ -3039,7 +3057,6 @@ struct iwl_rx_packet {
                struct iwl_notif_statistics stats;
                struct iwl_compressed_ba_resp compressed_ba;
                struct iwl4965_missed_beacon_notif missed_beacon;
-               struct iwl5000_calibration calib;
                __le32 status;
                u8 raw[0];
        } u;
@@ -3047,4 +3064,4 @@ struct iwl_rx_packet {
 
 #define IWL_RX_FRAME_SIZE        (4 + sizeof(struct iwl4965_rx_frame))
 
-#endif                         /* __iwl4965_commands_h__ */
+#endif                         /* __iwl_commands_h__ */
index 4c312c55f90cf49838af8954e0e891a0893af99c..8eb02031e797e59f0c92695b2e951a8d7967b834 100644 (file)
@@ -88,26 +88,27 @@ EXPORT_SYMBOL(iwl_rates);
  * translate ucode response to mac80211 tx status control values
  */
 void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
-                                 struct ieee80211_tx_info *control)
+                                 struct ieee80211_tx_info *info)
 {
        int rate_index;
+       struct ieee80211_tx_rate *r = &info->control.rates[0];
 
-       control->antenna_sel_tx =
+       info->antenna_sel_tx =
                ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
        if (rate_n_flags & RATE_MCS_HT_MSK)
-               control->flags |= IEEE80211_TX_CTL_OFDM_HT;
+               r->flags |= IEEE80211_TX_RC_MCS;
        if (rate_n_flags & RATE_MCS_GF_MSK)
-               control->flags |= IEEE80211_TX_CTL_GREEN_FIELD;
+               r->flags |= IEEE80211_TX_RC_GREEN_FIELD;
        if (rate_n_flags & RATE_MCS_FAT_MSK)
-               control->flags |= IEEE80211_TX_CTL_40_MHZ_WIDTH;
+               r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
        if (rate_n_flags & RATE_MCS_DUP_MSK)
-               control->flags |= IEEE80211_TX_CTL_DUP_DATA;
+               r->flags |= IEEE80211_TX_RC_DUP_DATA;
        if (rate_n_flags & RATE_MCS_SGI_MSK)
-               control->flags |= IEEE80211_TX_CTL_SHORT_GI;
+               r->flags |= IEEE80211_TX_RC_SHORT_GI;
        rate_index = iwl_hwrate_to_plcp_idx(rate_n_flags);
-       if (control->band == IEEE80211_BAND_5GHZ)
+       if (info->band == IEEE80211_BAND_5GHZ)
                rate_index -= IWL_FIRST_OFDM_RATE;
-       control->tx_rate_idx = rate_index;
+       r->idx = rate_index;
 }
 EXPORT_SYMBOL(iwl_hwrate_to_tx_control);
 
@@ -119,7 +120,9 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
        if (rate_n_flags & RATE_MCS_HT_MSK) {
                idx = (rate_n_flags & 0xff);
 
-               if (idx >= IWL_RATE_MIMO2_6M_PLCP)
+               if (idx >= IWL_RATE_MIMO3_6M_PLCP)
+                       idx = idx - IWL_RATE_MIMO3_6M_PLCP;
+               else if (idx >= IWL_RATE_MIMO2_6M_PLCP)
                        idx = idx - IWL_RATE_MIMO2_6M_PLCP;
 
                idx += IWL_FIRST_OFDM_RATE;
@@ -140,7 +143,17 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
 }
 EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx);
 
-
+u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant)
+{
+       int i;
+       u8 ind = ant;
+       for (i = 0; i < RATE_ANT_NUM - 1; i++) {
+               ind = (ind + 1) < RATE_ANT_NUM ?  ind + 1 : 0;
+               if (priv->hw_params.valid_tx_ant & BIT(ind))
+                       return ind;
+       }
+       return ant;
+}
 
 const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 EXPORT_SYMBOL(iwl_bcast_addr);
@@ -382,10 +395,10 @@ void iwl_reset_qos(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_reset_qos);
 
-#define MAX_BIT_RATE_40_MHZ 0x96 /* 150 Mbps */
-#define MAX_BIT_RATE_20_MHZ 0x48 /* 72 Mbps */
+#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
+#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
 static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
-                             struct ieee80211_ht_info *ht_info,
+                             struct ieee80211_sta_ht_cap *ht_info,
                              enum ieee80211_band band)
 {
        u16 max_bit_rate = 0;
@@ -393,45 +406,46 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
        u8 tx_chains_num = priv->hw_params.tx_chains_num;
 
        ht_info->cap = 0;
-       memset(ht_info->supp_mcs_set, 0, 16);
+       memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
 
-       ht_info->ht_supported = 1;
+       ht_info->ht_supported = true;
 
-       ht_info->cap |= (u16)IEEE80211_HT_CAP_GRN_FLD;
-       ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_20;
-       ht_info->cap |= (u16)(IEEE80211_HT_CAP_SM_PS &
+       ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
+       ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
+       ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
                             (WLAN_HT_CAP_SM_PS_DISABLED << 2));
 
        max_bit_rate = MAX_BIT_RATE_20_MHZ;
        if (priv->hw_params.fat_channel & BIT(band)) {
-               ht_info->cap |= (u16)IEEE80211_HT_CAP_SUP_WIDTH;
-               ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_40;
-               ht_info->supp_mcs_set[4] = 0x01;
+               ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+               ht_info->cap |= IEEE80211_HT_CAP_SGI_40;
+               ht_info->mcs.rx_mask[4] = 0x01;
                max_bit_rate = MAX_BIT_RATE_40_MHZ;
        }
 
        if (priv->cfg->mod_params->amsdu_size_8K)
-               ht_info->cap |= (u16)IEEE80211_HT_CAP_MAX_AMSDU;
+               ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
 
        ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
        ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF;
 
-       ht_info->supp_mcs_set[0] = 0xFF;
+       ht_info->mcs.rx_mask[0] = 0xFF;
        if (rx_chains_num >= 2)
-               ht_info->supp_mcs_set[1] = 0xFF;
+               ht_info->mcs.rx_mask[1] = 0xFF;
        if (rx_chains_num >= 3)
-               ht_info->supp_mcs_set[2] = 0xFF;
+               ht_info->mcs.rx_mask[2] = 0xFF;
 
        /* Highest supported Rx data rate */
        max_bit_rate *= rx_chains_num;
-       ht_info->supp_mcs_set[10] = (u8)(max_bit_rate & 0x00FF);
-       ht_info->supp_mcs_set[11] = (u8)((max_bit_rate & 0xFF00) >> 8);
+       WARN_ON(max_bit_rate & ~IEEE80211_HT_MCS_RX_HIGHEST_MASK);
+       ht_info->mcs.rx_highest = cpu_to_le16(max_bit_rate);
 
        /* Tx MCS capabilities */
-       ht_info->supp_mcs_set[12] = IEEE80211_HT_CAP_MCS_TX_DEFINED;
+       ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
        if (tx_chains_num != rx_chains_num) {
-               ht_info->supp_mcs_set[12] |= IEEE80211_HT_CAP_MCS_TX_RX_DIFF;
-               ht_info->supp_mcs_set[12] |= ((tx_chains_num - 1) << 2);
+               ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
+               ht_info->mcs.tx_params |= ((tx_chains_num - 1) <<
+                               IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
        }
 }
 
@@ -495,7 +509,7 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
        sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE;
 
        if (priv->cfg->sku & IWL_SKU_N)
-               iwlcore_init_ht_hw_capab(priv, &sband->ht_info,
+               iwlcore_init_ht_hw_capab(priv, &sband->ht_cap,
                                         IEEE80211_BAND_5GHZ);
 
        sband = &priv->bands[IEEE80211_BAND_2GHZ];
@@ -505,7 +519,7 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
        sband->n_bitrates = IWL_RATE_COUNT;
 
        if (priv->cfg->sku & IWL_SKU_N)
-               iwlcore_init_ht_hw_capab(priv, &sband->ht_info,
+               iwlcore_init_ht_hw_capab(priv, &sband->ht_cap,
                                         IEEE80211_BAND_2GHZ);
 
        priv->ieee_channels = channels;
@@ -595,8 +609,8 @@ static void iwlcore_free_geos(struct iwl_priv *priv)
 static bool is_single_rx_stream(struct iwl_priv *priv)
 {
        return !priv->current_ht_config.is_ht ||
-              ((priv->current_ht_config.supp_mcs_set[1] == 0) &&
-               (priv->current_ht_config.supp_mcs_set[2] == 0));
+              ((priv->current_ht_config.mcs.rx_mask[1] == 0) &&
+               (priv->current_ht_config.mcs.rx_mask[2] == 0));
 }
 
 static u8 iwl_is_channel_extension(struct iwl_priv *priv,
@@ -609,10 +623,10 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv,
        if (!is_channel_valid(ch_info))
                return 0;
 
-       if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE)
+       if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
                return !(ch_info->fat_extension_channel &
                                        IEEE80211_CHAN_NO_FAT_ABOVE);
-       else if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW)
+       else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW)
                return !(ch_info->fat_extension_channel &
                                        IEEE80211_CHAN_NO_FAT_BELOW);
 
@@ -620,24 +634,24 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv,
 }
 
 u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
-                            struct ieee80211_ht_info *sta_ht_inf)
+                        struct ieee80211_sta_ht_cap *sta_ht_inf)
 {
        struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config;
 
        if ((!iwl_ht_conf->is_ht) ||
           (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) ||
-          (iwl_ht_conf->extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE))
+          (iwl_ht_conf->extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE))
                return 0;
 
        if (sta_ht_inf) {
                if ((!sta_ht_inf->ht_supported) ||
-                  (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH)))
+                  (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)))
                        return 0;
        }
 
        return iwl_is_channel_extension(priv, priv->band,
-                                        iwl_ht_conf->control_channel,
-                                        iwl_ht_conf->extension_chan_offset);
+                                       le16_to_cpu(priv->staging_rxon.channel),
+                                       iwl_ht_conf->extension_chan_offset);
 }
 EXPORT_SYMBOL(iwl_is_fat_tx_allowed);
 
@@ -662,22 +676,15 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
                rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
                                 RXON_FLG_CHANNEL_MODE_PURE_40_MSK);
 
-       if (le16_to_cpu(rxon->channel) != ht_info->control_channel) {
-               IWL_DEBUG_ASSOC("control diff than current %d %d\n",
-                               le16_to_cpu(rxon->channel),
-                               ht_info->control_channel);
-               return;
-       }
-
        /* Note: control channel is opposite of extension channel */
        switch (ht_info->extension_chan_offset) {
-       case IEEE80211_HT_IE_CHA_SEC_ABOVE:
+       case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
                rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
                break;
-       case IEEE80211_HT_IE_CHA_SEC_BELOW:
+       case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
                rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
                break;
-       case IEEE80211_HT_IE_CHA_SEC_NONE:
+       case IEEE80211_HT_PARAM_CHA_SEC_NONE:
        default:
                rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK;
                break;
@@ -691,14 +698,12 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
 
        IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X "
                        "rxon flags 0x%X operation mode :0x%X "
-                       "extension channel offset 0x%x "
-                       "control chan %d\n",
-                       ht_info->supp_mcs_set[0],
-                       ht_info->supp_mcs_set[1],
-                       ht_info->supp_mcs_set[2],
+                       "extension channel offset 0x%x\n",
+                       ht_info->mcs.rx_mask[0],
+                       ht_info->mcs.rx_mask[1],
+                       ht_info->mcs.rx_mask[2],
                        le32_to_cpu(rxon->flags), ht_info->ht_protection,
-                       ht_info->extension_chan_offset,
-                       ht_info->control_channel);
+                       ht_info->extension_chan_offset);
        return;
 }
 EXPORT_SYMBOL(iwl_set_rxon_ht);
@@ -742,7 +747,7 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
                break;
        case WLAN_HT_CAP_SM_PS_INVALID:
        default:
-               IWL_ERROR("invalide mimo ps mode %d\n",
+               IWL_ERROR("invalid mimo ps mode %d\n",
                           priv->current_ht_config.sm_ps);
                WARN_ON(1);
                idle_cnt = -1;
@@ -868,7 +873,8 @@ int iwl_setup_mac(struct iwl_priv *priv)
 
        /* Tell mac80211 our characteristics */
        hw->flags = IEEE80211_HW_SIGNAL_DBM |
-                   IEEE80211_HW_NOISE_DBM;
+                   IEEE80211_HW_NOISE_DBM |
+                   IEEE80211_HW_AMPDU_AGGREGATION;
        hw->wiphy->interface_modes =
                BIT(NL80211_IFTYPE_AP) |
                BIT(NL80211_IFTYPE_STATION) |
@@ -945,7 +951,6 @@ int iwl_init_drv(struct iwl_priv *priv)
 
        priv->iw_mode = NL80211_IFTYPE_STATION;
 
-       priv->use_ant_b_for_management_frame = 1; /* start with ant B */
        priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED;
 
        /* Choose which receivers/antennas to use */
@@ -1169,24 +1174,47 @@ int iwl_verify_ucode(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_verify_ucode);
 
+
+static const char *desc_lookup_text[] = {
+       "OK",
+       "FAIL",
+       "BAD_PARAM",
+       "BAD_CHECKSUM",
+       "NMI_INTERRUPT_WDG",
+       "SYSASSERT",
+       "FATAL_ERROR",
+       "BAD_COMMAND",
+       "HW_ERROR_TUNE_LOCK",
+       "HW_ERROR_TEMPERATURE",
+       "ILLEGAL_CHAN_FREQ",
+       "VCC_NOT_STABLE",
+       "FH_ERROR",
+       "NMI_INTERRUPT_HOST",
+       "NMI_INTERRUPT_ACTION_PT",
+       "NMI_INTERRUPT_UNKNOWN",
+       "UCODE_VERSION_MISMATCH",
+       "HW_ERROR_ABS_LOCK",
+       "HW_ERROR_CAL_LOCK_FAIL",
+       "NMI_INTERRUPT_INST_ACTION_PT",
+       "NMI_INTERRUPT_DATA_ACTION_PT",
+       "NMI_TRM_HW_ER",
+       "NMI_INTERRUPT_TRM",
+       "NMI_INTERRUPT_BREAK_POINT"
+       "DEBUG_0",
+       "DEBUG_1",
+       "DEBUG_2",
+       "DEBUG_3",
+       "UNKNOWN"
+};
+
 static const char *desc_lookup(int i)
 {
-       switch (i) {
-       case 1:
-               return "FAIL";
-       case 2:
-               return "BAD_PARAM";
-       case 3:
-               return "BAD_CHECKSUM";
-       case 4:
-               return "NMI_INTERRUPT";
-       case 5:
-               return "SYSASSERT";
-       case 6:
-               return "FATAL_ERROR";
-       }
+       int max = ARRAY_SIZE(desc_lookup_text) - 1;
+
+       if (i < 0 || i > max)
+               i = max;
 
-       return "UNKNOWN";
+       return desc_lookup_text[i];
 }
 
 #define ERROR_START_OFFSET  (1 * sizeof(u32))
@@ -1232,9 +1260,9 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
        line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
        time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
 
-       IWL_ERROR("Desc        Time       "
+       IWL_ERROR("Desc                               Time       "
                "data1      data2      line\n");
-       IWL_ERROR("%-13s (#%d) %010u 0x%08X 0x%08X %u\n",
+       IWL_ERROR("%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
                desc_lookup(desc), desc, time, data1, data2, line);
        IWL_ERROR("blink1  blink2  ilink1  ilink2\n");
        IWL_ERROR("0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
index 288b6a800e03306cc2cc34885e364450b9389cb2..10f07f6e17372fd69a02d190e1fa87a227dc423e 100644 (file)
@@ -100,7 +100,7 @@ struct iwl_hcmd_utils_ops {
 };
 
 struct iwl_lib_ops {
-       /* set hw dependant perameters */
+       /* set hw dependent parameters */
        int (*set_hw_params)(struct iwl_priv *priv);
        /* ucode shared memory */
        int (*alloc_shared_mem)(struct iwl_priv *priv);
@@ -173,6 +173,8 @@ struct iwl_cfg {
        const char *fw_name;
        unsigned int sku;
        int eeprom_size;
+       u16  eeprom_ver;
+       u16  eeprom_calib_ver;
        const struct iwl_ops *ops;
        const struct iwl_mod_params *mod_params;
 };
@@ -190,7 +192,7 @@ void iwl_set_rxon_chain(struct iwl_priv *priv);
 int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
 void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info);
 u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
-                        struct ieee80211_ht_info *sta_ht_inf);
+                        struct ieee80211_sta_ht_cap *sta_ht_inf);
 int iwl_hw_nic_init(struct iwl_priv *priv);
 int iwl_setup_mac(struct iwl_priv *priv);
 int iwl_set_hw_params(struct iwl_priv *priv);
@@ -237,7 +239,6 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
 int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
 int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
 int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
-
 /*****************************************************
  * TX power
  ****************************************************/
@@ -259,6 +260,13 @@ void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
                              struct ieee80211_tx_info *info);
 int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
 
+u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx);
+
+static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
+{
+       return BIT(ant_idx) << RATE_MCS_ANT_POS;
+}
+
 static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
 {
        return le32_to_cpu(rate_n_flags) & 0xFF;
@@ -313,6 +321,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
 void iwl_dump_nic_error_log(struct iwl_priv *priv);
 void iwl_dump_nic_event_log(struct iwl_priv *priv);
 
+
 /*************** DRIVER STATUS FUNCTIONS   *****/
 
 #define STATUS_HCMD_ACTIVE     0       /* host command in progress */
index 662edf4f8d226a13e8ce915e9c2aa085d581adc5..84f56a21770dd1fcab05836b1b05c7483ec6bd22 100644 (file)
@@ -60,6 +60,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  *****************************************************************************/
+#ifndef __iwl_csr_h__
+#define __iwl_csr_h__
 /*=== CSR (control and status registers) ===*/
 #define CSR_BASE    (0x000)
 
 #define HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED         (0x00000004)
 
 
-
+#endif /* !__iwl_csr_h__ */
index e548d67f87fd400583d1ff61ab06d24f78a2885b..84b7772809e3dae0966a2f8de4447afec63b10b9 100644 (file)
@@ -101,13 +101,12 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
  *
  * To add your debug level to the list of levels seen when you perform
  *
- * % cat /proc/net/iwl/debug_level
+ * % cat /sys/class/net/wlanX/device/debug_level
  *
  * you simply need to add your entry to the iwl_debug_levels array.
  *
- * If you do not see debug_level in /proc/net/iwl then you do not have
- * CONFIG_IWLWIFI_DEBUG defined in your kernel configuration
- *
+ * If you do not see debug_level in  /sys/class/net/wlanX/device/debug_level
+ * then you do not have CONFIG_IWLWIFI_DEBUG defined in your kernel config file
  */
 
 #define IWL_DL_INFO            (1 << 0)
@@ -183,6 +182,8 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
 #define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
 #define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a)
 #define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
+#define IWL_DEBUG_TX_REPLY_LIMIT(f, a...) \
+       IWL_DEBUG_LIMIT(IWL_DL_TX_REPLY, f, ## a)
 #define IWL_DEBUG_QOS(f, a...)   IWL_DEBUG(IWL_DL_QOS, f, ## a)
 #define IWL_DEBUG_RADIO(f, a...)  IWL_DEBUG(IWL_DL_RADIO, f, ## a)
 #define IWL_DEBUG_POWER(f, a...)  IWL_DEBUG(IWL_DL_POWER, f, ## a)
index 20db0eb636a82b64a85f403ef5c096ab37827aaf..c3df5aa8df919350459bc6ad9d172ae3a76628a3 100644 (file)
@@ -58,7 +58,8 @@
 #define DEBUGFS_ADD_BOOL(name, parent, ptr) do {                        \
        dbgfs->dbgfs_##parent##_files.file_##name =                     \
        debugfs_create_bool(#name, 0644, dbgfs->dir_##parent, ptr);     \
-       if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name))          \
+       if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name)           \
+                       || !dbgfs->dbgfs_##parent##_files.file_##name)  \
                goto err;                                               \
 } while (0)
 
@@ -228,7 +229,6 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
        ssize_t ret;
        /* Add 30 for initial string */
        const size_t bufsz = 30 + sizeof(char) * 500 * (priv->num_stations);
-       DECLARE_MAC_BUF(mac);
 
        buf = kmalloc(bufsz, GFP_KERNEL);
        if (!buf)
@@ -242,7 +242,6 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
                if (station->used) {
                        pos += scnprintf(buf + pos, bufsz - pos,
                                        "station %d:\ngeneral data:\n", i+1);
-                       print_mac(mac, station->sta.sta.addr);
                        pos += scnprintf(buf + pos, bufsz - pos, "id: %u\n",
                                        station->sta.sta.sta_id);
                        pos += scnprintf(buf + pos, bufsz - pos, "mode: %u\n",
index c018121085e937dd210d2048f549f6cbcf6b0dfd..eb396f26730cbd416cb3bde06b56ba2bd35336c4 100644 (file)
@@ -112,11 +112,9 @@ struct iwl_queue {
                                * space less than this */
 } __attribute__ ((packed));
 
-#define MAX_NUM_OF_TBS          (20)
-
 /* One for each TFD */
 struct iwl_tx_info {
-       struct sk_buff *skb[MAX_NUM_OF_TBS];
+       struct sk_buff *skb[IWL_NUM_OF_TBS - 1];
 };
 
 /**
@@ -134,12 +132,13 @@ struct iwl_tx_info {
  */
 struct iwl_tx_queue {
        struct iwl_queue q;
-       struct iwl_tfd_frame *bd;
+       struct iwl_tfd *tfds;
        struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS];
        struct iwl_tx_info *txb;
-       int need_update;
-       int sched_retry;
-       int active;
+       u8 need_update;
+       u8 sched_retry;
+       u8 active;
+       u8 swq_id;
 };
 
 #define IWL_NUM_SCAN_RATES         (2)
@@ -252,7 +251,8 @@ struct iwl_cmd_meta {
        /* The CMD_SIZE_HUGE flag bit indicates that the command
         * structure is stored at the end of the shared queue memory. */
        u32 flags;
-
+       DECLARE_PCI_UNMAP_ADDR(mapping)
+       DECLARE_PCI_UNMAP_LEN(len)
 } __attribute__ ((packed));
 
 #define IWL_CMD_MAX_PAYLOAD 320
@@ -268,24 +268,16 @@ struct iwl_cmd {
        struct iwl_cmd_meta meta;       /* driver data */
        struct iwl_cmd_header hdr;      /* uCode API */
        union {
-               struct iwl_addsta_cmd addsta;
-               struct iwl_led_cmd led;
                u32 flags;
                u8 val8;
                u16 val16;
                u32 val32;
-               struct iwl4965_bt_cmd bt;
-               struct iwl4965_rxon_time_cmd rxon_time;
-               struct iwl_powertable_cmd powertable;
-               struct iwl_qosparam_cmd qosparam;
                struct iwl_tx_cmd tx;
-               struct iwl4965_rxon_assoc_cmd rxon_assoc;
-               struct iwl_rem_sta_cmd rm_sta;
-               u8 *indirect;
                u8 payload[IWL_CMD_MAX_PAYLOAD];
        } __attribute__ ((packed)) cmd;
 } __attribute__ ((packed));
 
+
 struct iwl_host_cmd {
        u8 id;
        u16 len;
@@ -412,9 +404,8 @@ struct iwl_ht_info {
        u8 max_amsdu_size;
        u8 ampdu_factor;
        u8 mpdu_density;
-       u8 supp_mcs_set[16];
+       struct ieee80211_mcs_info mcs;
        /* BSS related data */
-       u8 control_channel;
        u8 extension_chan_offset;
        u8 tx_chan_width;
        u8 ht_protection;
@@ -527,8 +518,8 @@ struct iwl_sensitivity_ranges {
  * @sw_crypto: 0 for hw, 1 for sw
  * @max_xxx_size: for ucode uses
  * @ct_kill_threshold: temperature threshold
+ * @calib_init_cfg: setup initial calibrations for the hw
  * @struct iwl_sensitivity_ranges: range of sensitivity values
- * @first_ampdu_q: first HW queue available for ampdu
  */
 struct iwl_hw_params {
        u16 max_txq_num;
@@ -548,8 +539,8 @@ struct iwl_hw_params {
        u32 max_data_size;
        u32 max_bsm_size;
        u32 ct_kill_threshold; /* value in hw-dependent units */
+       u32 calib_init_cfg;
        const struct iwl_sensitivity_ranges *sens;
-       u8 first_ampdu_q;
 };
 
 #define HT_SHORT_GI_20MHZ      (1 << 0)
@@ -584,9 +575,9 @@ struct iwl_addsta_cmd;
 extern int iwl_send_add_sta(struct iwl_priv *priv,
                            struct iwl_addsta_cmd *sta, u8 flags);
 extern u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr,
-                       int is_ap, u8 flags, struct ieee80211_ht_info *ht_info);
-extern void iwl4965_update_chain_flags(struct iwl_priv *priv);
-extern int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
+                       int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info);
+extern void iwl_update_chain_flags(struct iwl_priv *priv);
+extern int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
 extern const u8 iwl_bcast_addr[ETH_ALEN];
 extern int iwl_rxq_stop(struct iwl_priv *priv);
 extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
@@ -699,6 +690,20 @@ struct statistics_general_data {
        u32 beacon_energy_c;
 };
 
+
+/*
+ * enum iwl_calib
+ * defines the order in which results of initial calibrations
+ * should be sent to the runtime uCode
+ */
+enum iwl_calib {
+       IWL_CALIB_XTAL,
+       IWL_CALIB_LO,
+       IWL_CALIB_TX_IQ,
+       IWL_CALIB_TX_IQ_PERD,
+       IWL_CALIB_MAX
+};
+
 /* Opaque calibration results */
 struct iwl_calib_result {
        void *buf;
@@ -765,7 +770,6 @@ enum {
 
 
 #define IWL_MAX_NUM_QUEUES     20 /* FIXME: do dynamic allocation */
-#define IWL_CALIB_MAX  3
 
 struct iwl_priv {
 
@@ -817,12 +821,13 @@ struct iwl_priv {
        unsigned long scan_start;
        unsigned long scan_pass_start;
        unsigned long scan_start_tsf;
+       struct iwl_scan_cmd *scan;
        int scan_bands;
        int one_direct_scan;
        u8 direct_ssid_len;
        u8 direct_ssid[IW_ESSID_MAX_SIZE];
-       struct iwl_scan_cmd *scan;
-       u32 scan_tx_ant[IEEE80211_NUM_BANDS];
+       u8 scan_tx_ant[IEEE80211_NUM_BANDS];
+       u8 mgmt_tx_ant;
 
        /* spinlock */
        spinlock_t lock;        /* protect general shared data */
@@ -849,7 +854,7 @@ struct iwl_priv {
        u8 ucode_write_complete;        /* the image write is complete */
 
 
-       struct iwl4965_rxon_time_cmd rxon_timing;
+       struct iwl_rxon_time_cmd rxon_timing;
 
        /* We declare this const so it can only be
         * changed via explicit cast within the
@@ -881,7 +886,6 @@ struct iwl_priv {
        u16 active_rate_basic;
 
        u8 assoc_station_added;
-       u8 use_ant_b_for_management_frame;      /* Tx antenna selection */
        u8 start_calib;
        struct iwl_sensitivity_data sensitivity_data;
        struct iwl_chain_noise_data chain_noise_data;
@@ -907,7 +911,7 @@ struct iwl_priv {
 
        unsigned long status;
 
-       int last_rx_rssi;       /* From Rx packet statisitics */
+       int last_rx_rssi;       /* From Rx packet statistics */
        int last_rx_noise;      /* From beacon statistics */
 
        /* counts mgmt, ctl, and data packets */
@@ -922,8 +926,6 @@ struct iwl_priv {
        unsigned long last_statistics_time;
 
        /* context information */
-       u8 essid[IW_ESSID_MAX_SIZE];
-       u8 essid_len;
        u16 rates_mask;
 
        u32 power_mode;
index 37155755efc596bb51d3dc395374bf40a533b086..792a3c15f172a95ebc4d322477c50942fa8449cb 100644 (file)
@@ -279,7 +279,23 @@ EXPORT_SYMBOL(iwl_eeprom_free);
 
 int iwl_eeprom_check_version(struct iwl_priv *priv)
 {
-       return priv->cfg->ops->lib->eeprom_ops.check_version(priv);
+       u16 eeprom_ver;
+       u16 calib_ver;
+
+       eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
+       calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv);
+
+       if (eeprom_ver < priv->cfg->eeprom_ver ||
+           calib_ver < priv->cfg->eeprom_calib_ver)
+               goto err;
+
+       return 0;
+err:
+       IWL_ERROR("Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
+                 eeprom_ver, priv->cfg->eeprom_ver,
+                 calib_ver,  priv->cfg->eeprom_calib_ver);
+       return -EINVAL;
+
 }
 EXPORT_SYMBOL(iwl_eeprom_check_version);
 
index d3a2a5b4ac56214f4127c4a6456650e0f6fc82b6..997f23c8db2e8245edd461bd404722c496960b6d 100644 (file)
@@ -174,6 +174,9 @@ struct iwl_eeprom_channel {
 #define EEPROM_5000_REG_BAND_52_FAT_CHANNELS  ((0x92)\
                | INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 22  bytes */
 
+/* 5050 Specific */
+#define EEPROM_5050_TX_POWER_VERSION    (4)
+#define EEPROM_5050_EEPROM_VERSION     (0x21E)
 
 /* 2.4 GHz */
 extern const u8 iwl_eeprom_band_1[14];
@@ -371,7 +374,7 @@ struct iwl_eeprom_ops {
        int (*verify_signature) (struct iwl_priv *priv);
        int (*acquire_semaphore) (struct iwl_priv *priv);
        void (*release_semaphore) (struct iwl_priv *priv);
-       int (*check_version) (struct iwl_priv *priv);
+       u16 (*calib_version) (struct iwl_priv *priv);
        const u8* (*query_addr) (const struct iwl_priv *priv, size_t offset);
 };
 
index a72efdf6d1dd20160f5bf1526717007615ad875e..97e2cf41258d278109fd811619d06f5c8cfc9354 100644 (file)
@@ -60,6 +60,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  *****************************************************************************/
+#ifndef __iwl_fh_h__
+#define __iwl_fh_h__
 
 /****************************/
 /* Flow Handler Definitions */
 #define FH_TCSR_UPPER_BOUND  (FH_MEM_LOWER_BOUND + 0xE60)
 
 /* Find Control/Status reg for given Tx DMA/FIFO channel */
-#define FH_TCSR_CHNL_TX_CONFIG_REG(_chnl) \
-       (FH_TCSR_LOWER_BOUND + 0x20 * _chnl)
+#define FH49_TCSR_CHNL_NUM                            (7)
+#define FH50_TCSR_CHNL_NUM                            (8)
 
-#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL    (0x00000000)
-#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL     (0x00000008)
+#define FH_TCSR_CHNL_TX_CONFIG_REG(_chnl)      \
+               (FH_TCSR_LOWER_BOUND + 0x20 * (_chnl))
+#define FH_TCSR_CHNL_TX_CREDIT_REG(_chnl)      \
+               (FH_TCSR_LOWER_BOUND + 0x20 * (_chnl) + 0x4)
+#define FH_TCSR_CHNL_TX_BUF_STS_REG(_chnl)     \
+               (FH_TCSR_LOWER_BOUND + 0x20 * (_chnl) + 0x8)
 
-#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE            (0x00000000)
-#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE_EOF        (0x40000000)
-#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE           (0x80000000)
+#define FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF         (0x00000000)
+#define FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRV         (0x00000001)
 
-#define FH_TCSR_CHNL_NUM                            (7)
+#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE   (0x00000000)
+#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE    (0x00000008)
 
-#define FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_EMPTY          (0x00000000)
-#define FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_WAIT           (0x00002000)
-#define FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID          (0x00000003)
+#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_NOINT      (0x00000000)
+#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD     (0x00100000)
+#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD      (0x00200000)
 
-#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_NOINT           (0x00000000)
-#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD          (0x00100000)
-#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD           (0x00200000)
+#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT       (0x00000000)
+#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_ENDTFD      (0x00400000)
+#define FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_IFTFD       (0x00800000)
 
-#define FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM      (20)
-#define FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX      (12)
-#define FH_TCSR_CHNL_TX_CONFIG_REG(_chnl) \
-       (FH_TCSR_LOWER_BOUND + 0x20 * _chnl)
-#define FH_TCSR_CHNL_TX_CREDIT_REG(_chnl) \
-         (FH_TCSR_LOWER_BOUND + 0x20 * _chnl + 0x4)
-#define FH_TCSR_CHNL_TX_BUF_STS_REG(_chnl) \
-        (FH_TCSR_LOWER_BOUND + 0x20 * _chnl + 0x8)
+#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE       (0x00000000)
+#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE_EOF   (0x40000000)
+#define FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE      (0x80000000)
+
+#define FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_EMPTY     (0x00000000)
+#define FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_WAIT      (0x00002000)
+#define FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID     (0x00000003)
+
+#define FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM         (20)
+#define FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX         (12)
 
 /**
  * Tx Shared Status Registers (TSSR)
 #define FH_TSSR_LOWER_BOUND            (FH_MEM_LOWER_BOUND + 0xEA0)
 #define FH_TSSR_UPPER_BOUND            (FH_MEM_LOWER_BOUND + 0xEC0)
 
-#define FH_TSSR_TX_STATUS_REG  (FH_TSSR_LOWER_BOUND + 0x010)
+#define FH_TSSR_TX_STATUS_REG          (FH_TSSR_LOWER_BOUND + 0x010)
 
 #define FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) ((1 << (_chnl)) << 24)
 #define FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl) ((1 << (_chnl)) << 16)
 /* TCSR: tx_config register values */
 #define FH_RSCSR_FRAME_SIZE_MSK        (0x00003FFF)    /* bits 0-13 */
 
+#define TFD_QUEUE_SIZE_MAX      (256)
+#define TFD_QUEUE_SIZE_BC_DUP  (64)
+#define TFD_QUEUE_BC_SIZE      (TFD_QUEUE_SIZE_MAX + TFD_QUEUE_SIZE_BC_DUP)
+
+
+#endif /* !__iwl_fh_h__ */
index 41eed67933289c6f732dfd08892a229cd369d8ef..4f0fa215d32e2fa56a08cbd27f1d1c7ef496ae62 100644 (file)
 
 #include <linux/ctype.h>
 
-/*
- * The structures defined by the hardware/uCode interface
- * have bit-wise operations.  For each bit-field there is
- * a data symbol in the structure, the start bit position
- * and the length of the bit-field.
- *
- * iwl_get_bits and iwl_set_bits will return or set the
- * appropriate bits on a 32-bit value.
- *
- * IWL_GET_BITS and IWL_SET_BITS use symbol expansion to
- * expand out to the appropriate call to iwl_get_bits
- * and iwl_set_bits without having to reference all of the
- * numerical constants and defines provided in the hardware
- * definition
- */
-
-/**
- * iwl_get_bits - Extract a hardware bit-field value
- * @src: source hardware value (__le32)
- * @pos: bit-position (0-based) of first bit of value
- * @len: length of bit-field
- *
- * iwl_get_bits will return the bit-field in cpu endian ordering.
- *
- * NOTE:  If used from IWL_GET_BITS then pos and len are compile-constants and
- *        will collapse to minimal code by the compiler.
- */
-static inline u32 iwl_get_bits(__le32 src, u8 pos, u8 len)
-{
-       u32 tmp = le32_to_cpu(src);
-
-       tmp >>= pos;
-       tmp &= (1UL << len) - 1;
-       return tmp;
-}
-
-/**
- * iwl_set_bits - Set a hardware bit-field value
- * @dst: Address of __le32 hardware value
- * @pos: bit-position (0-based) of first bit of value
- * @len: length of bit-field
- * @val: cpu endian value to encode into the bit-field
- *
- * iwl_set_bits will encode val into dst, masked to be len bits long at bit
- * position pos.
- *
- * NOTE:  If used IWL_SET_BITS pos and len will be compile-constants and
- *        will collapse to minimal code by the compiler.
- */
-static inline void iwl_set_bits(__le32 *dst, u8 pos, u8 len, int val)
-{
-       u32 tmp = le32_to_cpu(*dst);
-
-       tmp &= ~(((1UL << len) - 1) << pos);
-       tmp |= (val & ((1UL << len) - 1)) << pos;
-       *dst = cpu_to_le32(tmp);
-}
-
-static inline void iwl_set_bits16(__le16 *dst, u8 pos, u8 len, int val)
-{
-       u16 tmp = le16_to_cpu(*dst);
-
-       tmp &= ~((1UL << (pos + len)) - (1UL << pos));
-       tmp |= (val & ((1UL << len) - 1)) << pos;
-       *dst = cpu_to_le16(tmp);
-}
-
-/*
- * The bit-field definitions in iwl-xxxx-hw.h are in the form of:
- *
- * struct example {
- *         __le32 val1;
- * #define IWL_name_POS 8
- * #define IWL_name_LEN 4
- * #define IWL_name_SYM val1
- * };
- *
- * The IWL_SET_BITS and IWL_GET_BITS macros are provided to allow the driver
- * to call:
- *
- * struct example bar;
- * u32 val = IWL_GET_BITS(bar, name);
- * val = val * 2;
- * IWL_SET_BITS(bar, name, val);
- *
- * All cpu / host ordering, masking, and shifts are performed by the macros
- * and iwl_{get,set}_bits.
- *
- */
-#define IWL_SET_BITS(s, sym, v) \
-       iwl_set_bits(&(s).IWL_ ## sym ## _SYM, IWL_ ## sym ## _POS, \
-                    IWL_ ## sym ## _LEN, (v))
-
-#define IWL_SET_BITS16(s, sym, v) \
-       iwl_set_bits16(&(s).IWL_ ## sym ## _SYM, IWL_ ## sym ## _POS, \
-                      IWL_ ## sym ## _LEN, (v))
-
-#define IWL_GET_BITS(s, sym) \
-       iwl_get_bits((s).IWL_ ## sym ## _SYM, IWL_ ## sym ## _POS, \
-                     IWL_ ## sym ## _LEN)
-
-
 #define KELVIN_TO_CELSIUS(x) ((x)-273)
 #define CELSIUS_TO_KELVIN(x) ((x)+273)
 #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
@@ -159,11 +57,6 @@ static inline unsigned long elapsed_jiffies(unsigned long start,
        return end + (MAX_JIFFY_OFFSET - start) + 1;
 }
 
-static inline u8 iwl_get_dma_hi_address(dma_addr_t addr)
-{
-       return sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0;
-}
-
 /**
  * iwl_queue_inc_wrap - increment queue index, wrap back to beginning
  * @index -- current index
index 9740fcc1805e7eb27f99ed6fd3ccd711aadcccf2..40e0050b753695f776db88bc660a7606e795356c 100644 (file)
@@ -55,7 +55,7 @@
  * _iwl_read32.)
  *
  * These declarations are *extremely* useful in quickly isolating code deltas
- * which result in misconfiguring of the hardware I/O.  In combination with
+ * which result in misconfiguration of the hardware I/O.  In combination with
  * git-bisect and the IO debug level you can quickly determine the specific
  * commit which breaks the IO sequence to the hardware.
  *
index 4eee1b163cd2c27115fa46ce95cc9cc0193011dc..ffb428a7dd6d9a65423da3a8f8bfb5771b3a8a79 100644 (file)
@@ -278,7 +278,7 @@ static int iwl_get_blink_rate(struct iwl_priv *priv)
        /* FIXME: + priv->rx_stats[2].bytes; */
        s64 tpt = current_tpt - priv->led_tpt;
 
-       if (tpt < 0) /* wrapparound */
+       if (tpt < 0) /* wraparound */
                tpt = -tpt;
 
        IWL_DEBUG_LED("tpt %lld current_tpt %llu\n",
index 60a03d2d2d0e451bc4f56a742b50b99d48a2b5dc..07a5f60e9229801c59b826173b5786ffee177bea 100644 (file)
@@ -80,7 +80,7 @@
 #define IWL_REDUCED_POWER_TEMPERATURE  95
 
 /* default power management (not Tx power) table values */
-/* for tim  0-10 */
+/* for TIM  0-10 */
 static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = {
        {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
        {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
@@ -91,7 +91,7 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = {
 };
 
 
-/* for tim = 3-10 */
+/* for TIM = 3-10 */
 static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = {
        {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
        {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
@@ -101,7 +101,7 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = {
        {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2}
 };
 
-/* for tim > 11 */
+/* for TIM > 11 */
 static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = {
        {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
        {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
@@ -183,7 +183,7 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
        return 0;
 }
 
-/* adjust power command according to dtim period and power level*/
+/* adjust power command according to DTIM period and power level*/
 static int iwl_update_power_command(struct iwl_priv *priv,
                                    struct iwl_powertable_cmd *cmd,
                                    u16 mode)
@@ -325,7 +325,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
 EXPORT_SYMBOL(iwl_power_update_mode);
 
 /* Allow other iwl code to disable/enable power management active
- * this will be usefull for rate scale to disable PM during heavy
+ * this will be useful for rate scale to disable PM during heavy
  * Tx/Rx activities
  */
 int iwl_power_disable_management(struct iwl_priv *priv, u32 ms)
@@ -352,8 +352,8 @@ int iwl_power_disable_management(struct iwl_priv *priv, u32 ms)
 EXPORT_SYMBOL(iwl_power_disable_management);
 
 /* Allow other iwl code to disable/enable power management active
- * this will be usefull for rate scale to disable PM during hight
- * valume activities
+ * this will be useful for rate scale to disable PM during high
+ * volume activities
  */
 int iwl_power_enable_management(struct iwl_priv *priv)
 {
@@ -391,7 +391,7 @@ int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode)
 }
 EXPORT_SYMBOL(iwl_power_set_system_mode);
 
-/* initilize to default */
+/* initialize to default */
 void iwl_power_initialize(struct iwl_priv *priv)
 {
 
@@ -443,7 +443,7 @@ static void iwl_bg_set_power_save(struct work_struct *work)
 
        mutex_lock(&priv->mutex);
 
-       /* on starting association we disable power managment
+       /* on starting association we disable power management
         * until association, if association failed then this
         * timer will expire and enable PM again.
         */
index ee5afd48d3af035ed22527c29c1b98264216077d..b0ffb8919d3b44f39f9535b0f10deb9a44480289 100644 (file)
  *
  * 4)  Point (via BSM_DRAM_*) to the "runtime" uCode data and instruction
  *     images in host DRAM.  The last register loaded must be the instruction
- *     bytecount register ("1" in MSbit tells initialization uCode to load
+ *     byte count register ("1" in MSbit tells initialization uCode to load
  *     the runtime uCode):
- *     BSM_DRAM_INST_BYTECOUNT_REG = bytecount | BSM_DRAM_INST_LOAD
+ *     BSM_DRAM_INST_BYTECOUNT_REG = byte count | BSM_DRAM_INST_LOAD
  *
  * 5)  Wait for "alive" notification, then issue normal runtime commands.
  *
 /**
  * Tx Scheduler
  *
- * The Tx Scheduler selects the next frame to be transmitted, chosing TFDs
+ * The Tx Scheduler selects the next frame to be transmitted, choosing TFDs
  * (Transmit Frame Descriptors) from up to 16 circular Tx queues resident in
  * host DRAM.  It steers each frame's Tx command (which contains the frame
  * data) into one of up to 7 prioritized Tx DMA FIFO channels within the
index 5d642298f04c33014c896e5cec97d143a38f1b66..618841a53b9014f7dc5a92fa6da9b020086f9083 100644 (file)
@@ -64,7 +64,7 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
                iwl_radio_kill_sw_disable_radio(priv);
                break;
        default:
-               IWL_WARNING("we recieved unexpected RFKILL state %d\n", state);
+               IWL_WARNING("we received unexpected RFKILL state %d\n", state);
                break;
        }
 out_unlock:
@@ -83,7 +83,7 @@ int iwl_rfkill_init(struct iwl_priv *priv)
        IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
        priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
        if (!priv->rfkill) {
-               IWL_ERROR("Unable to allocate rfkill device.\n");
+               IWL_ERROR("Unable to allocate RFKILL device.\n");
                ret = -ENOMEM;
                goto error;
        }
@@ -99,7 +99,7 @@ int iwl_rfkill_init(struct iwl_priv *priv)
 
        ret = rfkill_register(priv->rfkill);
        if (ret) {
-               IWL_ERROR("Unable to register rfkill: %d\n", ret);
+               IWL_ERROR("Unable to register RFKILL: %d\n", ret);
                goto free_rfkill;
        }
 
@@ -127,7 +127,7 @@ void iwl_rfkill_unregister(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_rfkill_unregister);
 
-/* set rf-kill to the right state. */
+/* set RFKILL to the right state. */
 void iwl_rfkill_set_hw_state(struct iwl_priv *priv)
 {
        if (!priv->rfkill)
index 7cde9d76ff5df438b335996f1b602cf4e14dd9dc..b86f9586acdee5171fc2f1d0c3c95666ab0c89f4 100644 (file)
@@ -407,7 +407,7 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
                           (priv->shared_phys + priv->rb_closed_offset) >> 4);
 
        /* Enable Rx DMA
-        * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set becuase of HW bug in
+        * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
         *      the credit mechanism in 5000 HW RX FIFO
         * Direct rx interrupts to hosts
         * Rx buffer size 4 or 8k
@@ -1149,7 +1149,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
                priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
 
        /* Set "1" to report good data frames in groups of 100 */
-       /* FIXME: need to optimze the call: */
+       /* FIXME: need to optimize the call: */
        iwl_dbg_report_frame(priv, pkt, header, 1);
 
        IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n",
@@ -1160,12 +1160,12 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
         * "antenna number"
         *
         * It seems that the antenna field in the phy flags value
-        * is actually a bitfield. This is undefined by radiotap,
+        * is actually a bit field. This is undefined by radiotap,
         * it wants an actual antenna number but I always get "7"
         * for most legacy frames I receive indicating that the
         * same frame was received on all three RX chains.
         *
-        * I think this field should be removed in favour of a
+        * I think this field should be removed in favor of a
         * new 802.11n radiotap field "RX chains" that is defined
         * as a bitmask.
         */
index c89365e2ca58e3f4c5d142e9f9d11ed75d7642cc..c4b90301e9a12c1337322eee9530b0342cd68e3f 100644 (file)
  * Tomas Winkler <tomas.winkler@intel.com>
  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  *****************************************************************************/
-#include <net/mac80211.h>
+#include <linux/types.h>
 #include <linux/etherdevice.h>
+#include <net/lib80211.h>
+#include <net/mac80211.h>
 
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
 #define IWL_SCAN_PROBE_MASK(n)         cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
 
 
-static int scan_tx_ant[3] = {
-       RATE_MCS_ANT_A_MSK, RATE_MCS_ANT_B_MSK, RATE_MCS_ANT_C_MSK
-};
-
-
-
-static int iwl_is_empty_essid(const char *essid, int essid_len)
-{
-       /* Single white space is for Linksys APs */
-       if (essid_len == 1 && essid[0] == ' ')
-               return 1;
-
-       /* Otherwise, if the entire essid is 0, we assume it is hidden */
-       while (essid_len) {
-               essid_len--;
-               if (essid[essid_len] != '\0')
-                       return 0;
-       }
-
-       return 1;
-}
-
-
-
-static const char *iwl_escape_essid(const char *essid, u8 essid_len)
-{
-       static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
-       const char *s = essid;
-       char *d = escaped;
-
-       if (iwl_is_empty_essid(essid, essid_len)) {
-               memcpy(escaped, "<hidden>", sizeof("<hidden>"));
-               return escaped;
-       }
-
-       essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
-       while (essid_len--) {
-               if (*s == '\0') {
-                       *d++ = '\\';
-                       *d++ = '0';
-                       s++;
-               } else
-                       *d++ = *s++;
-       }
-       *d = '\0';
-       return escaped;
-}
-
 /**
  * iwl_scan_cancel - Cancel any currently executing HW scan
  *
@@ -455,10 +409,11 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
 
 void iwl_init_scan_params(struct iwl_priv *priv)
 {
+       u8 ant_idx = fls(priv->hw_params.valid_tx_ant) - 1;
        if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ])
-               priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = RATE_MCS_ANT_INIT_IND;
+               priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = ant_idx;
        if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ])
-               priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = RATE_MCS_ANT_INIT_IND;
+               priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx;
 }
 
 int iwl_scan_initiate(struct iwl_priv *priv)
@@ -550,7 +505,7 @@ static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
 {
        struct ieee80211_ht_cap *ht_cap;
 
-       if (!sband || !sband->ht_info.ht_supported)
+       if (!sband || !sband->ht_cap.ht_supported)
                return;
 
        if (*left < sizeof(struct ieee80211_ht_cap))
@@ -559,12 +514,12 @@ static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
        *pos++ = sizeof(struct ieee80211_ht_cap);
        ht_cap = (struct ieee80211_ht_cap *) pos;
 
-       ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap);
-       memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16);
+       ht_cap->cap_info = cpu_to_le16(sband->ht_cap.cap);
+       memcpy(&ht_cap->mcs, &sband->ht_cap.mcs, 16);
        ht_cap->ampdu_params_info =
-               (sband->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) |
-               ((sband->ht_info.ampdu_density << 2) &
-                       IEEE80211_HT_CAP_AMPDU_DENSITY);
+               (sband->ht_cap.ampdu_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) |
+               ((sband->ht_cap.ampdu_density << 2) &
+                       IEEE80211_HT_AMPDU_PARM_DENSITY);
        *left -= sizeof(struct ieee80211_ht_cap);
 }
 
@@ -670,23 +625,6 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
        return (u16)len;
 }
 
-static u32 iwl_scan_tx_ant(struct iwl_priv *priv, enum ieee80211_band band)
-{
-       int i, ind;
-
-       ind = priv->scan_tx_ant[band];
-       for (i = 0; i < priv->hw_params.tx_chains_num; i++) {
-               ind = (ind+1) >= priv->hw_params.tx_chains_num ? 0 : ind+1;
-               if (priv->hw_params.valid_tx_ant & (1 << ind)) {
-                       priv->scan_tx_ant[band] = ind;
-                       break;
-               }
-       }
-       IWL_DEBUG_SCAN("select TX ANT = %c\n", 'A' + ind);
-       return scan_tx_ant[ind];
-}
-
-
 static void iwl_bg_request_scan(struct work_struct *data)
 {
        struct iwl_priv *priv =
@@ -699,11 +637,13 @@ static void iwl_bg_request_scan(struct work_struct *data)
        struct iwl_scan_cmd *scan;
        struct ieee80211_conf *conf = NULL;
        int ret = 0;
-       u32 tx_ant;
+       u32 rate_flags = 0;
        u16 cmd_len;
        enum ieee80211_band band;
        u8 n_probes = 2;
        u8 rx_chain = priv->hw_params.valid_rx_ant;
+       u8 rate;
+       DECLARE_SSID_BUF(ssid);
 
        conf = ieee80211_get_hw_conf(priv->hw);
 
@@ -714,7 +654,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
                goto done;
        }
 
-       /* Make sure the scan wasn't cancelled before this queued work
+       /* Make sure the scan wasn't canceled before this queued work
         * was given the chance to run... */
        if (!test_bit(STATUS_SCANNING, &priv->status))
                goto done;
@@ -796,20 +736,13 @@ static void iwl_bg_request_scan(struct work_struct *data)
        /* We should add the ability for user to lock to PASSIVE ONLY */
        if (priv->one_direct_scan) {
                IWL_DEBUG_SCAN("Start direct scan for '%s'\n",
-                               iwl_escape_essid(priv->direct_ssid,
-                               priv->direct_ssid_len));
+                               print_ssid(ssid, priv->direct_ssid,
+                                          priv->direct_ssid_len));
                scan->direct_scan[0].id = WLAN_EID_SSID;
                scan->direct_scan[0].len = priv->direct_ssid_len;
                memcpy(scan->direct_scan[0].ssid,
                       priv->direct_ssid, priv->direct_ssid_len);
                n_probes++;
-       } else if (!iwl_is_associated(priv) && priv->essid_len) {
-               IWL_DEBUG_SCAN("Start direct scan for '%s' (not associated)\n",
-                               iwl_escape_essid(priv->essid, priv->essid_len));
-               scan->direct_scan[0].id = WLAN_EID_SSID;
-               scan->direct_scan[0].len = priv->essid_len;
-               memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
-               n_probes++;
        } else {
                IWL_DEBUG_SCAN("Start indirect scan.\n");
        }
@@ -822,23 +755,16 @@ static void iwl_bg_request_scan(struct work_struct *data)
        if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
                band = IEEE80211_BAND_2GHZ;
                scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
-               tx_ant = iwl_scan_tx_ant(priv, band);
-               if (priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK)
-                       scan->tx_cmd.rate_n_flags =
-                               iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
-                                                       tx_ant);
-               else
-                       scan->tx_cmd.rate_n_flags =
-                               iwl_hw_set_rate_n_flags(IWL_RATE_1M_PLCP,
-                                                       tx_ant |
-                                                       RATE_MCS_CCK_MSK);
+               if (priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) {
+                       rate = IWL_RATE_6M_PLCP;
+               } else {
+                       rate = IWL_RATE_1M_PLCP;
+                       rate_flags = RATE_MCS_CCK_MSK;
+               }
                scan->good_CRC_th = 0;
        } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
                band = IEEE80211_BAND_5GHZ;
-               tx_ant = iwl_scan_tx_ant(priv, band);
-               scan->tx_cmd.rate_n_flags =
-                               iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
-                                                       tx_ant);
+               rate = IWL_RATE_6M_PLCP;
                scan->good_CRC_th = IWL_GOOD_CRC_TH;
 
                /* Force use of chains B and C (0x6) for scan Rx for 4965
@@ -851,6 +777,11 @@ static void iwl_bg_request_scan(struct work_struct *data)
                goto done;
        }
 
+       priv->scan_tx_ant[band] =
+                        iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band]);
+       rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
+       scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
+
        /* MIMO is not used here, but value is required */
        scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK |
                                cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) |
index 61797f3f8d5c9a475b85d7fb980fe6a16dbb804a..0c5f1221b8f3ef7f4a7b655a592d3457c42fa4b1 100644 (file)
@@ -45,7 +45,6 @@ u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
        int start = 0;
        int ret = IWL_INVALID_STATION;
        unsigned long flags;
-       DECLARE_MAC_BUF(mac);
 
        if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) ||
            (priv->iw_mode == NL80211_IFTYPE_AP))
@@ -63,8 +62,8 @@ u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
                        goto out;
                }
 
-       IWL_DEBUG_ASSOC_LIMIT("can not find STA %s total %d\n",
-                             print_mac(mac, addr), priv->num_stations);
+       IWL_DEBUG_ASSOC_LIMIT("can not find STA %pM total %d\n",
+                             addr, priv->num_stations);
 
  out:
        spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -86,7 +85,6 @@ EXPORT_SYMBOL(iwl_get_ra_sta_id);
 static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
 {
        unsigned long flags;
-       DECLARE_MAC_BUF(mac);
 
        spin_lock_irqsave(&priv->sta_lock, flags);
 
@@ -94,8 +92,8 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
                IWL_ERROR("ACTIVATE a non DRIVER active station %d\n", sta_id);
 
        priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
-       IWL_DEBUG_ASSOC("Added STA to Ucode: %s\n",
-                       print_mac(mac, priv->stations[sta_id].sta.sta.addr));
+       IWL_DEBUG_ASSOC("Added STA to Ucode: %pM\n",
+                       priv->stations[sta_id].sta.sta.addr);
 
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 }
@@ -104,7 +102,9 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
                                   struct iwl_cmd *cmd, struct sk_buff *skb)
 {
        struct iwl_rx_packet *res = NULL;
-       u8 sta_id = cmd->cmd.addsta.sta.sta_id;
+       struct iwl_addsta_cmd *addsta =
+               (struct iwl_addsta_cmd *)cmd->cmd.payload;
+       u8 sta_id = addsta->sta.sta_id;
 
        if (!skb) {
                IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n");
@@ -183,7 +183,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
 EXPORT_SYMBOL(iwl_send_add_sta);
 
 static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
-                                  struct ieee80211_ht_info *sta_ht_inf)
+                                  struct ieee80211_sta_ht_cap *sta_ht_inf)
 {
        __le32 sta_flags;
        u8 mimo_ps_mode;
@@ -231,13 +231,12 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
  * iwl_add_station_flags - Add station to tables in driver and device
  */
 u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
-                        u8 flags, struct ieee80211_ht_info *ht_info)
+                        u8 flags, struct ieee80211_sta_ht_cap *ht_info)
 {
        int i;
        int sta_id = IWL_INVALID_STATION;
        struct iwl_station_entry *station;
        unsigned long flags_spin;
-       DECLARE_MAC_BUF(mac);
 
        spin_lock_irqsave(&priv->sta_lock, flags_spin);
        if (is_ap)
@@ -273,8 +272,8 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
 
        station = &priv->stations[sta_id];
        station->used = IWL_STA_DRIVER_ACTIVE;
-       IWL_DEBUG_ASSOC("Add STA to driver ID %d: %s\n",
-                       sta_id, print_mac(mac, addr));
+       IWL_DEBUG_ASSOC("Add STA to driver ID %d: %pM\n",
+                       sta_id, addr);
        priv->num_stations++;
 
        /* Set up the REPLY_ADD_STA command to send to device */
@@ -301,14 +300,11 @@ EXPORT_SYMBOL(iwl_add_station_flags);
 static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
 {
        unsigned long flags;
-       DECLARE_MAC_BUF(mac);
-
        u8 sta_id = iwl_find_station(priv, addr);
 
        BUG_ON(sta_id == IWL_INVALID_STATION);
 
-       IWL_DEBUG_ASSOC("Removed STA from Ucode: %s\n",
-                       print_mac(mac, addr));
+       IWL_DEBUG_ASSOC("Removed STA from Ucode: %pM\n", addr);
 
        spin_lock_irqsave(&priv->sta_lock, flags);
 
@@ -326,7 +322,9 @@ static int iwl_remove_sta_callback(struct iwl_priv *priv,
                                   struct iwl_cmd *cmd, struct sk_buff *skb)
 {
        struct iwl_rx_packet *res = NULL;
-       const char *addr = cmd->cmd.rm_sta.addr;
+       struct iwl_rem_sta_cmd *rm_sta =
+                (struct iwl_rem_sta_cmd *)cmd->cmd.payload;
+       const char *addr = rm_sta->addr;
 
        if (!skb) {
                IWL_ERROR("Error: Response NULL in REPLY_REMOVE_STA.\n");
@@ -415,7 +413,6 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
        int sta_id = IWL_INVALID_STATION;
        int i, ret = -EINVAL;
        unsigned long flags;
-       DECLARE_MAC_BUF(mac);
 
        spin_lock_irqsave(&priv->sta_lock, flags);
 
@@ -435,18 +432,18 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
        if (unlikely(sta_id == IWL_INVALID_STATION))
                goto out;
 
-       IWL_DEBUG_ASSOC("Removing STA from driver:%d  %s\n",
-               sta_id, print_mac(mac, addr));
+       IWL_DEBUG_ASSOC("Removing STA from driver:%d  %pM\n",
+               sta_id, addr);
 
        if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
-               IWL_ERROR("Removing %s but non DRIVER active\n",
-                               print_mac(mac, addr));
+               IWL_ERROR("Removing %pM but non DRIVER active\n",
+                               addr);
                goto out;
        }
 
        if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
-               IWL_ERROR("Removing %s but non UCODE active\n",
-                               print_mac(mac, addr));
+               IWL_ERROR("Removing %pM but non UCODE active\n",
+                               addr);
                goto out;
        }
 
@@ -696,7 +693,7 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
        /* else, we are overriding an existing key => no need to allocated room
         * in uCode. */
 
-       /* This copy is acutally not needed: we get the key with each TX */
+       /* This copy is actually not needed: we get the key with each TX */
        memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
 
        memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16);
@@ -791,7 +788,7 @@ static void iwl_dump_lq_cmd(struct iwl_priv *priv,
 {
        int i;
        IWL_DEBUG_RATE("lq station id 0x%x\n", lq->sta_id);
-       IWL_DEBUG_RATE("lq dta 0x%X 0x%X\n",
+       IWL_DEBUG_RATE("lq ant 0x%X 0x%X\n",
                       lq->general_params.single_stream_ant_msk,
                       lq->general_params.dual_stream_ant_msk);
 
@@ -852,7 +849,7 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
        struct iwl_link_quality_cmd link_cmd = {
                .reserved1 = 0,
        };
-       u16 rate_flags;
+       u32 rate_flags;
 
        /* Set up the rate scaling to start at selected rate, fall back
         * all the way down to 1M in IEEE order, and then spin on 1M */
@@ -868,15 +865,16 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
                if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
                        rate_flags |= RATE_MCS_CCK_MSK;
 
-               /* Use Tx antenna B only */
-               rate_flags |= RATE_MCS_ANT_B_MSK; /*FIXME:RS*/
+               rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
+                               RATE_MCS_ANT_POS;
 
                link_cmd.rs_table[i].rate_n_flags =
                        iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
-               r = iwl4965_get_prev_ieee_rate(r);
+               r = iwl_get_prev_ieee_rate(r);
        }
 
-       link_cmd.general_params.single_stream_ant_msk = 2;
+       link_cmd.general_params.single_stream_ant_msk =
+                               first_antenna(priv->hw_params.valid_tx_ant);
        link_cmd.general_params.dual_stream_ant_msk = 3;
        link_cmd.agg_params.agg_dis_start_th = 3;
        link_cmd.agg_params.agg_time_limit = cpu_to_le16(4000);
@@ -892,24 +890,35 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
  * iwl_rxon_add_station - add station into station table.
  *
  * there is only one AP station with id= IWL_AP_ID
- * NOTE: mutex must be held before calling this fnction
+ * NOTE: mutex must be held before calling this function
  */
 int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
 {
+       struct ieee80211_sta *sta;
+       struct ieee80211_sta_ht_cap ht_config;
+       struct ieee80211_sta_ht_cap *cur_ht_config = NULL;
        u8 sta_id;
 
        /* Add station to device's station table */
-       struct ieee80211_conf *conf = &priv->hw->conf;
-       struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf;
-
-       if ((is_ap) &&
-           (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) &&
-           (priv->iw_mode == NL80211_IFTYPE_STATION))
-               sta_id = iwl_add_station_flags(priv, addr, is_ap,
-                                                  0, cur_ht_config);
-       else
-               sta_id = iwl_add_station_flags(priv, addr, is_ap,
-                                                  0, NULL);
+
+       /*
+        * XXX: This check is definitely not correct, if we're an AP
+        *      it'll always be false which is not what we want, but
+        *      it doesn't look like iwlagn is prepared to be an HT
+        *      AP anyway.
+        */
+       if (priv->current_ht_config.is_ht) {
+               rcu_read_lock();
+               sta = ieee80211_find_sta(priv->hw, addr);
+               if (sta) {
+                       memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config));
+                       cur_ht_config = &ht_config;
+               }
+               rcu_read_unlock();
+       }
+
+       sta_id = iwl_add_station_flags(priv, addr, is_ap,
+                                      0, cur_ht_config);
 
        /* Set up default rate scaling table in device's station table */
        iwl_sta_init_lq(priv, addr, is_ap);
@@ -927,7 +936,6 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
 {
        int sta_id;
        u16 fc = le16_to_cpu(hdr->frame_control);
-       DECLARE_MAC_BUF(mac);
 
        /* If this frame is broadcast or management, use broadcast station id */
        if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
@@ -962,9 +970,9 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
                if (sta_id != IWL_INVALID_STATION)
                        return sta_id;
 
-               IWL_DEBUG_DROP("Station %s not in station map. "
+               IWL_DEBUG_DROP("Station %pM not in station map. "
                               "Defaulting to broadcast...\n",
-                              print_mac(mac, hdr->addr1));
+                              hdr->addr1);
                iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
                return priv->hw_params.bcast_sta_id;
 
index 907a53ebc6e4dc62fc7a5226b6706af72d1e0d85..7d8b4e2d509473cad53300ecc2bfab3c3f1b3210 100644 (file)
@@ -56,96 +56,112 @@ static const u16 default_tid_to_tx_fifo[] = {
        IWL_TX_FIFO_AC3
 };
 
+static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
+{
+       struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+
+       dma_addr_t addr = get_unaligned_le32(&tb->lo);
+       if (sizeof(dma_addr_t) > sizeof(u32))
+               addr |=
+               ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
+
+       return addr;
+}
+
+static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
+{
+       struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+
+       return le16_to_cpu(tb->hi_n_len) >> 4;
+}
+
+static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
+                                 dma_addr_t addr, u16 len)
+{
+       struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+       u16 hi_n_len = len << 4;
+
+       put_unaligned_le32(addr, &tb->lo);
+       if (sizeof(dma_addr_t) > sizeof(u32))
+               hi_n_len |= ((addr >> 16) >> 16) & 0xF;
+
+       tb->hi_n_len = cpu_to_le16(hi_n_len);
+
+       tfd->num_tbs = idx + 1;
+}
+
+static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
+{
+       return tfd->num_tbs & 0x1f;
+}
 
 /**
  * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
+ * @priv - driver private data
+ * @txq - tx queue
  *
  * Does NOT advance any TFD circular buffer read/write indexes
  * Does NOT free the TFD itself (which is within circular buffer)
  */
-static int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+static void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
 {
-       struct iwl_tfd_frame *bd_tmp = (struct iwl_tfd_frame *)&txq->bd[0];
-       struct iwl_tfd_frame *bd = &bd_tmp[txq->q.read_ptr];
+       struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)&txq->tfds[0];
+       struct iwl_tfd *tfd;
        struct pci_dev *dev = priv->pci_dev;
+       int index = txq->q.read_ptr;
        int i;
-       int counter = 0;
-       int index, is_odd;
+       int num_tbs;
 
-       /* Host command buffers stay mapped in memory, nothing to clean */
-       if (txq->q.id == IWL_CMD_QUEUE_NUM)
-               return 0;
+       tfd = &tfd_tmp[index];
 
        /* Sanity check on number of chunks */
-       counter = IWL_GET_BITS(*bd, num_tbs);
-       if (counter > MAX_NUM_OF_TBS) {
-               IWL_ERROR("Too many chunks: %i\n", counter);
+       num_tbs = iwl_tfd_get_num_tbs(tfd);
+
+       if (num_tbs >= IWL_NUM_OF_TBS) {
+               IWL_ERROR("Too many chunks: %i\n", num_tbs);
                /* @todo issue fatal error, it is quite serious situation */
-               return 0;
+               return;
        }
 
-       /* Unmap chunks, if any.
-        * TFD info for odd chunks is different format than for even chunks. */
-       for (i = 0; i < counter; i++) {
-               index = i / 2;
-               is_odd = i & 0x1;
-
-               if (is_odd)
-                       pci_unmap_single(
-                               dev,
-                               IWL_GET_BITS(bd->pa[index], tb2_addr_lo16) |
-                               (IWL_GET_BITS(bd->pa[index],
-                                             tb2_addr_hi20) << 16),
-                               IWL_GET_BITS(bd->pa[index], tb2_len),
+       /* Unmap tx_cmd */
+       if (num_tbs)
+               pci_unmap_single(dev,
+                               pci_unmap_addr(&txq->cmd[index]->meta, mapping),
+                               pci_unmap_len(&txq->cmd[index]->meta, len),
                                PCI_DMA_TODEVICE);
 
-               else if (i > 0)
-                       pci_unmap_single(dev,
-                                        le32_to_cpu(bd->pa[index].tb1_addr),
-                                        IWL_GET_BITS(bd->pa[index], tb1_len),
-                                        PCI_DMA_TODEVICE);
-
-               /* Free SKB, if any, for this chunk */
-               if (txq->txb[txq->q.read_ptr].skb[i]) {
-                       struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[i];
+       /* Unmap chunks, if any. */
+       for (i = 1; i < num_tbs; i++) {
+               pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
+                               iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);
 
-                       dev_kfree_skb(skb);
-                       txq->txb[txq->q.read_ptr].skb[i] = NULL;
+               if (txq->txb) {
+                       dev_kfree_skb(txq->txb[txq->q.read_ptr].skb[i - 1]);
+                       txq->txb[txq->q.read_ptr].skb[i - 1] = NULL;
                }
        }
-       return 0;
 }
 
-static int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
-                                dma_addr_t addr, u16 len)
+static int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+                                       struct iwl_tfd *tfd,
+                                       dma_addr_t addr, u16 len)
 {
-       int index, is_odd;
-       struct iwl_tfd_frame *tfd = ptr;
-       u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs);
+
+       u32 num_tbs = iwl_tfd_get_num_tbs(tfd);
 
        /* Each TFD can point to a maximum 20 Tx buffers */
-       if (num_tbs >= MAX_NUM_OF_TBS) {
+       if (num_tbs >= IWL_NUM_OF_TBS) {
                IWL_ERROR("Error can not send more than %d chunks\n",
-                         MAX_NUM_OF_TBS);
+                         IWL_NUM_OF_TBS);
                return -EINVAL;
        }
 
-       index = num_tbs / 2;
-       is_odd = num_tbs & 0x1;
-
-       if (!is_odd) {
-               tfd->pa[index].tb1_addr = cpu_to_le32(addr);
-               IWL_SET_BITS(tfd->pa[index], tb1_addr_hi,
-                            iwl_get_dma_hi_address(addr));
-               IWL_SET_BITS(tfd->pa[index], tb1_len, len);
-       } else {
-               IWL_SET_BITS(tfd->pa[index], tb2_addr_lo16,
-                            (u32) (addr & 0xffff));
-               IWL_SET_BITS(tfd->pa[index], tb2_addr_hi20, addr >> 16);
-               IWL_SET_BITS(tfd->pa[index], tb2_len, len);
-       }
+       BUG_ON(addr & ~DMA_BIT_MASK(36));
+       if (unlikely(addr & ~IWL_TX_DMA_MASK))
+               IWL_ERROR("Unaligned address = %llx\n",
+                         (unsigned long long)addr);
 
-       IWL_SET_BITS(*tfd, num_tbs, num_tbs + 1);
+       iwl_tfd_set_tb(tfd, num_tbs, addr, len);
 
        return 0;
 }
@@ -210,7 +226,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
        struct iwl_tx_queue *txq = &priv->txq[txq_id];
        struct iwl_queue *q = &txq->q;
        struct pci_dev *dev = priv->pci_dev;
-       int i, slots_num, len;
+       int i, len;
 
        if (q->n_bd == 0)
                return;
@@ -221,21 +237,15 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
                iwl_hw_txq_free_tfd(priv, txq);
 
        len = sizeof(struct iwl_cmd) * q->n_window;
-       if (q->id == IWL_CMD_QUEUE_NUM)
-               len += IWL_MAX_SCAN_SIZE;
 
        /* De-alloc array of command/tx buffers */
-       slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
-                       TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
-       for (i = 0; i < slots_num; i++)
+       for (i = 0; i < TFD_TX_CMD_SLOTS; i++)
                kfree(txq->cmd[i]);
-       if (txq_id == IWL_CMD_QUEUE_NUM)
-               kfree(txq->cmd[slots_num]);
 
        /* De-alloc circular buffer of TFDs */
        if (txq->q.n_bd)
-               pci_free_consistent(dev, sizeof(struct iwl_tfd_frame) *
-                                   txq->q.n_bd, txq->bd, txq->q.dma_addr);
+               pci_free_consistent(dev, sizeof(struct iwl_tfd) *
+                                   txq->q.n_bd, txq->tfds, txq->q.dma_addr);
 
        /* De-alloc array of per-TFD driver data */
        kfree(txq->txb);
@@ -245,6 +255,40 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
        memset(txq, 0, sizeof(*txq));
 }
 
+
+/**
+ * iwl_cmd_queue_free - Deallocate DMA queue.
+ * @txq: Transmit queue to deallocate.
+ *
+ * Empty queue by removing and destroying all BD's.
+ * Free all buffers.
+ * 0-fill, but do not free "txq" descriptor structure.
+ */
+static void iwl_cmd_queue_free(struct iwl_priv *priv)
+{
+       struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
+       struct iwl_queue *q = &txq->q;
+       struct pci_dev *dev = priv->pci_dev;
+       int i, len;
+
+       if (q->n_bd == 0)
+               return;
+
+       len = sizeof(struct iwl_cmd) * q->n_window;
+       len += IWL_MAX_SCAN_SIZE;
+
+       /* De-alloc array of command/tx buffers */
+       for (i = 0; i <= TFD_CMD_SLOTS; i++)
+               kfree(txq->cmd[i]);
+
+       /* De-alloc circular buffer of TFDs */
+       if (txq->q.n_bd)
+               pci_free_consistent(dev, sizeof(struct iwl_tfd) *
+                                   txq->q.n_bd, txq->tfds, txq->q.dma_addr);
+
+       /* 0-fill queue descriptor structure */
+       memset(txq, 0, sizeof(*txq));
+}
 /*************** DMA-QUEUE-GENERAL-FUNCTIONS  *****
  * DMA services
  *
@@ -340,13 +384,13 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
 
        /* Circular buffer of transmit frame descriptors (TFDs),
         * shared with device */
-       txq->bd = pci_alloc_consistent(dev,
-                       sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX,
+       txq->tfds = pci_alloc_consistent(dev,
+                       sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX,
                        &txq->q.dma_addr);
 
-       if (!txq->bd) {
+       if (!txq->tfds) {
                IWL_ERROR("pci_alloc_consistent(%zd) failed\n",
-                         sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX);
+                         sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX);
                goto error;
        }
        txq->q.id = id;
@@ -370,15 +414,15 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
 static int iwl_hw_tx_queue_init(struct iwl_priv *priv,
                                struct iwl_tx_queue *txq)
 {
-       int rc;
+       int ret;
        unsigned long flags;
        int txq_id = txq->q.id;
 
        spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_nic_access(priv);
-       if (rc) {
+       ret = iwl_grab_nic_access(priv);
+       if (ret) {
                spin_unlock_irqrestore(&priv->lock, flags);
-               return rc;
+               return ret;
        }
 
        /* Circular buffer (TFD queue in DRAM) physical base address */
@@ -386,10 +430,10 @@ static int iwl_hw_tx_queue_init(struct iwl_priv *priv,
                             txq->q.dma_addr >> 8);
 
        /* Enable DMA channel, using same id as for TFD queue */
-       iwl_write_direct32(
-               priv, FH_TCSR_CHNL_TX_CONFIG_REG(txq_id),
-               FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
-               FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL);
+       iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(txq_id),
+                       FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
+                       FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
+
        iwl_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -468,7 +512,10 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
 
        /* Tx queues */
        for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
-               iwl_tx_queue_free(priv, txq_id);
+               if (txq_id == IWL_CMD_QUEUE_NUM)
+                       iwl_cmd_queue_free(priv);
+               else
+                       iwl_tx_queue_free(priv, txq_id);
 
        /* Keep-warm buffer */
        iwl_kw_free(priv);
@@ -477,7 +524,7 @@ EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
 
 /**
  * iwl_txq_ctx_reset - Reset TX queue context
- * Destroys all DMA structures and initialise them again
+ * Destroys all DMA structures and initialize them again
  *
  * @param priv
  * @return error code
@@ -647,11 +694,11 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
                              __le16 fc, int sta_id,
                              int is_hcca)
 {
+       u32 rate_flags = 0;
+       int rate_idx;
        u8 rts_retry_limit = 0;
        u8 data_retry_limit = 0;
        u8 rate_plcp;
-       u16 rate_flags = 0;
-       int rate_idx;
 
        rate_idx = min(ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xffff,
                        IWL_RATE_COUNT - 1);
@@ -694,14 +741,8 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
                        break;
                }
 
-               /* Alternate between antenna A and B for successive frames */
-               if (priv->use_ant_b_for_management_frame) {
-                       priv->use_ant_b_for_management_frame = 0;
-                       rate_flags |= RATE_MCS_ANT_B_MSK;
-               } else {
-                       priv->use_ant_b_for_management_frame = 1;
-                       rate_flags |= RATE_MCS_ANT_A_MSK;
-               }
+               priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant);
+               rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
        }
 
        tx_cmd->rts_retry_limit = rts_retry_limit;
@@ -723,7 +764,7 @@ static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
                memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
                if (info->flags & IEEE80211_TX_CTL_AMPDU)
                        tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK;
-               IWL_DEBUG_TX("tx_cmd with aes hwcrypto\n");
+               IWL_DEBUG_TX("tx_cmd with AES hwcrypto\n");
                break;
 
        case ALG_TKIP:
@@ -767,7 +808,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct iwl_tfd_frame *tfd;
+       struct iwl_tfd *tfd;
        struct iwl_tx_queue *txq;
        struct iwl_queue *q;
        struct iwl_cmd *out_cmd;
@@ -776,7 +817,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        dma_addr_t phys_addr;
        dma_addr_t txcmd_phys;
        dma_addr_t scratch_phys;
-       u16 len, idx, len_org;
+       u16 len, len_org;
        u16 seq_number = 0;
        __le16 fc;
        u8 hdr_len, unicast;
@@ -830,10 +871,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        /* Find (or create) index into station table for destination station */
        sta_id = iwl_get_sta_id(priv, hdr);
        if (sta_id == IWL_INVALID_STATION) {
-               DECLARE_MAC_BUF(mac);
-
-               IWL_DEBUG_DROP("Dropping - INVALID STATION: %s\n",
-                              print_mac(mac, hdr->addr1));
+               IWL_DEBUG_DROP("Dropping - INVALID STATION: %pM\n",
+                              hdr->addr1);
                goto drop;
        }
 
@@ -856,23 +895,22 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
                priv->stations[sta_id].tid[tid].tfds_in_queue++;
        }
 
-       /* Descriptor for chosen Tx queue */
        txq = &priv->txq[txq_id];
        q = &txq->q;
+       txq->swq_id = swq_id;
 
        spin_lock_irqsave(&priv->lock, flags);
 
        /* Set up first empty TFD within this queue's circular TFD buffer */
-       tfd = &txq->bd[q->write_ptr];
+       tfd = &txq->tfds[q->write_ptr];
        memset(tfd, 0, sizeof(*tfd));
-       idx = get_cmd_index(q, q->write_ptr, 0);
 
        /* Set up driver data for this TFD */
        memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
        txq->txb[q->write_ptr].skb[0] = skb;
 
        /* Set up first empty entry in queue's array of Tx/cmd buffers */
-       out_cmd = txq->cmd[idx];
+       out_cmd = txq->cmd[q->write_ptr];
        tx_cmd = &out_cmd->cmd.tx;
        memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
        memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd));
@@ -912,12 +950,14 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 
        /* Physical address of this Tx command's header (not MAC header!),
         * within command buffer array. */
-       txcmd_phys = pci_map_single(priv->pci_dev, out_cmd,
-                               sizeof(struct iwl_cmd), PCI_DMA_TODEVICE);
-       txcmd_phys += offsetof(struct iwl_cmd, hdr);
-
+       txcmd_phys = pci_map_single(priv->pci_dev,
+                                   out_cmd, sizeof(struct iwl_cmd),
+                                   PCI_DMA_TODEVICE);
+       pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
+       pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd));
        /* Add buffer containing Tx command and MAC(!) header to TFD's
         * first entry */
+       txcmd_phys += offsetof(struct iwl_cmd, hdr);
        iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
 
        if (info->control.hw_key)
@@ -950,7 +990,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
                offsetof(struct iwl_tx_cmd, scratch);
        tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
-       tx_cmd->dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys);
+       tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
 
        if (!ieee80211_has_morefrags(hdr->frame_control)) {
                txq->need_update = 1;
@@ -983,7 +1023,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
                        iwl_txq_update_write_ptr(priv, txq);
                        spin_unlock_irqrestore(&priv->lock, flags);
                } else {
-                       ieee80211_stop_queue(priv->hw, swq_id);
+                       ieee80211_stop_queue(priv->hw, txq->swq_id);
                }
        }
 
@@ -1011,7 +1051,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 {
        struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
        struct iwl_queue *q = &txq->q;
-       struct iwl_tfd_frame *tfd;
+       struct iwl_tfd *tfd;
        struct iwl_cmd *out_cmd;
        dma_addr_t phys_addr;
        unsigned long flags;
@@ -1040,7 +1080,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 
        spin_lock_irqsave(&priv->hcmd_lock, flags);
 
-       tfd = &txq->bd[q->write_ptr];
+       tfd = &txq->tfds[q->write_ptr];
        memset(tfd, 0, sizeof(*tfd));
 
 
@@ -1061,9 +1101,13 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
                out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
        len = (idx == TFD_CMD_SLOTS) ?
                        IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd);
-       phys_addr = pci_map_single(priv->pci_dev, out_cmd, len,
-                                               PCI_DMA_TODEVICE);
+
+       phys_addr = pci_map_single(priv->pci_dev, out_cmd,
+                                  len, PCI_DMA_TODEVICE);
+       pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr);
+       pci_unmap_len_set(&out_cmd->meta, len, len);
        phys_addr += offsetof(struct iwl_cmd, hdr);
+
        iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -1113,8 +1157,9 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
                return 0;
        }
 
-       for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
-               q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+       for (index = iwl_queue_inc_wrap(index, q->n_bd);
+            q->read_ptr != index;
+            q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
 
                tx_info = &txq->txb[txq->q.read_ptr];
                ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]);
@@ -1138,44 +1183,34 @@ EXPORT_SYMBOL(iwl_tx_queue_reclaim);
  * need to be reclaimed. As result, some free space forms.  If there is
  * enough free space (> low mark), wake the stack that feeds us.
  */
-static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
+static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
+                                  int idx, int cmd_idx)
 {
        struct iwl_tx_queue *txq = &priv->txq[txq_id];
        struct iwl_queue *q = &txq->q;
-       struct iwl_tfd_frame *bd = &txq->bd[index];
-       dma_addr_t dma_addr;
-       int is_odd, buf_len;
        int nfreed = 0;
 
-       if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
+       if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) {
                IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
                          "is out of range [0-%d] %d %d.\n", txq_id,
-                         index, q->n_bd, q->write_ptr, q->read_ptr);
+                         idx, q->n_bd, q->write_ptr, q->read_ptr);
                return;
        }
 
-       for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
-               q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+       pci_unmap_single(priv->pci_dev,
+               pci_unmap_addr(&txq->cmd[cmd_idx]->meta, mapping),
+               pci_unmap_len(&txq->cmd[cmd_idx]->meta, len),
+               PCI_DMA_TODEVICE);
+
+       for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
+            q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
 
-               if (nfreed > 1) {
-                       IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
+               if (nfreed++ > 0) {
+                       IWL_ERROR("HCMD skipped: index (%d) %d %d\n", idx,
                                        q->write_ptr, q->read_ptr);
                        queue_work(priv->workqueue, &priv->restart);
                }
-               is_odd = (index/2) & 0x1;
-               if (is_odd) {
-                       dma_addr = IWL_GET_BITS(bd->pa[index], tb2_addr_lo16) |
-                                       (IWL_GET_BITS(bd->pa[index],
-                                                       tb2_addr_hi20) << 16);
-                       buf_len = IWL_GET_BITS(bd->pa[index], tb2_len);
-               } else {
-                       dma_addr = le32_to_cpu(bd->pa[index].tb1_addr);
-                       buf_len = IWL_GET_BITS(bd->pa[index], tb1_len);
-               }
 
-               pci_unmap_single(priv->pci_dev, dma_addr, buf_len,
-                                PCI_DMA_TODEVICE);
-               nfreed++;
        }
 }
 
@@ -1215,7 +1250,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
                   !cmd->meta.u.callback(priv, cmd, rxb->skb))
                rxb->skb = NULL;
 
-       iwl_hcmd_queue_reclaim(priv, txq_id, index);
+       iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
 
        if (!(cmd->meta.flags & CMD_ASYNC)) {
                clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
@@ -1248,15 +1283,14 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
        int ret;
        unsigned long flags;
        struct iwl_tid_data *tid_data;
-       DECLARE_MAC_BUF(mac);
 
        if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo)))
                tx_fifo = default_tid_to_tx_fifo[tid];
        else
                return -EINVAL;
 
-       IWL_WARNING("%s on ra = %s tid = %d\n",
-                       __func__, print_mac(mac, ra), tid);
+       IWL_WARNING("%s on ra = %pM tid = %d\n",
+                       __func__, ra, tid);
 
        sta_id = iwl_find_station(priv, ra);
        if (sta_id == IWL_INVALID_STATION)
@@ -1301,7 +1335,6 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
        struct iwl_tid_data *tid_data;
        int ret, write_ptr, read_ptr;
        unsigned long flags;
-       DECLARE_MAC_BUF(mac);
 
        if (!ra) {
                IWL_ERROR("ra = NULL\n");
@@ -1362,8 +1395,8 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id)
        case IWL_EMPTYING_HW_QUEUE_DELBA:
                /* We are reclaiming the last packet of the */
                /* aggregated HW queue */
-               if (txq_id  == tid_data->agg.txq_id &&
-                   q->read_ptr == q->write_ptr) {
+               if ((txq_id  == tid_data->agg.txq_id) &&
+                   (q->read_ptr == q->write_ptr)) {
                        u16 ssn = SEQ_TO_SN(tid_data->seq_number);
                        int tx_fifo = default_tid_to_tx_fifo[tid];
                        IWL_DEBUG_HT("HW queue empty: continue DELBA flow\n");
@@ -1414,7 +1447,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
        IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
 
        /* Calculate shift to align block-ack bits with our Tx window bits */
-       sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl>>4);
+       sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4);
        if (sh < 0) /* tbw something is wrong with indices */
                sh += 0x100;
 
@@ -1464,10 +1497,11 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
 {
        struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
        struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
-       int index;
        struct iwl_tx_queue *txq = NULL;
        struct iwl_ht_agg *agg;
-       DECLARE_MAC_BUF(mac);
+       int index;
+       int sta_id;
+       int tid;
 
        /* "flow" corresponds to Tx queue */
        u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
@@ -1482,17 +1516,19 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
        }
 
        txq = &priv->txq[scd_flow];
-       agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg;
+       sta_id = ba_resp->sta_id;
+       tid = ba_resp->tid;
+       agg = &priv->stations[sta_id].tid[tid].agg;
 
        /* Find index just before block-ack window */
        index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
 
        /* TODO: Need to get this copy more safely - now good for debug */
 
-       IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from %s, "
+       IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d] Received from %pM, "
                           "sta_id = %d\n",
                           agg->wait_for_ba,
-                          print_mac(mac, (u8 *) &ba_resp->sta_addr_lo32),
+                          (u8 *) &ba_resp->sta_addr_lo32,
                           ba_resp->sta_id);
        IWL_DEBUG_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = "
                           "%d, scd_ssn = %d\n",
@@ -1513,18 +1549,15 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
         * transmitted ... if not, it's too late anyway). */
        if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
                /* calculate mac80211 ampdu sw queue to wake */
-               int ampdu_q =
-                  scd_flow - priv->hw_params.first_ampdu_q + priv->hw->queues;
                int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);
-               priv->stations[ba_resp->sta_id].
-                       tid[ba_resp->tid].tfds_in_queue -= freed;
-               if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
-                       priv->mac80211_registered &&
-                       agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)
-                       ieee80211_wake_queue(priv->hw, ampdu_q);
-
-               iwl_txq_check_empty(priv, ba_resp->sta_id,
-                                   ba_resp->tid, scd_flow);
+               priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+
+               if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
+                   priv->mac80211_registered &&
+                   (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
+                       ieee80211_wake_queue(priv->hw, txq->swq_id);
+
+               iwl_txq_check_empty(priv, sta_id, tid, scd_flow);
        }
 }
 EXPORT_SYMBOL(iwl_rx_reply_compressed_ba);
index 285b53e7e261af8b70cbc447382b0e5369b86bbe..119185fb1e2625ab0e0be7bfbf5fac90753309f2 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/if_arp.h>
 
 #include <net/ieee80211_radiotap.h>
+#include <net/lib80211.h>
 #include <net/mac80211.h>
 
 #include <asm/div64.h>
@@ -107,46 +108,6 @@ static const struct ieee80211_supported_band *iwl3945_get_band(
        return priv->hw->wiphy->bands[band];
 }
 
-static int iwl3945_is_empty_essid(const char *essid, int essid_len)
-{
-       /* Single white space is for Linksys APs */
-       if (essid_len == 1 && essid[0] == ' ')
-               return 1;
-
-       /* Otherwise, if the entire essid is 0, we assume it is hidden */
-       while (essid_len) {
-               essid_len--;
-               if (essid[essid_len] != '\0')
-                       return 0;
-       }
-
-       return 1;
-}
-
-static const char *iwl3945_escape_essid(const char *essid, u8 essid_len)
-{
-       static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
-       const char *s = essid;
-       char *d = escaped;
-
-       if (iwl3945_is_empty_essid(essid, essid_len)) {
-               memcpy(escaped, "<hidden>", sizeof("<hidden>"));
-               return escaped;
-       }
-
-       essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
-       while (essid_len--) {
-               if (*s == '\0') {
-                       *d++ = '\\';
-                       *d++ = '0';
-                       s++;
-               } else
-                       *d++ = *s++;
-       }
-       *d = '\0';
-       return escaped;
-}
-
 /*************** DMA-QUEUE-GENERAL-FUNCTIONS  *****
  * DMA services
  *
@@ -446,7 +407,6 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8
        int index = IWL_INVALID_STATION;
        struct iwl3945_station_entry *station;
        unsigned long flags_spin;
-       DECLARE_MAC_BUF(mac);
        u8 rate;
 
        spin_lock_irqsave(&priv->sta_lock, flags_spin);
@@ -480,7 +440,7 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8
                return index;
        }
 
-       IWL_DEBUG_ASSOC("Add STA ID %d: %s\n", index, print_mac(mac, addr));
+       IWL_DEBUG_ASSOC("Add STA ID %d: %pM\n", index, addr);
        station = &priv->stations[index];
        station->used = 1;
        priv->num_stations++;
@@ -1063,7 +1023,6 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
        /* cast away the const for active_rxon in this function */
        struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
        int rc = 0;
-       DECLARE_MAC_BUF(mac);
 
        if (!iwl3945_is_alive(priv))
                return -1;
@@ -1124,11 +1083,11 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
        IWL_DEBUG_INFO("Sending RXON\n"
                       "* with%s RXON_FILTER_ASSOC_MSK\n"
                       "* channel = %d\n"
-                      "* bssid = %s\n",
+                      "* bssid = %pM\n",
                       ((priv->staging_rxon.filter_flags &
                         RXON_FILTER_ASSOC_MSK) ? "" : "out"),
                       le16_to_cpu(priv->staging_rxon.channel),
-                      print_mac(mac, priv->staging_rxon.bssid_addr));
+                      priv->staging_rxon.bssid_addr);
 
        /* Apply the new configuration */
        rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON,
@@ -1634,7 +1593,7 @@ static u16 iwl3945_supported_rate_to_ie(u8 *ie, u16 supported_rate,
  */
 static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv,
                              struct ieee80211_mgmt *frame,
-                             int left, int is_direct)
+                             int left)
 {
        int len = 0;
        u8 *pos = NULL;
@@ -1664,20 +1623,6 @@ static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv,
        *pos++ = WLAN_EID_SSID;
        *pos++ = 0;
 
-       /* fill in our direct SSID IE... */
-       if (is_direct) {
-               /* ...next IE... */
-               left -= 2 + priv->essid_len;
-               if (left < 0)
-                       return 0;
-               /* ... fill it in... */
-               *pos++ = WLAN_EID_SSID;
-               *pos++ = priv->essid_len;
-               memcpy(pos, priv->essid, priv->essid_len);
-               pos += priv->essid_len;
-               len += 2 + priv->essid_len;
-       }
-
        /* fill in supported rate */
        /* ...next IE... */
        left -= 2;
@@ -1846,7 +1791,7 @@ static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force)
        spin_unlock_irqrestore(&priv->lock, flags);
 
        if (force || iwl3945_is_associated(priv)) {
-               IWL_DEBUG_QOS("send QoS cmd with Qos active %d \n",
+               IWL_DEBUG_QOS("send QoS cmd with QoS active %d \n",
                              priv->qos_data.qos_active);
 
                iwl3945_send_qos_params_command(priv,
@@ -1870,7 +1815,7 @@ static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force)
 
 
 /* default power management (not Tx power) table values */
-/* for tim  0-10 */
+/* for TIM  0-10 */
 static struct iwl3945_power_vec_entry range_0[IWL_POWER_AC] = {
        {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
        {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
@@ -1880,7 +1825,7 @@ static struct iwl3945_power_vec_entry range_0[IWL_POWER_AC] = {
        {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25), SLP_VEC(4, 7, 10, 10, 10)}, 1}
 };
 
-/* for tim > 10 */
+/* for TIM > 10 */
 static struct iwl3945_power_vec_entry range_1[IWL_POWER_AC] = {
        {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
        {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500),
@@ -2230,13 +2175,14 @@ static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv,
 /*
  * initialize rxon structure with default values from eeprom
  */
-static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)
+static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv,
+                                             int mode)
 {
        const struct iwl3945_channel_info *ch_info;
 
        memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
 
-       switch (priv->iw_mode) {
+       switch (mode) {
        case NL80211_IFTYPE_AP:
                priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
                break;
@@ -2259,7 +2205,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)
                    RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
                break;
        default:
-               IWL_ERROR("Unsupported interface type %d\n", priv->iw_mode);
+               IWL_ERROR("Unsupported interface type %d\n", mode);
                break;
        }
 
@@ -2282,8 +2228,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)
         * in some case A channels are all non IBSS
         * in this case force B/G channel
         */
-       if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
-           !(is_channel_ibss(ch_info)))
+       if ((mode == NL80211_IFTYPE_ADHOC) && !(is_channel_ibss(ch_info)))
                ch_info = &priv->channel_info[0];
 
        priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
@@ -2316,14 +2261,12 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
                }
        }
 
-       priv->iw_mode = mode;
-
-       iwl3945_connection_init_rx_config(priv);
+       iwl3945_connection_init_rx_config(priv, mode);
        memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
 
        iwl3945_clear_stations_table(priv);
 
-       /* dont commit rxon if rf-kill is on*/
+       /* don't commit rxon if rf-kill is on*/
        if (!iwl3945_is_ready_rf(priv))
                return -EAGAIN;
 
@@ -2352,7 +2295,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
        case ALG_CCMP:
                cmd->cmd.tx.sec_ctl = TX_CMD_SEC_CCM;
                memcpy(cmd->cmd.tx.key, keyinfo->key, keyinfo->keylen);
-               IWL_DEBUG_TX("tx_cmd with aes hwcrypto\n");
+               IWL_DEBUG_TX("tx_cmd with AES hwcrypto\n");
                break;
 
        case ALG_TKIP:
@@ -2397,6 +2340,7 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
 {
        __le16 fc = hdr->frame_control;
        __le32 tx_flags = cmd->cmd.tx.tx_flags;
+       u8 rc_flags = info->control.rates[0].flags;
 
        cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
        if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
@@ -2423,10 +2367,10 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
                tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
        }
 
-       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
+       if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
                tx_flags |= TX_CMD_FLG_RTS_MSK;
                tx_flags &= ~TX_CMD_FLG_CTS_MSK;
-       } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
+       } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
                tx_flags &= ~TX_CMD_FLG_RTS_MSK;
                tx_flags |= TX_CMD_FLG_CTS_MSK;
        }
@@ -2482,8 +2426,6 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
        /* If this frame is going out to an IBSS network, find the station,
         * or create a new station table entry */
        case NL80211_IFTYPE_ADHOC: {
-               DECLARE_MAC_BUF(mac);
-
                /* Create new station table entry */
                sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
                if (sta_id != IWL_INVALID_STATION)
@@ -2494,9 +2436,9 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
                if (sta_id != IWL_INVALID_STATION)
                        return sta_id;
 
-               IWL_DEBUG_DROP("Station %s not in station map. "
+               IWL_DEBUG_DROP("Station %pM not in station map. "
                               "Defaulting to broadcast...\n",
-                              print_mac(mac, hdr->addr1));
+                              hdr->addr1);
                iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
                return priv->hw_setting.bcast_sta_id;
        }
@@ -2579,10 +2521,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
        /* Find (or create) index into station table for destination station */
        sta_id = iwl3945_get_sta_id(priv, hdr);
        if (sta_id == IWL_INVALID_STATION) {
-               DECLARE_MAC_BUF(mac);
-
-               IWL_DEBUG_DROP("Dropping - INVALID STATION: %s\n",
-                              print_mac(mac, hdr->addr1));
+               IWL_DEBUG_DROP("Dropping - INVALID STATION: %pM\n",
+                              hdr->addr1);
                goto drop;
        }
 
@@ -4019,8 +3959,6 @@ static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,
 #ifdef CONFIG_IWL3945_DEBUG
 static void iwl3945_print_rx_config_cmd(struct iwl3945_rxon_cmd *rxon)
 {
-       DECLARE_MAC_BUF(mac);
-
        IWL_DEBUG_RADIO("RX CONFIG:\n");
        iwl3945_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
        IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
@@ -4031,10 +3969,8 @@ static void iwl3945_print_rx_config_cmd(struct iwl3945_rxon_cmd *rxon)
        IWL_DEBUG_RADIO("u8 ofdm_basic_rates: 0x%02x\n",
                        rxon->ofdm_basic_rates);
        IWL_DEBUG_RADIO("u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
-       IWL_DEBUG_RADIO("u8[6] node_addr: %s\n",
-                       print_mac(mac, rxon->node_addr));
-       IWL_DEBUG_RADIO("u8[6] bssid_addr: %s\n",
-                       print_mac(mac, rxon->bssid_addr));
+       IWL_DEBUG_RADIO("u8[6] node_addr: %pM\n", rxon->node_addr);
+       IWL_DEBUG_RADIO("u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
        IWL_DEBUG_RADIO("u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
 }
 #endif
@@ -4050,7 +3986,7 @@ static void iwl3945_enable_interrupts(struct iwl3945_priv *priv)
 /* call this function to flush any scheduled tasklet */
 static inline void iwl_synchronize_irq(struct iwl3945_priv *priv)
 {
-       /* wait to make sure we flush pedding tasklet*/
+       /* wait to make sure we flush pending tasklet*/
        synchronize_irq(priv->pci_dev->irq);
        tasklet_kill(&priv->irq_tasklet);
 }
@@ -5607,7 +5543,7 @@ static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv)
        iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
                                 priv->ucode_data.len);
 
-       /* Inst bytecount must be last to set up, bit 31 signals uCode
+       /* Inst byte count must be last to set up, bit 31 signals uCode
         *   that all new ptr/size info is in place */
        iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
                                 priv->ucode_code.len | BSM_DRAM_INST_LOAD);
@@ -5699,7 +5635,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
 
        rc = iwl3945_grab_nic_access(priv);
        if (rc) {
-               IWL_WARNING("Can not read rfkill status from adapter\n");
+               IWL_WARNING("Can not read RFKILL status from adapter\n");
                return;
        }
 
@@ -5709,7 +5645,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
 
        if (rfkill & 0x1) {
                clear_bit(STATUS_RF_KILL_HW, &priv->status);
-               /* if rfkill is not on, then wait for thermal
+               /* if RFKILL is not on, then wait for thermal
                 * sensor in adapter to kick in */
                while (iwl3945_hw_get_temperature(priv) == 0) {
                        thermal_spin++;
@@ -5747,7 +5683,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
                active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
        } else {
                /* Initialize our rx_config data */
-               iwl3945_connection_init_rx_config(priv);
+               iwl3945_connection_init_rx_config(priv, priv->iw_mode);
                memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
        }
 
@@ -5902,7 +5838,7 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
        }
 
        if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
-               IWL_ERROR("ucode not available for device bringup\n");
+               IWL_ERROR("ucode not available for device bring up\n");
                return -EIO;
        }
 
@@ -6063,6 +5999,7 @@ static void iwl3945_bg_set_monitor(struct work_struct *work)
                        IWL_ERROR("iwl3945_set_mode() failed\n");
 
        mutex_unlock(&priv->mutex);
+       ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
 }
 
 #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
@@ -6102,6 +6039,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
        struct ieee80211_conf *conf = NULL;
        u8 n_probes = 2;
        enum ieee80211_band band;
+       DECLARE_SSID_BUF(ssid);
 
        conf = ieee80211_get_hw_conf(priv->hw);
 
@@ -6112,7 +6050,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
                goto done;
        }
 
-       /* Make sure the scan wasn't cancelled before this queued work
+       /* Make sure the scan wasn't canceled before this queued work
         * was given the chance to run... */
        if (!test_bit(STATUS_SCANNING, &priv->status))
                goto done;
@@ -6202,21 +6140,13 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
        if (priv->one_direct_scan) {
                IWL_DEBUG_SCAN
                    ("Kicking off one direct scan for '%s'\n",
-                    iwl3945_escape_essid(priv->direct_ssid,
-                                     priv->direct_ssid_len));
+                    print_ssid(ssid, priv->direct_ssid,
+                               priv->direct_ssid_len));
                scan->direct_scan[0].id = WLAN_EID_SSID;
                scan->direct_scan[0].len = priv->direct_ssid_len;
                memcpy(scan->direct_scan[0].ssid,
                       priv->direct_ssid, priv->direct_ssid_len);
                n_probes++;
-       } else if (!iwl3945_is_associated(priv) && priv->essid_len) {
-               IWL_DEBUG_SCAN
-                 ("Kicking off one direct scan for '%s' when not associated\n",
-                  iwl3945_escape_essid(priv->essid, priv->essid_len));
-               scan->direct_scan[0].id = WLAN_EID_SSID;
-               scan->direct_scan[0].len = priv->essid_len;
-               memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
-               n_probes++;
        } else
                IWL_DEBUG_SCAN("Kicking off one indirect scan.\n");
 
@@ -6224,7 +6154,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
         * that based on the direct_mask added to each channel entry */
        scan->tx_cmd.len = cpu_to_le16(
                iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
-                       IWL_MAX_SCAN_SIZE - sizeof(*scan), 0));
+                       IWL_MAX_SCAN_SIZE - sizeof(*scan)));
        scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
        scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
        scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
@@ -6334,7 +6264,6 @@ static void iwl3945_post_associate(struct iwl3945_priv *priv)
 {
        int rc = 0;
        struct ieee80211_conf *conf = NULL;
-       DECLARE_MAC_BUF(mac);
 
        if (priv->iw_mode == NL80211_IFTYPE_AP) {
                IWL_ERROR("%s Should not be called in AP mode\n", __func__);
@@ -6342,9 +6271,8 @@ static void iwl3945_post_associate(struct iwl3945_priv *priv)
        }
 
 
-       IWL_DEBUG_ASSOC("Associated as %d to: %s\n",
-                       priv->assoc_id,
-                       print_mac(mac, priv->active_rxon.bssid_addr));
+       IWL_DEBUG_ASSOC("Associated as %d to: %pM\n",
+                       priv->assoc_id, priv->active_rxon.bssid_addr);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
@@ -6440,7 +6368,7 @@ static void iwl3945_bg_abort_scan(struct work_struct *work)
        mutex_unlock(&priv->mutex);
 }
 
-static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
+static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed);
 
 static void iwl3945_bg_scan_completed(struct work_struct *work)
 {
@@ -6453,7 +6381,7 @@ static void iwl3945_bg_scan_completed(struct work_struct *work)
                return;
 
        if (test_bit(STATUS_CONF_PENDING, &priv->status))
-               iwl3945_mac_config(priv->hw, ieee80211_get_hw_conf(priv->hw));
+               iwl3945_mac_config(priv->hw, 0);
 
        ieee80211_scan_completed(priv->hw);
 
@@ -6605,7 +6533,6 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
 {
        struct iwl3945_priv *priv = hw->priv;
        unsigned long flags;
-       DECLARE_MAC_BUF(mac);
 
        IWL_DEBUG_MAC80211("enter: type %d\n", conf->type);
 
@@ -6616,13 +6543,14 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
 
        spin_lock_irqsave(&priv->lock, flags);
        priv->vif = conf->vif;
+       priv->iw_mode = conf->type;
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
        mutex_lock(&priv->mutex);
 
        if (conf->mac_addr) {
-               IWL_DEBUG_MAC80211("Set: %s\n", print_mac(mac, conf->mac_addr));
+               IWL_DEBUG_MAC80211("Set: %pM\n", conf->mac_addr);
                memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
        }
 
@@ -6642,10 +6570,11 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
  * be set inappropriately and the driver currently sets the hardware up to
  * use it whenever needed.
  */
-static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct iwl3945_priv *priv = hw->priv;
        const struct iwl3945_channel_info *ch_info;
+       struct ieee80211_conf *conf = &hw->conf;
        unsigned long flags;
        int ret = 0;
 
@@ -6791,8 +6720,6 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
                                    struct ieee80211_if_conf *conf)
 {
        struct iwl3945_priv *priv = hw->priv;
-       DECLARE_MAC_BUF(mac);
-       unsigned long flags;
        int rc;
 
        if (conf == NULL)
@@ -6814,23 +6741,13 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
                        return rc;
        }
 
-       /* XXX: this MUST use conf->mac_addr */
-
-       if ((priv->iw_mode == NL80211_IFTYPE_AP) &&
-           (!conf->ssid_len)) {
-               IWL_DEBUG_MAC80211
-                   ("Leaving in AP mode because HostAPD is not ready.\n");
-               return 0;
-       }
-
        if (!iwl3945_is_alive(priv))
                return -EAGAIN;
 
        mutex_lock(&priv->mutex);
 
        if (conf->bssid)
-               IWL_DEBUG_MAC80211("bssid: %s\n",
-                                  print_mac(mac, conf->bssid));
+               IWL_DEBUG_MAC80211("bssid: %pM\n", conf->bssid);
 
 /*
  * very dubious code was here; the probe filtering flag is never set:
@@ -6843,8 +6760,8 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
                if (!conf->bssid) {
                        conf->bssid = priv->mac_addr;
                        memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
-                       IWL_DEBUG_MAC80211("bssid was set to: %s\n",
-                                          print_mac(mac, conf->bssid));
+                       IWL_DEBUG_MAC80211("bssid was set to: %pM\n",
+                                          conf->bssid);
                }
                if (priv->ibss_beacon)
                        dev_kfree_skb(priv->ibss_beacon);
@@ -6890,15 +6807,6 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
        }
 
  done:
-       spin_lock_irqsave(&priv->lock, flags);
-       if (!conf->ssid_len)
-               memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
-       else
-               memcpy(priv->essid, conf->ssid, conf->ssid_len);
-
-       priv->essid_len = conf->ssid_len;
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        IWL_DEBUG_MAC80211("leave\n");
        mutex_unlock(&priv->mutex);
 
@@ -6941,8 +6849,6 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
        if (priv->vif == conf->vif) {
                priv->vif = NULL;
                memset(priv->bssid, 0, ETH_ALEN);
-               memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
-               priv->essid_len = 0;
        }
        mutex_unlock(&priv->mutex);
 
@@ -7011,6 +6917,7 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
        int rc = 0;
        unsigned long flags;
        struct iwl3945_priv *priv = hw->priv;
+       DECLARE_SSID_BUF(ssid_buf);
 
        IWL_DEBUG_MAC80211("enter\n");
 
@@ -7044,7 +6951,7 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
        }
        if (len) {
                IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
-                              iwl3945_escape_essid(ssid, len), (int)len);
+                              print_ssid(ssid_buf, ssid, len), (int)len);
 
                priv->one_direct_scan = 1;
                priv->direct_ssid_len = (u8)
@@ -7085,10 +6992,8 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
        sta_id = iwl3945_hw_find_station(priv, addr);
        if (sta_id == IWL_INVALID_STATION) {
-               DECLARE_MAC_BUF(mac);
-
-               IWL_DEBUG_MAC80211("leave - %s not in station map.\n",
-                                  print_mac(mac, addr));
+               IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
+                                  addr);
                return -EINVAL;
        }
 
@@ -7220,14 +7125,6 @@ static int iwl3945_mac_get_stats(struct ieee80211_hw *hw,
        return 0;
 }
 
-static u64 iwl3945_mac_get_tsf(struct ieee80211_hw *hw)
-{
-       IWL_DEBUG_MAC80211("enter\n");
-       IWL_DEBUG_MAC80211("leave\n");
-
-       return 0;
-}
-
 static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
 {
        struct iwl3945_priv *priv = hw->priv;
@@ -7793,7 +7690,7 @@ static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log);
 
 /*****************************************************************************
  *
- * driver setup and teardown
+ * driver setup and tear down
  *
  *****************************************************************************/
 
@@ -7870,7 +7767,6 @@ static struct ieee80211_ops iwl3945_hw_ops = {
        .get_stats = iwl3945_mac_get_stats,
        .get_tx_stats = iwl3945_mac_get_tx_stats,
        .conf_tx = iwl3945_mac_conf_tx,
-       .get_tsf = iwl3945_mac_get_tsf,
        .reset_tsf = iwl3945_mac_reset_tsf,
        .bss_info_changed = iwl3945_bss_info_changed,
        .hw_scan = iwl3945_mac_hw_scan
@@ -7883,7 +7779,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        struct ieee80211_hw *hw;
        struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data);
        unsigned long flags;
-       DECLARE_MAC_BUF(mac);
 
        /* Disabling hardware scan means that mac80211 will perform scans
         * "the hard way", rather than using device's scan. */
@@ -8058,7 +7953,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        }
        /* MAC Address location in EEPROM same for 3945/4965 */
        get_eeprom_mac(priv, priv->mac_addr);
-       IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
+       IWL_DEBUG_INFO("MAC address: %pM\n", priv->mac_addr);
        SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
 
        err = iwl3945_init_channel_map(priv);
@@ -8223,7 +8118,7 @@ static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return 0;
 
-       IWL_DEBUG_RF_KILL("we recieved soft RFKILL set to state %d\n", state);
+       IWL_DEBUG_RF_KILL("we received soft RFKILL set to state %d\n", state);
        mutex_lock(&priv->mutex);
 
        switch (state) {
@@ -8238,7 +8133,7 @@ static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
                iwl3945_radio_kill_sw(priv, 1);
                break;
        default:
-               IWL_WARNING("we recieved unexpected RFKILL state %d\n", state);
+               IWL_WARNING("we received unexpected RFKILL state %d\n", state);
                break;
        }
 out_unlock:
index 92be60415d043e041384bdaeea082f440a9123fb..a0e440cd8967ec55c53ae17b948d678d6c5b7959 100644 (file)
@@ -1,6 +1,10 @@
 /* Copyright (C) 2006, Red Hat, Inc. */
 
+#include <linux/types.h>
 #include <linux/etherdevice.h>
+#include <linux/ieee80211.h>
+#include <linux/if_arp.h>
+#include <net/lib80211.h>
 
 #include "assoc.h"
 #include "decl.h"
@@ -151,18 +155,18 @@ static int lbs_adhoc_join(struct lbs_private *priv,
        struct cmd_ds_802_11_ad_hoc_join cmd;
        struct bss_descriptor *bss = &assoc_req->bss;
        u8 preamble = RADIO_PREAMBLE_LONG;
-       DECLARE_MAC_BUF(mac);
+       DECLARE_SSID_BUF(ssid);
        u16 ratesize = 0;
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
        lbs_deb_join("current SSID '%s', ssid length %u\n",
-               escape_essid(priv->curbssparams.ssid,
+               print_ssid(ssid, priv->curbssparams.ssid,
                priv->curbssparams.ssid_len),
                priv->curbssparams.ssid_len);
        lbs_deb_join("requested ssid '%s', ssid length %u\n",
-               escape_essid(bss->ssid, bss->ssid_len),
+               print_ssid(ssid, bss->ssid, bss->ssid_len),
                bss->ssid_len);
 
        /* check if the requested SSID is already joined */
@@ -226,8 +230,8 @@ static int lbs_adhoc_join(struct lbs_private *priv,
               bss->capability, CAPINFO_MASK);
 
        /* information on BSSID descriptor passed to FW */
-       lbs_deb_join("ADHOC_J_CMD: BSSID = %s, SSID = '%s'\n",
-                       print_mac(mac, cmd.bss.bssid), cmd.bss.ssid);
+       lbs_deb_join("ADHOC_J_CMD: BSSID = %pM, SSID = '%s'\n",
+                       cmd.bss.bssid, cmd.bss.ssid);
 
        /* Only v8 and below support setting these */
        if (priv->fwrelease < 0x09000000) {
@@ -307,6 +311,7 @@ static int lbs_adhoc_start(struct lbs_private *priv,
        size_t ratesize = 0;
        u16 tmpcap = 0;
        int ret = 0;
+       DECLARE_SSID_BUF(ssid);
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
@@ -326,7 +331,7 @@ static int lbs_adhoc_start(struct lbs_private *priv,
        memcpy(cmd.ssid, assoc_req->ssid, assoc_req->ssid_len);
 
        lbs_deb_join("ADHOC_START: SSID '%s', ssid length %u\n",
-               escape_essid(assoc_req->ssid, assoc_req->ssid_len),
+               print_ssid(ssid, assoc_req->ssid, assoc_req->ssid_len),
                assoc_req->ssid_len);
 
        cmd.bsstype = CMD_BSS_TYPE_IBSS;
@@ -338,12 +343,12 @@ static int lbs_adhoc_start(struct lbs_private *priv,
        WARN_ON(!assoc_req->channel);
 
        /* set Physical parameter set */
-       cmd.phyparamset.dsparamset.elementid = MFIE_TYPE_DS_SET;
+       cmd.phyparamset.dsparamset.elementid = WLAN_EID_DS_PARAMS;
        cmd.phyparamset.dsparamset.len = 1;
        cmd.phyparamset.dsparamset.currentchan = assoc_req->channel;
 
        /* set IBSS parameter set */
-       cmd.ssparamset.ibssparamset.elementid = MFIE_TYPE_IBSS_SET;
+       cmd.ssparamset.ibssparamset.elementid = WLAN_EID_IBSS_PARAMS;
        cmd.ssparamset.ibssparamset.len = 2;
        cmd.ssparamset.ibssparamset.atimwindow = 0;
 
@@ -427,8 +432,8 @@ static inline int match_bss_no_security(struct lbs_802_11_security *secinfo,
 {
        if (!secinfo->wep_enabled  && !secinfo->WPAenabled
            && !secinfo->WPA2enabled
-           && match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC
-           && match_bss->rsn_ie[0] != MFIE_TYPE_RSN
+           && match_bss->wpa_ie[0] != WLAN_EID_GENERIC
+           && match_bss->rsn_ie[0] != WLAN_EID_RSN
            && !(match_bss->capability & WLAN_CAPABILITY_PRIVACY))
                return 1;
        else
@@ -450,7 +455,7 @@ static inline int match_bss_wpa(struct lbs_802_11_security *secinfo,
                                struct bss_descriptor *match_bss)
 {
        if (!secinfo->wep_enabled && secinfo->WPAenabled
-           && (match_bss->wpa_ie[0] == MFIE_TYPE_GENERIC)
+           && (match_bss->wpa_ie[0] == WLAN_EID_GENERIC)
            /* privacy bit may NOT be set in some APs like LinkSys WRT54G
            && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */
           )
@@ -463,7 +468,7 @@ static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo,
                                 struct bss_descriptor *match_bss)
 {
        if (!secinfo->wep_enabled && secinfo->WPA2enabled &&
-           (match_bss->rsn_ie[0] == MFIE_TYPE_RSN)
+           (match_bss->rsn_ie[0] == WLAN_EID_RSN)
            /* privacy bit may NOT be set in some APs like LinkSys WRT54G
            (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */
           )
@@ -477,8 +482,8 @@ static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo,
 {
        if (!secinfo->wep_enabled && !secinfo->WPAenabled
            && !secinfo->WPA2enabled
-           && (match_bss->wpa_ie[0] != MFIE_TYPE_GENERIC)
-           && (match_bss->rsn_ie[0] != MFIE_TYPE_RSN)
+           && (match_bss->wpa_ie[0] != WLAN_EID_GENERIC)
+           && (match_bss->rsn_ie[0] != WLAN_EID_RSN)
            && (match_bss->capability & WLAN_CAPABILITY_PRIVACY))
                return 1;
        else
@@ -694,6 +699,7 @@ static int assoc_helper_essid(struct lbs_private *priv,
        int ret = 0;
        struct bss_descriptor * bss;
        int channel = -1;
+       DECLARE_SSID_BUF(ssid);
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
@@ -705,7 +711,7 @@ static int assoc_helper_essid(struct lbs_private *priv,
                channel = assoc_req->channel;
 
        lbs_deb_assoc("SSID '%s' requested\n",
-                     escape_essid(assoc_req->ssid, assoc_req->ssid_len));
+                     print_ssid(ssid, assoc_req->ssid, assoc_req->ssid_len));
        if (assoc_req->mode == IW_MODE_INFRA) {
                lbs_send_specific_ssid_scan(priv, assoc_req->ssid,
                        assoc_req->ssid_len);
@@ -752,17 +758,15 @@ static int assoc_helper_bssid(struct lbs_private *priv,
 {
        int ret = 0;
        struct bss_descriptor * bss;
-       DECLARE_MAC_BUF(mac);
 
-       lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID %s",
-               print_mac(mac, assoc_req->bssid));
+       lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID %pM", assoc_req->bssid);
 
        /* Search for index position in list for requested MAC */
        bss = lbs_find_bssid_in_list(priv, assoc_req->bssid,
                            assoc_req->mode);
        if (bss == NULL) {
-               lbs_deb_assoc("ASSOC: WAP: BSSID %s not found, "
-                       "cannot associate.\n", print_mac(mac, assoc_req->bssid));
+               lbs_deb_assoc("ASSOC: WAP: BSSID %pM not found, "
+                       "cannot associate.\n", assoc_req->bssid);
                goto out;
        }
 
@@ -1208,7 +1212,7 @@ void lbs_association_worker(struct work_struct *work)
        struct assoc_request * assoc_req = NULL;
        int ret = 0;
        int find_any_ssid = 0;
-       DECLARE_MAC_BUF(mac);
+       DECLARE_SSID_BUF(ssid);
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
@@ -1228,13 +1232,13 @@ void lbs_association_worker(struct work_struct *work)
                "    chann:     %d\n"
                "    band:      %d\n"
                "    mode:      %d\n"
-               "    BSSID:     %s\n"
+               "    BSSID:     %pM\n"
                "    secinfo:  %s%s%s\n"
                "    auth_mode: %d\n",
                assoc_req->flags,
-               escape_essid(assoc_req->ssid, assoc_req->ssid_len),
+               print_ssid(ssid, assoc_req->ssid, assoc_req->ssid_len),
                assoc_req->channel, assoc_req->band, assoc_req->mode,
-               print_mac(mac, assoc_req->bssid),
+               assoc_req->bssid,
                assoc_req->secinfo.WPAenabled ? " WPA" : "",
                assoc_req->secinfo.WPA2enabled ? " WPA2" : "",
                assoc_req->secinfo.wep_enabled ? " WEP" : "",
@@ -1357,8 +1361,8 @@ void lbs_association_worker(struct work_struct *work)
                }
 
                if (success) {
-                       lbs_deb_assoc("associated to %s\n",
-                               print_mac(mac, priv->curbssparams.bssid));
+                       lbs_deb_assoc("associated to %pM\n",
+                               priv->curbssparams.bssid);
                        lbs_prepare_and_send_command(priv,
                                CMD_802_11_RSSI,
                                0, CMD_OPTION_WAITFORRSP, 0, NULL);
@@ -1478,7 +1482,6 @@ int lbs_cmd_80211_authenticate(struct lbs_private *priv,
        struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth;
        int ret = -1;
        u8 *bssid = pdata_buf;
-       DECLARE_MAC_BUF(mac);
 
        lbs_deb_enter(LBS_DEB_JOIN);
 
@@ -1505,8 +1508,8 @@ int lbs_cmd_80211_authenticate(struct lbs_private *priv,
 
        memcpy(pauthenticate->macaddr, bssid, ETH_ALEN);
 
-       lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
-               print_mac(mac, bssid), pauthenticate->authtype);
+       lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n",
+               bssid, pauthenticate->authtype);
        ret = 0;
 
 out:
@@ -1770,7 +1773,7 @@ static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp)
        struct cmd_ds_802_11_ad_hoc_result *adhoc_resp;
        union iwreq_data wrqu;
        struct bss_descriptor *bss;
-       DECLARE_MAC_BUF(mac);
+       DECLARE_SSID_BUF(ssid);
 
        lbs_deb_enter(LBS_DEB_JOIN);
 
@@ -1819,9 +1822,9 @@ static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp)
        wrqu.ap_addr.sa_family = ARPHRD_ETHER;
        wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
 
-       lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %s, channel %d\n",
-                    escape_essid(bss->ssid, bss->ssid_len),
-                    print_mac(mac, priv->curbssparams.bssid),
+       lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n",
+                    print_ssid(ssid, bss->ssid, bss->ssid_len),
+                    priv->curbssparams.bssid,
                     priv->curbssparams.channel);
 
 done:
index 8265c7d25edcb9cbe51478e00828d93e8a26000c..957fd5a10a8d30a1b7b8aaca68460865ef6fa5dd 100644 (file)
@@ -4,7 +4,7 @@
   */
 
 #include <net/iw_handler.h>
-#include <net/ieee80211.h>
+#include <net/lib80211.h>
 #include <linux/kfifo.h>
 #include "host.h"
 #include "hostcmd.h"
@@ -87,7 +87,6 @@ int lbs_update_hw_spec(struct lbs_private *priv)
        struct cmd_ds_get_hw_spec cmd;
        int ret = -1;
        u32 i;
-       DECLARE_MAC_BUF(mac);
 
        lbs_deb_enter(LBS_DEB_CMD);
 
@@ -110,8 +109,8 @@ int lbs_update_hw_spec(struct lbs_private *priv)
         * CF card    firmware 5.0.16p0:   cap 0x00000303
         * USB dongle firmware 5.110.17p2: cap 0x00000303
         */
-       lbs_pr_info("%s, fw %u.%u.%up%u, cap 0x%08x\n",
-               print_mac(mac, cmd.permanentaddr),
+       lbs_pr_info("%pM, fw %u.%u.%up%u, cap 0x%08x\n",
+               cmd.permanentaddr,
                priv->fwrelease >> 24 & 0xff,
                priv->fwrelease >> 16 & 0xff,
                priv->fwrelease >>  8 & 0xff,
@@ -1063,6 +1062,7 @@ int lbs_mesh_config(struct lbs_private *priv, uint16_t action, uint16_t chan)
 {
        struct cmd_ds_mesh_config cmd;
        struct mrvl_meshie *ie;
+       DECLARE_SSID_BUF(ssid);
 
        memset(&cmd, 0, sizeof(cmd));
        cmd.channel = cpu_to_le16(chan);
@@ -1070,7 +1070,7 @@ int lbs_mesh_config(struct lbs_private *priv, uint16_t action, uint16_t chan)
 
        switch (action) {
        case CMD_ACT_MESH_CONFIG_START:
-               ie->hdr.id = MFIE_TYPE_GENERIC;
+               ie->id = WLAN_EID_GENERIC;
                ie->val.oui[0] = 0x00;
                ie->val.oui[1] = 0x50;
                ie->val.oui[2] = 0x43;
@@ -1082,7 +1082,7 @@ int lbs_mesh_config(struct lbs_private *priv, uint16_t action, uint16_t chan)
                ie->val.mesh_capability = MARVELL_MESH_CAPABILITY;
                ie->val.mesh_id_len = priv->mesh_ssid_len;
                memcpy(ie->val.mesh_id, priv->mesh_ssid, priv->mesh_ssid_len);
-               ie->hdr.len = sizeof(struct mrvl_meshie_val) -
+               ie->len = sizeof(struct mrvl_meshie_val) -
                        IW_ESSID_MAX_SIZE + priv->mesh_ssid_len;
                cmd.length = cpu_to_le16(sizeof(struct mrvl_meshie_val));
                break;
@@ -1093,7 +1093,7 @@ int lbs_mesh_config(struct lbs_private *priv, uint16_t action, uint16_t chan)
        }
        lbs_deb_cmd("mesh config action %d type %x channel %d SSID %s\n",
                    action, priv->mesh_tlv, chan,
-                   escape_essid(priv->mesh_ssid, priv->mesh_ssid_len));
+                   print_ssid(ssid, priv->mesh_ssid, priv->mesh_ssid_len));
 
        return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
 }
index 0aa0ce3b2c425206262997ef1eacb163cb66c977..ec4efd7ff3c85064929fe67a6dee3c10f3c2148a 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <net/iw_handler.h>
+#include <net/lib80211.h>
 
 #include "dev.h"
 #include "decl.h"
@@ -65,7 +66,7 @@ static ssize_t lbs_getscantable(struct file *file, char __user *userbuf,
        int numscansdone = 0, res;
        unsigned long addr = get_zeroed_page(GFP_KERNEL);
        char *buf = (char *)addr;
-       DECLARE_MAC_BUF(mac);
+       DECLARE_SSID_BUF(ssid);
        struct bss_descriptor * iter_bss;
 
        pos += snprintf(buf+pos, len-pos,
@@ -77,17 +78,17 @@ static ssize_t lbs_getscantable(struct file *file, char __user *userbuf,
                u16 privacy = (iter_bss->capability & WLAN_CAPABILITY_PRIVACY);
                u16 spectrum_mgmt = (iter_bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT);
 
-               pos += snprintf(buf+pos, len-pos,
-                       "%02u| %03d | %04d | %s |",
+               pos += snprintf(buf+pos, len-pos, "%02u| %03d | %04d | %pM |",
                        numscansdone, iter_bss->channel, iter_bss->rssi,
-                       print_mac(mac, iter_bss->bssid));
+                       iter_bss->bssid);
                pos += snprintf(buf+pos, len-pos, " %04x-", iter_bss->capability);
                pos += snprintf(buf+pos, len-pos, "%c%c%c |",
                                ibss ? 'A' : 'I', privacy ? 'P' : ' ',
                                spectrum_mgmt ? 'S' : ' ');
                pos += snprintf(buf+pos, len-pos, " %04d |", SCAN_RSSI(iter_bss->rssi));
                pos += snprintf(buf+pos, len-pos, " %s\n",
-                               escape_essid(iter_bss->ssid, iter_bss->ssid_len));
+                               print_ssid(ssid, iter_bss->ssid,
+                                          iter_bss->ssid_len));
 
                numscansdone++;
        }
index 1a8888cceadc080bffd7d9b6dab1222c0529802e..0b84bdca0726129c98ccebbc0fe684a64a63c728 100644 (file)
@@ -74,8 +74,4 @@ void lbs_host_to_card_done(struct lbs_private *priv);
 
 int lbs_update_channel(struct lbs_private *priv);
 
-#ifndef CONFIG_IEEE80211
-const char *escape_essid(const char *essid, u8 essid_len);
-#endif
-
 #endif
index 076a636e8f62165252b8f931f88312187e64c1bf..2d4666f26808b8cd4f9029d143e9677697490f15 100644 (file)
@@ -79,7 +79,7 @@ do { if ((lbs_debug & (grp)) == (grp)) \
 #define lbs_deb_tx(fmt, args...)        LBS_DEB_LL(LBS_DEB_TX, " tx", fmt, ##args)
 #define lbs_deb_fw(fmt, args...)        LBS_DEB_LL(LBS_DEB_FW, " fw", fmt, ##args)
 #define lbs_deb_usb(fmt, args...)       LBS_DEB_LL(LBS_DEB_USB, " usb", fmt, ##args)
-#define lbs_deb_usbd(dev, fmt, args...) LBS_DEB_LL(LBS_DEB_USB, " usbd", "%s:" fmt, (dev)->bus_id, ##args)
+#define lbs_deb_usbd(dev, fmt, args...) LBS_DEB_LL(LBS_DEB_USB, " usbd", "%s:" fmt, dev_name(dev), ##args)
 #define lbs_deb_cs(fmt, args...)        LBS_DEB_LL(LBS_DEB_CS, " cs", fmt, ##args)
 #define lbs_deb_thread(fmt, args...)    LBS_DEB_LL(LBS_DEB_THREAD, " thread", fmt, ##args)
 #define lbs_deb_sdio(fmt, args...)      LBS_DEB_LL(LBS_DEB_SDIO, " sdio", fmt, ##args)
index f6f3753da303d80f26bc95d0f51ca52f03106814..dd682c4cfde816929425b3f68417de552e62b0b6 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/wireless.h>
 #include <linux/ethtool.h>
 #include <linux/debugfs.h>
-#include <net/ieee80211.h>
 
 #include "defs.h"
 #include "hostcmd.h"
@@ -278,6 +277,12 @@ struct lbs_private {
        struct enc_key wpa_mcast_key;
        struct enc_key wpa_unicast_key;
 
+/*
+ * In theory, the IE is limited to the IE length, 255,
+ * but in practice 64 bytes are enough.
+ */
+#define MAX_WPA_IE_LEN 64
+
        /** WPA Information Elements*/
        u8 wpa_ie[MAX_WPA_IE_LEN];
        u8 wpa_ie_len;
index 688d60de55cb580d89cb3e188377be4203e887ef..156f471217bbfc34cd463e365d8db0fe52e744a2 100644 (file)
@@ -23,7 +23,7 @@ static const char * mesh_stat_strings[]= {
 static void lbs_ethtool_get_drvinfo(struct net_device *dev,
                                         struct ethtool_drvinfo *info)
 {
-       struct lbs_private *priv = (struct lbs_private *) dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        snprintf(info->fw_version, 32, "%u.%u.%u.p%u",
                priv->fwrelease >> 24 & 0xff,
@@ -47,7 +47,7 @@ static int lbs_ethtool_get_eeprom_len(struct net_device *dev)
 static int lbs_ethtool_get_eeprom(struct net_device *dev,
                                   struct ethtool_eeprom *eeprom, u8 * bytes)
 {
-       struct lbs_private *priv = (struct lbs_private *) dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        struct cmd_ds_802_11_eeprom_access cmd;
        int ret;
 
@@ -76,7 +76,7 @@ out:
 static void lbs_ethtool_get_stats(struct net_device *dev,
                                  struct ethtool_stats *stats, uint64_t *data)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        struct cmd_ds_mesh_access mesh_access;
        int ret;
 
@@ -113,7 +113,7 @@ static void lbs_ethtool_get_stats(struct net_device *dev,
 
 static int lbs_ethtool_get_sset_count(struct net_device *dev, int sset)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        if (sset == ETH_SS_STATS && dev == priv->mesh_dev)
                return MESH_STATS_NUM;
@@ -143,7 +143,7 @@ static void lbs_ethtool_get_strings(struct net_device *dev,
 static void lbs_ethtool_get_wol(struct net_device *dev,
                                struct ethtool_wolinfo *wol)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        if (priv->wol_criteria == 0xffffffff) {
                /* Interface driver didn't configure wake */
@@ -166,7 +166,7 @@ static void lbs_ethtool_get_wol(struct net_device *dev,
 static int lbs_ethtool_set_wol(struct net_device *dev,
                               struct ethtool_wolinfo *wol)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        uint32_t criteria = 0;
 
        if (priv->wol_criteria == 0xffffffff && wol->wolopts)
index 73dc8c72402a93fbfa85d1477869d370454c4cd2..241af7fe44bb6320485899f1ccca561f1a08ca60 100644 (file)
@@ -12,9 +12,8 @@
 #include <linux/kthread.h>
 #include <linux/kfifo.h>
 #include <linux/stddef.h>
-
+#include <linux/ieee80211.h>
 #include <net/iw_handler.h>
-#include <net/ieee80211.h>
 
 #include "host.h"
 #include "decl.h"
@@ -223,7 +222,7 @@ u8 lbs_data_rate_to_fw_index(u32 rate)
 static ssize_t lbs_anycast_get(struct device *dev,
                struct device_attribute *attr, char * buf)
 {
-       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
        struct cmd_ds_mesh_access mesh_access;
        int ret;
 
@@ -242,7 +241,7 @@ static ssize_t lbs_anycast_get(struct device *dev,
 static ssize_t lbs_anycast_set(struct device *dev,
                struct device_attribute *attr, const char * buf, size_t count)
 {
-       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
        struct cmd_ds_mesh_access mesh_access;
        uint32_t datum;
        int ret;
@@ -270,7 +269,7 @@ static void lbs_remove_mesh(struct lbs_private *priv);
 static ssize_t lbs_rtap_get(struct device *dev,
                struct device_attribute *attr, char * buf)
 {
-       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
        return snprintf(buf, 5, "0x%X\n", priv->monitormode);
 }
 
@@ -281,7 +280,7 @@ static ssize_t lbs_rtap_set(struct device *dev,
                struct device_attribute *attr, const char * buf, size_t count)
 {
        int monitor_mode;
-       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
 
        sscanf(buf, "%x", &monitor_mode);
        if (monitor_mode) {
@@ -332,7 +331,7 @@ static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set );
 static ssize_t lbs_mesh_get(struct device *dev,
                struct device_attribute *attr, char * buf)
 {
-       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
        return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
 }
 
@@ -342,7 +341,7 @@ static ssize_t lbs_mesh_get(struct device *dev,
 static ssize_t lbs_mesh_set(struct device *dev,
                struct device_attribute *attr, const char * buf, size_t count)
 {
-       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
        int enable;
        int ret, action = CMD_ACT_MESH_CONFIG_STOP;
 
@@ -393,7 +392,7 @@ static struct attribute_group lbs_mesh_attr_group = {
  */
 static int lbs_dev_open(struct net_device *dev)
 {
-       struct lbs_private *priv = (struct lbs_private *) dev->priv ;
+       struct lbs_private *priv = netdev_priv(dev) ;
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_NET);
@@ -435,7 +434,7 @@ static int lbs_dev_open(struct net_device *dev)
  */
 static int lbs_mesh_stop(struct net_device *dev)
 {
-       struct lbs_private *priv = (struct lbs_private *) (dev->priv);
+       struct lbs_private *priv = dev->ml_priv;
 
        lbs_deb_enter(LBS_DEB_MESH);
        spin_lock_irq(&priv->driver_lock);
@@ -462,7 +461,7 @@ static int lbs_mesh_stop(struct net_device *dev)
  */
 static int lbs_eth_stop(struct net_device *dev)
 {
-       struct lbs_private *priv = (struct lbs_private *) dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        lbs_deb_enter(LBS_DEB_NET);
 
@@ -479,7 +478,7 @@ static int lbs_eth_stop(struct net_device *dev)
 
 static void lbs_tx_timeout(struct net_device *dev)
 {
-       struct lbs_private *priv = (struct lbs_private *) dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        lbs_deb_enter(LBS_DEB_TX);
 
@@ -531,7 +530,7 @@ EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
  */
 static struct net_device_stats *lbs_get_stats(struct net_device *dev)
 {
-       struct lbs_private *priv = (struct lbs_private *) dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        lbs_deb_enter(LBS_DEB_NET);
        return &priv->stats;
@@ -540,7 +539,7 @@ static struct net_device_stats *lbs_get_stats(struct net_device *dev)
 static int lbs_set_mac_address(struct net_device *dev, void *addr)
 {
        int ret = 0;
-       struct lbs_private *priv = (struct lbs_private *) dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        struct sockaddr *phwaddr = addr;
        struct cmd_ds_802_11_mac_address cmd;
 
@@ -588,7 +587,6 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
 {
        int i = nr_addrs;
        struct dev_mc_list *mc_list;
-       DECLARE_MAC_BUF(mac);
 
        if ((dev->flags & (IFF_UP|IFF_MULTICAST)) != (IFF_UP|IFF_MULTICAST))
                return nr_addrs;
@@ -596,16 +594,16 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
        netif_addr_lock_bh(dev);
        for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) {
                if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) {
-                       lbs_deb_net("mcast address %s:%s skipped\n", dev->name,
-                                   print_mac(mac, mc_list->dmi_addr));
+                       lbs_deb_net("mcast address %s:%pM skipped\n", dev->name,
+                                   mc_list->dmi_addr);
                        continue;
                }
 
                if (i == MRVDRV_MAX_MULTICAST_LIST_SIZE)
                        break;
                memcpy(&cmd->maclist[6*i], mc_list->dmi_addr, ETH_ALEN);
-               lbs_deb_net("mcast address %s:%s added to filter\n", dev->name,
-                           print_mac(mac, mc_list->dmi_addr));
+               lbs_deb_net("mcast address %s:%pM added to filter\n", dev->name,
+                           mc_list->dmi_addr);
                i++;
        }
        netif_addr_unlock_bh(dev);
@@ -674,7 +672,7 @@ static void lbs_set_mcast_worker(struct work_struct *work)
 
 static void lbs_set_multicast_list(struct net_device *dev)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        schedule_work(&priv->mcast_work);
 }
@@ -690,7 +688,7 @@ static void lbs_set_multicast_list(struct net_device *dev)
 static int lbs_thread(void *data)
 {
        struct net_device *dev = data;
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        wait_queue_t wait;
 
        lbs_deb_enter(LBS_DEB_THREAD);
@@ -1125,7 +1123,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
                lbs_pr_err("init ethX device failed\n");
                goto done;
        }
-       priv = dev->priv;
+       priv = netdev_priv(dev);
 
        if (lbs_init_adapter(priv)) {
                lbs_pr_err("failed to initialize adapter structure.\n");
@@ -1378,7 +1376,7 @@ static int lbs_add_mesh(struct lbs_private *priv)
                ret = -ENOMEM;
                goto done;
        }
-       mesh_dev->priv = priv;
+       mesh_dev->ml_priv = priv;
        priv->mesh_dev = mesh_dev;
 
        mesh_dev->open = lbs_dev_open;
@@ -1591,7 +1589,7 @@ static int lbs_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static struct net_device_stats *lbs_rtap_get_stats(struct net_device *dev)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = dev->ml_priv;
        lbs_deb_enter(LBS_DEB_NET);
        return &priv->stats;
 }
@@ -1632,7 +1630,7 @@ static int lbs_add_rtap(struct lbs_private *priv)
        rtap_dev->stop = lbs_rtap_stop;
        rtap_dev->get_stats = lbs_rtap_get_stats;
        rtap_dev->hard_start_xmit = lbs_rtap_hard_start_xmit;
-       rtap_dev->priv = priv;
+       rtap_dev->ml_priv = priv;
        SET_NETDEV_DEV(rtap_dev, priv->dev->dev.parent);
 
        ret = register_netdev(rtap_dev);
@@ -1647,33 +1645,6 @@ out:
        return ret;
 }
 
-#ifndef CONFIG_IEEE80211
-const char *escape_essid(const char *essid, u8 essid_len)
-{
-       static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
-       const char *s = essid;
-       char *d = escaped;
-
-       if (ieee80211_is_empty_essid(essid, essid_len)) {
-               memcpy(escaped, "<hidden>", sizeof("<hidden>"));
-               return escaped;
-       }
-
-       essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
-       while (essid_len--) {
-               if (*s == '\0') {
-                       *d++ = '\\';
-                       *d++ = '0';
-                       s++;
-               } else {
-                       *d++ = *s++;
-               }
-       }
-       *d = '\0';
-       return escaped;
-}
-#endif
-
 module_init(lbs_init_module);
 module_exit(lbs_exit_module);
 
index 3309a9c3cfef3f66c84f5f1cb67388dda176c5e6..d42b7a5a1b3f32a564579771e19149429348db5b 100644 (file)
@@ -18,7 +18,7 @@
 static int mesh_get_default_parameters(struct device *dev,
                                       struct mrvl_mesh_defaults *defs)
 {
-       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
        struct cmd_ds_mesh_config cmd;
        int ret;
 
@@ -57,7 +57,7 @@ static ssize_t bootflag_get(struct device *dev,
 static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
                            const char *buf, size_t count)
 {
-       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
        struct cmd_ds_mesh_config cmd;
        uint32_t datum;
        int ret;
@@ -100,7 +100,7 @@ static ssize_t boottime_get(struct device *dev,
 static ssize_t boottime_set(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t count)
 {
-       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
        struct cmd_ds_mesh_config cmd;
        uint32_t datum;
        int ret;
@@ -152,7 +152,7 @@ static ssize_t channel_get(struct device *dev,
 static ssize_t channel_set(struct device *dev, struct device_attribute *attr,
                           const char *buf, size_t count)
 {
-       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
        struct cmd_ds_mesh_config cmd;
        uint32_t datum;
        int ret;
@@ -210,7 +210,7 @@ static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
        struct cmd_ds_mesh_config cmd;
        struct mrvl_mesh_defaults defs;
        struct mrvl_meshie *ie;
-       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
        int len;
        int ret;
 
@@ -233,7 +233,7 @@ static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
        /* SSID len */
        ie->val.mesh_id_len = len;
        /* IE len */
-       ie->hdr.len = sizeof(struct mrvl_meshie_val) - IW_ESSID_MAX_SIZE + len;
+       ie->len = sizeof(struct mrvl_meshie_val) - IW_ESSID_MAX_SIZE + len;
 
        ret = lbs_mesh_config_send(priv, &cmd, CMD_ACT_MESH_CONFIG_SET,
                                   CMD_TYPE_MESH_SET_MESH_IE);
@@ -269,7 +269,7 @@ static ssize_t protocol_id_set(struct device *dev,
        struct cmd_ds_mesh_config cmd;
        struct mrvl_mesh_defaults defs;
        struct mrvl_meshie *ie;
-       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
        uint32_t datum;
        int ret;
 
@@ -323,7 +323,7 @@ static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
        struct cmd_ds_mesh_config cmd;
        struct mrvl_mesh_defaults defs;
        struct mrvl_meshie *ie;
-       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
        uint32_t datum;
        int ret;
 
@@ -377,7 +377,7 @@ static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
        struct cmd_ds_mesh_config cmd;
        struct mrvl_mesh_defaults defs;
        struct mrvl_meshie *ie;
-       struct lbs_private *priv = to_net_dev(dev)->priv;
+       struct lbs_private *priv = netdev_priv(to_net_dev(dev));
        uint32_t datum;
        int ret;
 
index 22c4c611052147ef3c2e1b3d01f1d64026ad9bec..57f6c12cda2085a902a8fae4e1e950c138f34475 100644 (file)
@@ -4,8 +4,11 @@
   * IOCTL handlers as well as command preperation and response routines
   *  for sending scan commands to the firmware.
   */
+#include <linux/types.h>
 #include <linux/etherdevice.h>
+#include <linux/if_arp.h>
 #include <asm/unaligned.h>
+#include <net/lib80211.h>
 
 #include "host.h"
 #include "decl.h"
@@ -52,6 +55,8 @@
 //! Scan time specified in the channel TLV for each channel for active scans
 #define MRVDRV_ACTIVE_SCAN_CHAN_TIME   100
 
+#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
+
 static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy,
                              struct cmd_header *resp);
 
@@ -359,7 +364,7 @@ int lbs_scan_networks(struct lbs_private *priv, int full_scan)
 #ifdef CONFIG_LIBERTAS_DEBUG
        struct bss_descriptor *iter;
        int i = 0;
-       DECLARE_MAC_BUF(mac);
+       DECLARE_SSID_BUF(ssid);
 #endif
 
        lbs_deb_enter_args(LBS_DEB_SCAN, "full_scan %d", full_scan);
@@ -451,9 +456,9 @@ int lbs_scan_networks(struct lbs_private *priv, int full_scan)
        mutex_lock(&priv->lock);
        lbs_deb_scan("scan table:\n");
        list_for_each_entry(iter, &priv->network_list, list)
-               lbs_deb_scan("%02d: BSSID %s, RSSI %d, SSID '%s'\n",
-                            i++, print_mac(mac, iter->bssid), iter->rssi,
-                            escape_essid(iter->ssid, iter->ssid_len));
+               lbs_deb_scan("%02d: BSSID %pM, RSSI %d, SSID '%s'\n",
+                            i++, iter->bssid, iter->rssi,
+                            print_ssid(ssid, iter->ssid, iter->ssid_len));
        mutex_unlock(&priv->lock);
 #endif
 
@@ -512,7 +517,7 @@ static int lbs_process_bss(struct bss_descriptor *bss,
        struct ieeetypes_dsparamset *pDS;
        struct ieeetypes_cfparamset *pCF;
        struct ieeetypes_ibssparamset *pibss;
-       DECLARE_MAC_BUF(mac);
+       DECLARE_SSID_BUF(ssid);
        struct ieeetypes_countryinfoset *pcountryinfo;
        uint8_t *pos, *end, *p;
        uint8_t n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0;
@@ -544,7 +549,7 @@ static int lbs_process_bss(struct bss_descriptor *bss,
        *bytesleft -= beaconsize;
 
        memcpy(bss->bssid, pos, ETH_ALEN);
-       lbs_deb_scan("process_bss: BSSID %s\n", print_mac(mac, bss->bssid));
+       lbs_deb_scan("process_bss: BSSID %pM\n", bss->bssid);
        pos += ETH_ALEN;
 
        if ((end - pos) < 12) {
@@ -588,38 +593,36 @@ static int lbs_process_bss(struct bss_descriptor *bss,
 
        /* process variable IE */
        while (pos <= end - 2) {
-               struct ieee80211_info_element * elem = (void *)pos;
-
-               if (pos + elem->len > end) {
+               if (pos + pos[1] > end) {
                        lbs_deb_scan("process_bss: error in processing IE, "
                                     "bytes left < IE length\n");
                        break;
                }
 
-               switch (elem->id) {
-               case MFIE_TYPE_SSID:
-                       bss->ssid_len = min_t(int, 32, elem->len);
-                       memcpy(bss->ssid, elem->data, bss->ssid_len);
+               switch (pos[0]) {
+               case WLAN_EID_SSID:
+                       bss->ssid_len = min_t(int, IEEE80211_MAX_SSID_LEN, pos[1]);
+                       memcpy(bss->ssid, pos + 2, bss->ssid_len);
                        lbs_deb_scan("got SSID IE: '%s', len %u\n",
-                                    escape_essid(bss->ssid, bss->ssid_len),
+                                    print_ssid(ssid, bss->ssid, bss->ssid_len),
                                     bss->ssid_len);
                        break;
 
-               case MFIE_TYPE_RATES:
-                       n_basic_rates = min_t(uint8_t, MAX_RATES, elem->len);
-                       memcpy(bss->rates, elem->data, n_basic_rates);
+               case WLAN_EID_SUPP_RATES:
+                       n_basic_rates = min_t(uint8_t, MAX_RATES, pos[1]);
+                       memcpy(bss->rates, pos + 2, n_basic_rates);
                        got_basic_rates = 1;
                        lbs_deb_scan("got RATES IE\n");
                        break;
 
-               case MFIE_TYPE_FH_SET:
+               case WLAN_EID_FH_PARAMS:
                        pFH = (struct ieeetypes_fhparamset *) pos;
                        memmove(&bss->phyparamset.fhparamset, pFH,
                                sizeof(struct ieeetypes_fhparamset));
                        lbs_deb_scan("got FH IE\n");
                        break;
 
-               case MFIE_TYPE_DS_SET:
+               case WLAN_EID_DS_PARAMS:
                        pDS = (struct ieeetypes_dsparamset *) pos;
                        bss->channel = pDS->currentchan;
                        memcpy(&bss->phyparamset.dsparamset, pDS,
@@ -627,14 +630,14 @@ static int lbs_process_bss(struct bss_descriptor *bss,
                        lbs_deb_scan("got DS IE, channel %d\n", bss->channel);
                        break;
 
-               case MFIE_TYPE_CF_SET:
+               case WLAN_EID_CF_PARAMS:
                        pCF = (struct ieeetypes_cfparamset *) pos;
                        memcpy(&bss->ssparamset.cfparamset, pCF,
                               sizeof(struct ieeetypes_cfparamset));
                        lbs_deb_scan("got CF IE\n");
                        break;
 
-               case MFIE_TYPE_IBSS_SET:
+               case WLAN_EID_IBSS_PARAMS:
                        pibss = (struct ieeetypes_ibssparamset *) pos;
                        bss->atimwindow = le16_to_cpu(pibss->atimwindow);
                        memmove(&bss->ssparamset.ibssparamset, pibss,
@@ -642,7 +645,7 @@ static int lbs_process_bss(struct bss_descriptor *bss,
                        lbs_deb_scan("got IBSS IE\n");
                        break;
 
-               case MFIE_TYPE_COUNTRY:
+               case WLAN_EID_COUNTRY:
                        pcountryinfo = (struct ieeetypes_countryinfoset *) pos;
                        lbs_deb_scan("got COUNTRY IE\n");
                        if (pcountryinfo->len < sizeof(pcountryinfo->countrycode)
@@ -659,7 +662,7 @@ static int lbs_process_bss(struct bss_descriptor *bss,
                                    (int) (pcountryinfo->len + 2));
                        break;
 
-               case MFIE_TYPE_RATES_EX:
+               case WLAN_EID_EXT_SUPP_RATES:
                        /* only process extended supported rate if data rate is
                         * already found. Data rate IE should come before
                         * extended supported rate IE
@@ -670,50 +673,51 @@ static int lbs_process_bss(struct bss_descriptor *bss,
                                break;
                        }
 
-                       n_ex_rates = elem->len;
+                       n_ex_rates = pos[1];
                        if (n_basic_rates + n_ex_rates > MAX_RATES)
                                n_ex_rates = MAX_RATES - n_basic_rates;
 
                        p = bss->rates + n_basic_rates;
-                       memcpy(p, elem->data, n_ex_rates);
+                       memcpy(p, pos + 2, n_ex_rates);
                        break;
 
-               case MFIE_TYPE_GENERIC:
-                       if (elem->len >= 4 &&
-                           elem->data[0] == 0x00 && elem->data[1] == 0x50 &&
-                           elem->data[2] == 0xf2 && elem->data[3] == 0x01) {
-                               bss->wpa_ie_len = min(elem->len + 2, MAX_WPA_IE_LEN);
-                               memcpy(bss->wpa_ie, elem, bss->wpa_ie_len);
+               case WLAN_EID_GENERIC:
+                       if (pos[1] >= 4 &&
+                           pos[2] == 0x00 && pos[3] == 0x50 &&
+                           pos[4] == 0xf2 && pos[5] == 0x01) {
+                               bss->wpa_ie_len = min(pos[1] + 2, MAX_WPA_IE_LEN);
+                               memcpy(bss->wpa_ie, pos, bss->wpa_ie_len);
                                lbs_deb_scan("got WPA IE\n");
-                               lbs_deb_hex(LBS_DEB_SCAN, "WPA IE", bss->wpa_ie, elem->len);
-                       } else if (elem->len >= MARVELL_MESH_IE_LENGTH &&
-                                  elem->data[0] == 0x00 && elem->data[1] == 0x50 &&
-                                  elem->data[2] == 0x43 && elem->data[3] == 0x04) {
+                               lbs_deb_hex(LBS_DEB_SCAN, "WPA IE", bss->wpa_ie,
+                                           bss->wpa_ie_len);
+                       } else if (pos[1] >= MARVELL_MESH_IE_LENGTH &&
+                                  pos[2] == 0x00 && pos[3] == 0x50 &&
+                                  pos[4] == 0x43 && pos[4] == 0x04) {
                                lbs_deb_scan("got mesh IE\n");
                                bss->mesh = 1;
                        } else {
                                lbs_deb_scan("got generic IE: %02x:%02x:%02x:%02x, len %d\n",
-                                       elem->data[0], elem->data[1],
-                                       elem->data[2], elem->data[3],
-                                       elem->len);
+                                       pos[2], pos[3],
+                                       pos[4], pos[5],
+                                       pos[1]);
                        }
                        break;
 
-               case MFIE_TYPE_RSN:
+               case WLAN_EID_RSN:
                        lbs_deb_scan("got RSN IE\n");
-                       bss->rsn_ie_len = min(elem->len + 2, MAX_WPA_IE_LEN);
-                       memcpy(bss->rsn_ie, elem, bss->rsn_ie_len);
+                       bss->rsn_ie_len = min(pos[1] + 2, MAX_WPA_IE_LEN);
+                       memcpy(bss->rsn_ie, pos, bss->rsn_ie_len);
                        lbs_deb_hex(LBS_DEB_SCAN, "process_bss: RSN_IE",
-                                   bss->rsn_ie, elem->len);
+                                   bss->rsn_ie, bss->rsn_ie_len);
                        break;
 
                default:
                        lbs_deb_scan("got IE 0x%04x, len %d\n",
-                                    elem->id, elem->len);
+                                    pos[0], pos[1]);
                        break;
                }
 
-               pos += elem->len + 2;
+               pos += pos[1] + 2;
        }
 
        /* Timestamp */
@@ -741,10 +745,11 @@ done:
 int lbs_send_specific_ssid_scan(struct lbs_private *priv, uint8_t *ssid,
                                uint8_t ssid_len)
 {
+       DECLARE_SSID_BUF(ssid_buf);
        int ret = 0;
 
        lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s'\n",
-                          escape_essid(ssid, ssid_len));
+                          print_ssid(ssid_buf, ssid, ssid_len));
 
        if (!ssid_len)
                goto out;
@@ -939,7 +944,8 @@ out:
 int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
                 union iwreq_data *wrqu, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       DECLARE_SSID_BUF(ssid);
+       struct lbs_private *priv = netdev_priv(dev);
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_WEXT);
@@ -968,7 +974,7 @@ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
                priv->scan_ssid_len = req->essid_len;
                memcpy(priv->scan_ssid, req->essid, priv->scan_ssid_len);
                lbs_deb_wext("set_scan, essid '%s'\n",
-                       escape_essid(priv->scan_ssid, priv->scan_ssid_len));
+                       print_ssid(ssid, priv->scan_ssid, priv->scan_ssid_len));
        } else {
                priv->scan_ssid_len = 0;
        }
@@ -1002,7 +1008,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
                 struct iw_point *dwrq, char *extra)
 {
 #define SCAN_ITEM_SIZE 128
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        int err = 0;
        char *ev = extra;
        char *stop = ev + dwrq->length;
@@ -1151,7 +1157,6 @@ static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy,
                struct bss_descriptor new;
                struct bss_descriptor *found = NULL;
                struct bss_descriptor *oldest = NULL;
-               DECLARE_MAC_BUF(mac);
 
                /* Process the data fields and IEs returned for this BSS */
                memset(&new, 0, sizeof (struct bss_descriptor));
@@ -1190,7 +1195,7 @@ static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy,
                        continue;
                }
 
-               lbs_deb_scan("SCAN_RESP: BSSID %s\n", print_mac(mac, new.bssid));
+               lbs_deb_scan("SCAN_RESP: BSSID %pM\n", new.bssid);
 
                /* Copy the locally created newbssentry to the scan table */
                memcpy(found, &new, offsetof(struct bss_descriptor, list));
index 9e07b0464a8e1e432d82cb787f9e34ec95afe68f..fab7d5d097fc73f5241117e35b4adc32b30a6c1c 100644 (file)
@@ -7,6 +7,10 @@
 #ifndef _LBS_SCAN_H
 #define _LBS_SCAN_H
 
+#include <net/iw_handler.h>
+
+#define MAX_NETWORK_COUNT 128
+
 /**
  *  @brief Maximum number of channels that can be sent in a setuserscan ioctl
  */
index a4972fed294171dfacf99135e4de9cf7bd206371..dac462641170e6193da4f04cfd44e39222520ba3 100644 (file)
@@ -60,7 +60,7 @@ static u32 convert_radiotap_rate_to_mv(u8 rate)
 int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        unsigned long flags;
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        struct txpd *txpd;
        char *p802x_hdr;
        uint16_t pkt_len;
index e0c2599da92f182c2e3a31b616d04fd9c2ac4323..fb7a2d1a2525e5efae1d78c9dcf0edec7ab1a76c 100644 (file)
@@ -7,7 +7,6 @@
 #include <linux/if_ether.h>
 #include <asm/byteorder.h>
 #include <linux/wireless.h>
-#include <net/ieee80211.h>
 
 struct ieeetypes_cfparamset {
        u8 elementid;
@@ -258,7 +257,7 @@ struct mrvlietypes_ledbhv {
  * Note that the len member of the ieee80211_info_element varies depending on
  * the mesh_id_len */
 struct mrvl_meshie_val {
-       uint8_t oui[P80211_OUI_LEN];
+       uint8_t oui[3];
        uint8_t type;
        uint8_t subtype;
        uint8_t version;
@@ -270,7 +269,7 @@ struct mrvl_meshie_val {
 } __attribute__ ((packed));
 
 struct mrvl_meshie {
-       struct ieee80211_info_element hdr;
+       u8 id, len;
        struct mrvl_meshie_val val;
 } __attribute__ ((packed));
 
index 82c3e5a50ea695602fa844b7cc5ce93493f1b0d3..c6102e08179e6ba7d9fcc09d7fb8a26da721024b 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/wireless.h>
 #include <linux/bitops.h>
 
-#include <net/ieee80211.h>
+#include <net/lib80211.h>
 #include <net/iw_handler.h>
 
 #include "host.h"
@@ -163,7 +163,7 @@ static int lbs_get_name(struct net_device *dev, struct iw_request_info *info,
 static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info,
                         struct iw_freq *fwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        struct chan_freq_power *cfp;
 
        lbs_deb_enter(LBS_DEB_WEXT);
@@ -189,7 +189,7 @@ static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info,
 static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info,
                        struct sockaddr *awrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -207,7 +207,7 @@ static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info,
 static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info,
                         struct iw_point *dwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -231,7 +231,7 @@ static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info,
 static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info,
                         struct iw_point *dwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -248,7 +248,7 @@ static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info,
 static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
                         struct iw_point *dwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -273,7 +273,7 @@ static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
                        struct iw_param *vwrq, char *extra)
 {
        int ret = 0;
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        u32 val = vwrq->value;
 
        lbs_deb_enter(LBS_DEB_WEXT);
@@ -293,7 +293,7 @@ static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
 static int lbs_get_rts(struct net_device *dev, struct iw_request_info *info,
                        struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        int ret = 0;
        u16 val = 0;
 
@@ -315,7 +315,7 @@ out:
 static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info,
                         struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        int ret = 0;
        u32 val = vwrq->value;
 
@@ -336,7 +336,7 @@ static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info,
 static int lbs_get_frag(struct net_device *dev, struct iw_request_info *info,
                         struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        int ret = 0;
        u16 val = 0;
 
@@ -359,7 +359,7 @@ out:
 static int lbs_get_mode(struct net_device *dev,
                         struct iw_request_info *info, u32 * uwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -385,7 +385,7 @@ static int lbs_get_txpow(struct net_device *dev,
                          struct iw_request_info *info,
                          struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        s16 curlevel = 0;
        int ret = 0;
 
@@ -418,7 +418,7 @@ out:
 static int lbs_set_retry(struct net_device *dev, struct iw_request_info *info,
                          struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        int ret = 0;
        u16 slimit = 0, llimit = 0;
 
@@ -466,7 +466,7 @@ out:
 static int lbs_get_retry(struct net_device *dev, struct iw_request_info *info,
                          struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        int ret = 0;
        u16 val = 0;
 
@@ -542,7 +542,7 @@ static int lbs_get_range(struct net_device *dev, struct iw_request_info *info,
                          struct iw_point *dwrq, char *extra)
 {
        int i, j;
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        struct iw_range *range = (struct iw_range *)extra;
        struct chan_freq_power *cfp;
        u8 rates[MAX_RATES + 1];
@@ -708,7 +708,7 @@ out:
 static int lbs_set_power(struct net_device *dev, struct iw_request_info *info,
                          struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -758,7 +758,7 @@ static int lbs_set_power(struct net_device *dev, struct iw_request_info *info,
 static int lbs_get_power(struct net_device *dev, struct iw_request_info *info,
                          struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -781,7 +781,7 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev)
                EXCELLENT = 95,
                PERFECT = 100
        };
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        u32 rssi_qual;
        u32 tx_qual;
        u32 quality = 0;
@@ -886,7 +886,7 @@ static int lbs_set_freq(struct net_device *dev, struct iw_request_info *info,
                  struct iw_freq *fwrq, char *extra)
 {
        int ret = -EINVAL;
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        struct chan_freq_power *cfp;
        struct assoc_request * assoc_req;
 
@@ -943,7 +943,7 @@ static int lbs_mesh_set_freq(struct net_device *dev,
                             struct iw_request_info *info,
                             struct iw_freq *fwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        struct chan_freq_power *cfp;
        int ret = -EINVAL;
 
@@ -994,7 +994,7 @@ out:
 static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
                  struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        u8 new_rate = 0;
        int ret = -EINVAL;
        u8 rates[MAX_RATES + 1];
@@ -1054,7 +1054,7 @@ out:
 static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info,
                  struct iw_param *vwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -1079,7 +1079,7 @@ static int lbs_set_mode(struct net_device *dev,
                  struct iw_request_info *info, u32 * uwrq, char *extra)
 {
        int ret = 0;
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        struct assoc_request * assoc_req;
 
        lbs_deb_enter(LBS_DEB_WEXT);
@@ -1124,7 +1124,7 @@ static int lbs_get_encode(struct net_device *dev,
                           struct iw_request_info *info,
                           struct iw_point *dwrq, u8 * extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 
        lbs_deb_enter(LBS_DEB_WEXT);
@@ -1319,7 +1319,7 @@ static int lbs_set_encode(struct net_device *dev,
                    struct iw_point *dwrq, char *extra)
 {
        int ret = 0;
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        struct assoc_request * assoc_req;
        u16 is_default = 0, index = 0, set_tx_key = 0;
 
@@ -1395,7 +1395,7 @@ static int lbs_get_encodeext(struct net_device *dev,
                              char *extra)
 {
        int ret = -EINVAL;
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
        int index, max_key_len;
 
@@ -1501,7 +1501,7 @@ static int lbs_set_encodeext(struct net_device *dev,
                              char *extra)
 {
        int ret = 0;
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
        int alg = ext->alg;
        struct assoc_request * assoc_req;
@@ -1639,7 +1639,7 @@ static int lbs_set_genie(struct net_device *dev,
                          struct iw_point *dwrq,
                          char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        int ret = 0;
        struct assoc_request * assoc_req;
 
@@ -1685,7 +1685,7 @@ static int lbs_get_genie(struct net_device *dev,
                          char *extra)
 {
        int ret = 0;
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -1713,7 +1713,7 @@ static int lbs_set_auth(struct net_device *dev,
                         struct iw_param *dwrq,
                         char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        struct assoc_request * assoc_req;
        int ret = 0;
        int updated = 0;
@@ -1816,7 +1816,7 @@ static int lbs_get_auth(struct net_device *dev,
                         char *extra)
 {
        int ret = 0;
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -1857,7 +1857,7 @@ static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
                   struct iw_param *vwrq, char *extra)
 {
        int ret = 0;
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        s16 dbm = (s16) vwrq->value;
 
        lbs_deb_enter(LBS_DEB_WEXT);
@@ -1936,7 +1936,7 @@ out:
 static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info,
                   struct iw_point *dwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -1971,12 +1971,13 @@ static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info,
 static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info,
                   struct iw_point *dwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        int ret = 0;
        u8 ssid[IW_ESSID_MAX_SIZE];
        u8 ssid_len = 0;
        struct assoc_request * assoc_req;
        int in_ssid_len = dwrq->length;
+       DECLARE_SSID_BUF(ssid_buf);
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -2005,7 +2006,7 @@ static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info,
                lbs_deb_wext("requested any SSID\n");
        } else {
                lbs_deb_wext("requested SSID '%s'\n",
-                            escape_essid(ssid, ssid_len));
+                            print_ssid(ssid_buf, ssid, ssid_len));
        }
 
 out:
@@ -2039,7 +2040,7 @@ static int lbs_mesh_get_essid(struct net_device *dev,
                              struct iw_request_info *info,
                              struct iw_point *dwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -2057,7 +2058,7 @@ static int lbs_mesh_set_essid(struct net_device *dev,
                              struct iw_request_info *info,
                              struct iw_point *dwrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_WEXT);
@@ -2101,10 +2102,9 @@ static int lbs_mesh_set_essid(struct net_device *dev,
 static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
                 struct sockaddr *awrq, char *extra)
 {
-       struct lbs_private *priv = dev->priv;
+       struct lbs_private *priv = netdev_priv(dev);
        struct assoc_request * assoc_req;
        int ret = 0;
-       DECLARE_MAC_BUF(mac);
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -2114,7 +2114,7 @@ static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
        if (awrq->sa_family != ARPHRD_ETHER)
                return -EINVAL;
 
-       lbs_deb_wext("ASSOC: WAP: sa_data %s\n", print_mac(mac, awrq->sa_data));
+       lbs_deb_wext("ASSOC: WAP: sa_data %pM\n", awrq->sa_data);
 
        mutex_lock(&priv->lock);
 
index fdbcf8ba3e8a0c6bc02036c05d7c9bd7d9c19dc2..3d3914c83b145388c6d2afc6c6c6fc124f8b2469 100644 (file)
@@ -79,7 +79,6 @@ int lbtf_update_hw_spec(struct lbtf_private *priv)
        struct cmd_ds_get_hw_spec cmd;
        int ret = -1;
        u32 i;
-       DECLARE_MAC_BUF(mac);
 
        memset(&cmd, 0, sizeof(cmd));
        cmd.hdr.size = cpu_to_le16(sizeof(cmd));
@@ -96,8 +95,8 @@ int lbtf_update_hw_spec(struct lbtf_private *priv)
        priv->fwrelease = (priv->fwrelease << 8) |
                (priv->fwrelease >> 24 & 0xff);
 
-       printk(KERN_INFO "libertastf: %s, fw %u.%u.%up%u, cap 0x%08x\n",
-               print_mac(mac, cmd.permanentaddr),
+       printk(KERN_INFO "libertastf: %pM, fw %u.%u.%up%u, cap 0x%08x\n",
+               cmd.permanentaddr,
                priv->fwrelease >> 24 & 0xff,
                priv->fwrelease >> 16 & 0xff,
                priv->fwrelease >>  8 & 0xff,
index 1cc03a8dd67acdfaca7c93a09c39b02428565c1f..59634c33b1f9194f4e10ed8fc36e2d9aed30ef4e 100644 (file)
@@ -331,7 +331,7 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
        /* Fill the receive configuration URB and initialise the Rx call back */
        usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
                          usb_rcvbulkpipe(cardp->udev, cardp->ep_in),
-                         (void *) (skb->tail),
+                         skb_tail_pointer(skb),
                          MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn, cardp);
 
        cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
index feff945ad856368e737eac8a344352b947ad73c5..d1fc305de5fe03c755368b70690d3f81d5fe54ba 100644 (file)
@@ -354,9 +354,11 @@ static void lbtf_op_remove_interface(struct ieee80211_hw *hw,
        priv->vif = NULL;
 }
 
-static int lbtf_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct lbtf_private *priv = hw->priv;
+       struct ieee80211_conf *conf = &hw->conf;
+
        if (conf->channel->center_freq != priv->cur_freq) {
                priv->cur_freq = conf->channel->center_freq;
                lbtf_set_channel(priv, conf->channel->hw_value);
@@ -590,14 +592,14 @@ EXPORT_SYMBOL_GPL(lbtf_remove_card);
 void lbtf_send_tx_feedback(struct lbtf_private *priv, u8 retrycnt, u8 fail)
 {
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(priv->tx_skb);
-       memset(&info->status, 0, sizeof(info->status));
+
+       ieee80211_tx_info_clear_status(info);
        /*
         * Commented out, otherwise we never go beyond 1Mbit/s using mac80211
         * default pid rc algorithm.
         *
         * info->status.retry_count = MRVL_DEFAULT_RETRIES - retrycnt;
         */
-       info->status.excessive_retries = fail ? 1 : 0;
        if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && !fail)
                info->flags |= IEEE80211_TX_STAT_ACK;
        skb_pull(priv->tx_skb, sizeof(struct txpd));
index 1a019e98dac3ee8ef0b7be504a6cee8af6a36369..b9230da925ee7a6d98a02d1d5d5b39b38a374138 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/if_arp.h>
 #include <linux/rtnetlink.h>
 #include <linux/etherdevice.h>
+#include <linux/debugfs.h>
 
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Software simulator of 802.11 radio(s) for mac80211");
@@ -32,6 +33,9 @@ MODULE_PARM_DESC(radios, "Number of simulated radios");
 
 struct hwsim_vif_priv {
        u32 magic;
+       u8 bssid[ETH_ALEN];
+       bool assoc;
+       u16 aid;
 };
 
 #define HWSIM_VIF_MAGIC        0x69537748
@@ -63,13 +67,13 @@ struct hwsim_sta_priv {
 static inline void hwsim_check_sta_magic(struct ieee80211_sta *sta)
 {
        struct hwsim_sta_priv *sp = (void *)sta->drv_priv;
-       WARN_ON(sp->magic != HWSIM_VIF_MAGIC);
+       WARN_ON(sp->magic != HWSIM_STA_MAGIC);
 }
 
 static inline void hwsim_set_sta_magic(struct ieee80211_sta *sta)
 {
        struct hwsim_sta_priv *sp = (void *)sta->drv_priv;
-       sp->magic = HWSIM_VIF_MAGIC;
+       sp->magic = HWSIM_STA_MAGIC;
 }
 
 static inline void hwsim_clear_sta_magic(struct ieee80211_sta *sta)
@@ -132,6 +136,12 @@ struct mac80211_hwsim_data {
        unsigned int rx_filter;
        int started;
        struct timer_list beacon_timer;
+       enum ps_mode {
+               PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL
+       } ps;
+       bool ps_poll_pending;
+       struct dentry *debugfs;
+       struct dentry *debugfs_ps;
 };
 
 
@@ -196,6 +206,34 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
 }
 
 
+static bool hwsim_ps_rx_ok(struct mac80211_hwsim_data *data,
+                          struct sk_buff *skb)
+{
+       switch (data->ps) {
+       case PS_DISABLED:
+               return true;
+       case PS_ENABLED:
+               return false;
+       case PS_AUTO_POLL:
+               /* TODO: accept (some) Beacons by default and other frames only
+                * if pending PS-Poll has been sent */
+               return true;
+       case PS_MANUAL_POLL:
+               /* Allow unicast frames to own address if there is a pending
+                * PS-Poll */
+               if (data->ps_poll_pending &&
+                   memcmp(data->hw->wiphy->perm_addr, skb->data + 4,
+                          ETH_ALEN) == 0) {
+                       data->ps_poll_pending = false;
+                       return true;
+               }
+               return false;
+       }
+
+       return true;
+}
+
+
 static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
                                    struct sk_buff *skb)
 {
@@ -209,9 +247,12 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
        /* TODO: set mactime */
        rx_status.freq = data->channel->center_freq;
        rx_status.band = data->channel->band;
-       rx_status.rate_idx = info->tx_rate_idx;
+       rx_status.rate_idx = info->control.rates[0].idx;
        /* TODO: simulate signal strength (and optional packet drop) */
 
+       if (data->ps != PS_DISABLED)
+               hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
+
        /* Copy skb to all enabled radios that are on the current frequency */
        spin_lock(&hwsim_radio_lock);
        list_for_each_entry(data2, &hwsim_radios, list) {
@@ -221,6 +262,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
                        continue;
 
                if (!data2->started || !data2->radio_enabled ||
+                   !hwsim_ps_rx_ok(data2, skb) ||
                    data->channel->center_freq != data2->channel->center_freq)
                        continue;
 
@@ -269,13 +311,9 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        if (txi->control.sta)
                hwsim_check_sta_magic(txi->control.sta);
 
-       memset(&txi->status, 0, sizeof(txi->status));
-       if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK)) {
-               if (ack)
-                       txi->flags |= IEEE80211_TX_STAT_ACK;
-               else
-                       txi->status.excessive_retries = 1;
-       }
+       ieee80211_tx_info_clear_status(txi);
+       if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) && ack)
+               txi->flags |= IEEE80211_TX_STAT_ACK;
        ieee80211_tx_status_irqsafe(hw, skb);
        return NETDEV_TX_OK;
 }
@@ -294,6 +332,7 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw)
 {
        struct mac80211_hwsim_data *data = hw->priv;
        data->started = 0;
+       del_timer(&data->beacon_timer);
        printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__);
 }
 
@@ -301,10 +340,9 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw)
 static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
                                        struct ieee80211_if_init_conf *conf)
 {
-       DECLARE_MAC_BUF(mac);
-       printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%s)\n",
+       printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n",
               wiphy_name(hw->wiphy), __func__, conf->type,
-              print_mac(mac, conf->mac_addr));
+              conf->mac_addr);
        hwsim_set_magic(conf->vif);
        return 0;
 }
@@ -313,10 +351,9 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
 static void mac80211_hwsim_remove_interface(
        struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf)
 {
-       DECLARE_MAC_BUF(mac);
-       printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%s)\n",
+       printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n",
               wiphy_name(hw->wiphy), __func__, conf->type,
-              print_mac(mac, conf->mac_addr));
+              conf->mac_addr);
        hwsim_check_magic(conf->vif);
        hwsim_clear_magic(conf->vif);
 }
@@ -361,10 +398,10 @@ static void mac80211_hwsim_beacon(unsigned long arg)
 }
 
 
-static int mac80211_hwsim_config(struct ieee80211_hw *hw,
-                                struct ieee80211_conf *conf)
+static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct mac80211_hwsim_data *data = hw->priv;
+       struct ieee80211_conf *conf = &hw->conf;
 
        printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d beacon_int=%d)\n",
               wiphy_name(hw->wiphy), __func__,
@@ -409,7 +446,16 @@ static int mac80211_hwsim_config_interface(struct ieee80211_hw *hw,
                                           struct ieee80211_vif *vif,
                                           struct ieee80211_if_conf *conf)
 {
+       struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
+
        hwsim_check_magic(vif);
+       if (conf->changed & IEEE80211_IFCC_BSSID) {
+               DECLARE_MAC_BUF(mac);
+               printk(KERN_DEBUG "%s:%s: BSSID changed: %s\n",
+                      wiphy_name(hw->wiphy), __func__,
+                      print_mac(mac, conf->bssid));
+               memcpy(vp->bssid, conf->bssid, ETH_ALEN);
+       }
        return 0;
 }
 
@@ -418,7 +464,48 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
                                            struct ieee80211_bss_conf *info,
                                            u32 changed)
 {
+       struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
+
        hwsim_check_magic(vif);
+
+       printk(KERN_DEBUG "%s:%s(changed=0x%x)\n",
+              wiphy_name(hw->wiphy), __func__, changed);
+
+       if (changed & BSS_CHANGED_ASSOC) {
+               printk(KERN_DEBUG "  %s: ASSOC: assoc=%d aid=%d\n",
+                      wiphy_name(hw->wiphy), info->assoc, info->aid);
+               vp->assoc = info->assoc;
+               vp->aid = info->aid;
+       }
+
+       if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+               printk(KERN_DEBUG "  %s: ERP_CTS_PROT: %d\n",
+                      wiphy_name(hw->wiphy), info->use_cts_prot);
+       }
+
+       if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+               printk(KERN_DEBUG "  %s: ERP_PREAMBLE: %d\n",
+                      wiphy_name(hw->wiphy), info->use_short_preamble);
+       }
+
+       if (changed & BSS_CHANGED_ERP_SLOT) {
+               printk(KERN_DEBUG "  %s: ERP_SLOT: %d\n",
+                      wiphy_name(hw->wiphy), info->use_short_slot);
+       }
+
+       if (changed & BSS_CHANGED_HT) {
+               printk(KERN_DEBUG "  %s: HT: sec_ch_offs=%d width_40_ok=%d "
+                      "op_mode=%d\n",
+                      wiphy_name(hw->wiphy),
+                      info->ht.secondary_channel_offset,
+                      info->ht.width_40_ok, info->ht.operation_mode);
+       }
+
+       if (changed & BSS_CHANGED_BASIC_RATES) {
+               printk(KERN_DEBUG "  %s: BASIC_RATES: 0x%llx\n",
+                      wiphy_name(hw->wiphy),
+                      (unsigned long long) info->basic_rates);
+       }
 }
 
 static void mac80211_hwsim_sta_notify(struct ieee80211_hw *hw,
@@ -445,6 +532,17 @@ static int mac80211_hwsim_set_tim(struct ieee80211_hw *hw,
        return 0;
 }
 
+static int mac80211_hwsim_conf_tx(
+       struct ieee80211_hw *hw, u16 queue,
+       const struct ieee80211_tx_queue_params *params)
+{
+       printk(KERN_DEBUG "%s:%s (queue=%d txop=%d cw_min=%d cw_max=%d "
+              "aifs=%d)\n",
+              wiphy_name(hw->wiphy), __func__, queue,
+              params->txop, params->cw_min, params->cw_max, params->aifs);
+       return 0;
+}
+
 static const struct ieee80211_ops mac80211_hwsim_ops =
 {
        .tx = mac80211_hwsim_tx,
@@ -458,6 +556,7 @@ static const struct ieee80211_ops mac80211_hwsim_ops =
        .bss_info_changed = mac80211_hwsim_bss_info_changed,
        .sta_notify = mac80211_hwsim_sta_notify,
        .set_tim = mac80211_hwsim_set_tim,
+       .conf_tx = mac80211_hwsim_conf_tx,
 };
 
 
@@ -474,6 +573,8 @@ static void mac80211_hwsim_free(void)
        spin_unlock_bh(&hwsim_radio_lock);
 
        list_for_each_entry(data, &tmplist, list) {
+               debugfs_remove(data->debugfs_ps);
+               debugfs_remove(data->debugfs);
                ieee80211_unregister_hw(data->hw);
                device_unregister(data->dev);
                ieee80211_free_hw(data->hw);
@@ -499,13 +600,133 @@ static void hwsim_mon_setup(struct net_device *dev)
 }
 
 
+static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
+{
+       struct mac80211_hwsim_data *data = dat;
+       struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
+       DECLARE_MAC_BUF(buf);
+       struct sk_buff *skb;
+       struct ieee80211_pspoll *pspoll;
+
+       if (!vp->assoc)
+               return;
+
+       printk(KERN_DEBUG "%s:%s: send PS-Poll to %s for aid %d\n",
+              wiphy_name(data->hw->wiphy), __func__,
+              print_mac(buf, vp->bssid), vp->aid);
+
+       skb = dev_alloc_skb(sizeof(*pspoll));
+       if (!skb)
+               return;
+       pspoll = (void *) skb_put(skb, sizeof(*pspoll));
+       pspoll->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
+                                           IEEE80211_STYPE_PSPOLL |
+                                           IEEE80211_FCTL_PM);
+       pspoll->aid = cpu_to_le16(0xc000 | vp->aid);
+       memcpy(pspoll->bssid, vp->bssid, ETH_ALEN);
+       memcpy(pspoll->ta, mac, ETH_ALEN);
+       if (data->radio_enabled &&
+           !mac80211_hwsim_tx_frame(data->hw, skb))
+               printk(KERN_DEBUG "%s: PS-Poll frame not ack'ed\n", __func__);
+       dev_kfree_skb(skb);
+}
+
+
+static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
+                               struct ieee80211_vif *vif, int ps)
+{
+       struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
+       DECLARE_MAC_BUF(buf);
+       struct sk_buff *skb;
+       struct ieee80211_hdr *hdr;
+
+       if (!vp->assoc)
+               return;
+
+       printk(KERN_DEBUG "%s:%s: send data::nullfunc to %s ps=%d\n",
+              wiphy_name(data->hw->wiphy), __func__,
+              print_mac(buf, vp->bssid), ps);
+
+       skb = dev_alloc_skb(sizeof(*hdr));
+       if (!skb)
+               return;
+       hdr = (void *) skb_put(skb, sizeof(*hdr) - ETH_ALEN);
+       hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
+                                        IEEE80211_STYPE_NULLFUNC |
+                                        (ps ? IEEE80211_FCTL_PM : 0));
+       hdr->duration_id = cpu_to_le16(0);
+       memcpy(hdr->addr1, vp->bssid, ETH_ALEN);
+       memcpy(hdr->addr2, mac, ETH_ALEN);
+       memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
+       if (data->radio_enabled &&
+           !mac80211_hwsim_tx_frame(data->hw, skb))
+               printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__);
+       dev_kfree_skb(skb);
+}
+
+
+static void hwsim_send_nullfunc_ps(void *dat, u8 *mac,
+                                  struct ieee80211_vif *vif)
+{
+       struct mac80211_hwsim_data *data = dat;
+       hwsim_send_nullfunc(data, mac, vif, 1);
+}
+
+
+static void hwsim_send_nullfunc_no_ps(void *dat, u8 *mac,
+                                     struct ieee80211_vif *vif)
+{
+       struct mac80211_hwsim_data *data = dat;
+       hwsim_send_nullfunc(data, mac, vif, 0);
+}
+
+
+static int hwsim_fops_ps_read(void *dat, u64 *val)
+{
+       struct mac80211_hwsim_data *data = dat;
+       *val = data->ps;
+       return 0;
+}
+
+static int hwsim_fops_ps_write(void *dat, u64 val)
+{
+       struct mac80211_hwsim_data *data = dat;
+       enum ps_mode old_ps;
+
+       if (val != PS_DISABLED && val != PS_ENABLED && val != PS_AUTO_POLL &&
+           val != PS_MANUAL_POLL)
+               return -EINVAL;
+
+       old_ps = data->ps;
+       data->ps = val;
+
+       if (val == PS_MANUAL_POLL) {
+               ieee80211_iterate_active_interfaces(data->hw,
+                                                   hwsim_send_ps_poll, data);
+               data->ps_poll_pending = true;
+       } else if (old_ps == PS_DISABLED && val != PS_DISABLED) {
+               ieee80211_iterate_active_interfaces(data->hw,
+                                                   hwsim_send_nullfunc_ps,
+                                                   data);
+       } else if (old_ps != PS_DISABLED && val == PS_DISABLED) {
+               ieee80211_iterate_active_interfaces(data->hw,
+                                                   hwsim_send_nullfunc_no_ps,
+                                                   data);
+       }
+
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_ps, hwsim_fops_ps_read, hwsim_fops_ps_write,
+                       "%llu\n");
+
+
 static int __init init_mac80211_hwsim(void)
 {
        int i, err = 0;
        u8 addr[ETH_ALEN];
        struct mac80211_hwsim_data *data;
        struct ieee80211_hw *hw;
-       DECLARE_MAC_BUF(mac);
 
        if (radios < 1 || radios > 100)
                return -EINVAL;
@@ -566,19 +787,18 @@ static int __init init_mac80211_hwsim(void)
                data->band.n_channels = ARRAY_SIZE(hwsim_channels);
                data->band.bitrates = data->rates;
                data->band.n_bitrates = ARRAY_SIZE(hwsim_rates);
-               data->band.ht_info.ht_supported = 1;
-               data->band.ht_info.cap = IEEE80211_HT_CAP_SUP_WIDTH |
+               data->band.ht_cap.ht_supported = true;
+               data->band.ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
                        IEEE80211_HT_CAP_GRN_FLD |
                        IEEE80211_HT_CAP_SGI_40 |
                        IEEE80211_HT_CAP_DSSSCCK40;
-               data->band.ht_info.ampdu_factor = 0x3;
-               data->band.ht_info.ampdu_density = 0x6;
-               memset(data->band.ht_info.supp_mcs_set, 0,
-                      sizeof(data->band.ht_info.supp_mcs_set));
-               data->band.ht_info.supp_mcs_set[0] = 0xff;
-               data->band.ht_info.supp_mcs_set[1] = 0xff;
-               data->band.ht_info.supp_mcs_set[12] =
-                       IEEE80211_HT_CAP_MCS_TX_DEFINED;
+               data->band.ht_cap.ampdu_factor = 0x3;
+               data->band.ht_cap.ampdu_density = 0x6;
+               memset(&data->band.ht_cap.mcs, 0,
+                      sizeof(data->band.ht_cap.mcs));
+               data->band.ht_cap.mcs.rx_mask[0] = 0xff;
+               data->band.ht_cap.mcs.rx_mask[1] = 0xff;
+               data->band.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
                hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band;
 
                err = ieee80211_register_hw(hw);
@@ -588,9 +808,15 @@ static int __init init_mac80211_hwsim(void)
                        goto failed_hw;
                }
 
-               printk(KERN_DEBUG "%s: hwaddr %s registered\n",
+               printk(KERN_DEBUG "%s: hwaddr %pM registered\n",
                       wiphy_name(hw->wiphy),
-                      print_mac(mac, hw->wiphy->perm_addr));
+                      hw->wiphy->perm_addr);
+
+               data->debugfs = debugfs_create_dir("hwsim",
+                                                  hw->wiphy->debugfsdir);
+               data->debugfs_ps = debugfs_create_file("ps", 0666,
+                                                      data->debugfs, data,
+                                                      &hwsim_fops_ps);
 
                setup_timer(&data->beacon_timer, mac80211_hwsim_beacon,
                            (unsigned long) hw);
index a670f36b5f3f3c1e3222d0e45c27491132caed7d..24caec6caf1fc0f98cdbffb1141ee6c57dd123aa 100644 (file)
@@ -737,7 +737,6 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
     win_req_t req;
     memreq_t mem;
     u_char __iomem *ramBase = NULL;
-    DECLARE_MAC_BUF(mac);
 
     DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link);
 
@@ -808,12 +807,12 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
        dev->dev_addr[i] = readb(ramBase + NETWAVE_EREG_PA + i);
 
     printk(KERN_INFO "%s: Netwave: port %#3lx, irq %d, mem %lx, "
-          "id %c%c, hw_addr %s\n",
+          "id %c%c, hw_addr %pM\n",
           dev->name, dev->base_addr, dev->irq,
           (u_long) ramBase,
           (int) readb(ramBase+NETWAVE_EREG_NI),
           (int) readb(ramBase+NETWAVE_EREG_NI+1),
-          print_mac(mac, dev->dev_addr));
+          dev->dev_addr);
 
     /* get revision words */
     printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n", 
@@ -1308,7 +1307,6 @@ static int netwave_rx(struct net_device *dev)
        /* Queue packet for network layer */
        netif_rx(skb);
 
-       dev->last_rx = jiffies;
        priv->stats.rx_packets++;
        priv->stats.rx_bytes += rcvLen;
 
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
deleted file mode 100644 (file)
index e0512e4..0000000
+++ /dev/null
@@ -1,6021 +0,0 @@
-/* orinoco.c - (formerly known as dldwd_cs.c and orinoco_cs.c)
- *
- * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
- * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
- *
- * Current maintainers (as of 29 September 2003) are:
- *     Pavel Roskin <proski AT gnu.org>
- * and David Gibson <hermes AT gibson.dropbear.id.au>
- *
- * (C) Copyright David Gibson, IBM Corporation 2001-2003.
- * Copyright (C) 2000 David Gibson, Linuxcare Australia.
- *     With some help from :
- * Copyright (C) 2001 Jean Tourrilhes, HP Labs
- * Copyright (C) 2001 Benjamin Herrenschmidt
- *
- * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
- *
- * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy
- * AT fasta.fh-dortmund.de>
- *      http://www.stud.fh-dortmund.de/~andy/wvlan/
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License.
- *
- * The initial developer of the original code is David A. Hinds
- * <dahinds AT users.sourceforge.net>.  Portions created by David
- * A. Hinds are Copyright (C) 1999 David A. Hinds.  All Rights
- * Reserved.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in
- * which case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.  */
-
-/*
- * TODO
- *     o Handle de-encapsulation within network layer, provide 802.11
- *       headers (patch from Thomas 'Dent' Mirlacher)
- *     o Fix possible races in SPY handling.
- *     o Disconnect wireless extensions from fundamental configuration.
- *     o (maybe) Software WEP support (patch from Stano Meduna).
- *     o (maybe) Use multiple Tx buffers - driver handling queue
- *       rather than firmware.
- */
-
-/* Locking and synchronization:
- *
- * The basic principle is that everything is serialized through a
- * single spinlock, priv->lock.  The lock is used in user, bh and irq
- * context, so when taken outside hardirq context it should always be
- * taken with interrupts disabled.  The lock protects both the
- * hardware and the struct orinoco_private.
- *
- * Another flag, priv->hw_unavailable indicates that the hardware is
- * unavailable for an extended period of time (e.g. suspended, or in
- * the middle of a hard reset).  This flag is protected by the
- * spinlock.  All code which touches the hardware should check the
- * flag after taking the lock, and if it is set, give up on whatever
- * they are doing and drop the lock again.  The orinoco_lock()
- * function handles this (it unlocks and returns -EBUSY if
- * hw_unavailable is non-zero).
- */
-
-#define DRIVER_NAME "orinoco"
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/firmware.h>
-#include <linux/if_arp.h>
-#include <linux/wireless.h>
-#include <net/iw_handler.h>
-#include <net/ieee80211.h>
-
-#include <linux/scatterlist.h>
-#include <linux/crypto.h>
-
-#include "hermes_rid.h"
-#include "hermes_dld.h"
-#include "orinoco.h"
-
-/********************************************************************/
-/* Module information                                               */
-/********************************************************************/
-
-MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
-MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
-MODULE_LICENSE("Dual MPL/GPL");
-
-/* Level of debugging. Used in the macros in orinoco.h */
-#ifdef ORINOCO_DEBUG
-int orinoco_debug = ORINOCO_DEBUG;
-module_param(orinoco_debug, int, 0644);
-MODULE_PARM_DESC(orinoco_debug, "Debug level");
-EXPORT_SYMBOL(orinoco_debug);
-#endif
-
-static int suppress_linkstatus; /* = 0 */
-module_param(suppress_linkstatus, bool, 0644);
-MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
-static int ignore_disconnect; /* = 0 */
-module_param(ignore_disconnect, int, 0644);
-MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer");
-
-static int force_monitor; /* = 0 */
-module_param(force_monitor, int, 0644);
-MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
-
-/********************************************************************/
-/* Compile time configuration and compatibility stuff               */
-/********************************************************************/
-
-/* We do this this way to avoid ifdefs in the actual code */
-#ifdef WIRELESS_SPY
-#define SPY_NUMBER(priv)       (priv->spy_data.spy_number)
-#else
-#define SPY_NUMBER(priv)       0
-#endif /* WIRELESS_SPY */
-
-/********************************************************************/
-/* Internal constants                                               */
-/********************************************************************/
-
-/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
-static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
-#define ENCAPS_OVERHEAD                (sizeof(encaps_hdr) + 2)
-
-#define ORINOCO_MIN_MTU                256
-#define ORINOCO_MAX_MTU                (IEEE80211_DATA_LEN - ENCAPS_OVERHEAD)
-
-#define SYMBOL_MAX_VER_LEN     (14)
-#define USER_BAP               0
-#define IRQ_BAP                        1
-#define MAX_IRQLOOPS_PER_IRQ   10
-#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of
-                                           * how many events the
-                                           * device could
-                                           * legitimately generate */
-#define SMALL_KEY_SIZE         5
-#define LARGE_KEY_SIZE         13
-#define TX_NICBUF_SIZE_BUG     1585            /* Bug in Symbol firmware */
-
-#define DUMMY_FID              0xFFFF
-
-/*#define MAX_MULTICAST(priv)  (priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
-  HERMES_MAX_MULTICAST : 0)*/
-#define MAX_MULTICAST(priv)    (HERMES_MAX_MULTICAST)
-
-#define ORINOCO_INTEN          (HERMES_EV_RX | HERMES_EV_ALLOC \
-                                | HERMES_EV_TX | HERMES_EV_TXEXC \
-                                | HERMES_EV_WTERR | HERMES_EV_INFO \
-                                | HERMES_EV_INFDROP )
-
-#define MAX_RID_LEN 1024
-
-static const struct iw_handler_def orinoco_handler_def;
-static const struct ethtool_ops orinoco_ethtool_ops;
-
-/********************************************************************/
-/* Data tables                                                      */
-/********************************************************************/
-
-/* The frequency of each channel in MHz */
-static const long channel_frequency[] = {
-       2412, 2417, 2422, 2427, 2432, 2437, 2442,
-       2447, 2452, 2457, 2462, 2467, 2472, 2484
-};
-#define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
-
-/* This tables gives the actual meanings of the bitrate IDs returned
- * by the firmware. */
-static struct {
-       int bitrate; /* in 100s of kilobits */
-       int automatic;
-       u16 agere_txratectrl;
-       u16 intersil_txratectrl;
-} bitrate_table[] = {
-       {110, 1,  3, 15}, /* Entry 0 is the default */
-       {10,  0,  1,  1},
-       {10,  1,  1,  1},
-       {20,  0,  2,  2},
-       {20,  1,  6,  3},
-       {55,  0,  4,  4},
-       {55,  1,  7,  7},
-       {110, 0,  5,  8},
-};
-#define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
-
-/********************************************************************/
-/* Data types                                                       */
-/********************************************************************/
-
-/* Beginning of the Tx descriptor, used in TxExc handling */
-struct hermes_txexc_data {
-       struct hermes_tx_descriptor desc;
-       __le16 frame_ctl;
-       __le16 duration_id;
-       u8 addr1[ETH_ALEN];
-} __attribute__ ((packed));
-
-/* Rx frame header except compatibility 802.3 header */
-struct hermes_rx_descriptor {
-       /* Control */
-       __le16 status;
-       __le32 time;
-       u8 silence;
-       u8 signal;
-       u8 rate;
-       u8 rxflow;
-       __le32 reserved;
-
-       /* 802.11 header */
-       __le16 frame_ctl;
-       __le16 duration_id;
-       u8 addr1[ETH_ALEN];
-       u8 addr2[ETH_ALEN];
-       u8 addr3[ETH_ALEN];
-       __le16 seq_ctl;
-       u8 addr4[ETH_ALEN];
-
-       /* Data length */
-       __le16 data_len;
-} __attribute__ ((packed));
-
-/********************************************************************/
-/* Function prototypes                                              */
-/********************************************************************/
-
-static int __orinoco_program_rids(struct net_device *dev);
-static void __orinoco_set_multicast_list(struct net_device *dev);
-
-/********************************************************************/
-/* Michael MIC crypto setup                                         */
-/********************************************************************/
-#define MICHAEL_MIC_LEN 8
-static int orinoco_mic_init(struct orinoco_private *priv)
-{
-       priv->tx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
-       if (IS_ERR(priv->tx_tfm_mic)) {
-               printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
-                      "crypto API michael_mic\n");
-               priv->tx_tfm_mic = NULL;
-               return -ENOMEM;
-       }
-
-       priv->rx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
-       if (IS_ERR(priv->rx_tfm_mic)) {
-               printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
-                      "crypto API michael_mic\n");
-               priv->rx_tfm_mic = NULL;
-               return -ENOMEM;
-       }
-
-       return 0;
-}
-
-static void orinoco_mic_free(struct orinoco_private *priv)
-{
-       if (priv->tx_tfm_mic)
-               crypto_free_hash(priv->tx_tfm_mic);
-       if (priv->rx_tfm_mic)
-               crypto_free_hash(priv->rx_tfm_mic);
-}
-
-static int michael_mic(struct crypto_hash *tfm_michael, u8 *key,
-                      u8 *da, u8 *sa, u8 priority,
-                      u8 *data, size_t data_len, u8 *mic)
-{
-       struct hash_desc desc;
-       struct scatterlist sg[2];
-       u8 hdr[ETH_HLEN + 2]; /* size of header + padding */
-
-       if (tfm_michael == NULL) {
-               printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
-               return -1;
-       }
-
-       /* Copy header into buffer. We need the padding on the end zeroed */
-       memcpy(&hdr[0], da, ETH_ALEN);
-       memcpy(&hdr[ETH_ALEN], sa, ETH_ALEN);
-       hdr[ETH_ALEN*2] = priority;
-       hdr[ETH_ALEN*2+1] = 0;
-       hdr[ETH_ALEN*2+2] = 0;
-       hdr[ETH_ALEN*2+3] = 0;
-
-       /* Use scatter gather to MIC header and data in one go */
-       sg_init_table(sg, 2);
-       sg_set_buf(&sg[0], hdr, sizeof(hdr));
-       sg_set_buf(&sg[1], data, data_len);
-
-       if (crypto_hash_setkey(tfm_michael, key, MIC_KEYLEN))
-               return -1;
-
-       desc.tfm = tfm_michael;
-       desc.flags = 0;
-       return crypto_hash_digest(&desc, sg, data_len + sizeof(hdr),
-                                 mic);
-}
-
-/********************************************************************/
-/* Internal helper functions                                        */
-/********************************************************************/
-
-static inline void set_port_type(struct orinoco_private *priv)
-{
-       switch (priv->iw_mode) {
-       case IW_MODE_INFRA:
-               priv->port_type = 1;
-               priv->createibss = 0;
-               break;
-       case IW_MODE_ADHOC:
-               if (priv->prefer_port3) {
-                       priv->port_type = 3;
-                       priv->createibss = 0;
-               } else {
-                       priv->port_type = priv->ibss_port;
-                       priv->createibss = 1;
-               }
-               break;
-       case IW_MODE_MONITOR:
-               priv->port_type = 3;
-               priv->createibss = 0;
-               break;
-       default:
-               printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
-                      priv->ndev->name);
-       }
-}
-
-#define ORINOCO_MAX_BSS_COUNT  64
-static int orinoco_bss_data_allocate(struct orinoco_private *priv)
-{
-       if (priv->bss_xbss_data)
-               return 0;
-
-       if (priv->has_ext_scan)
-               priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
-                                             sizeof(struct xbss_element),
-                                             GFP_KERNEL);
-       else
-               priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
-                                             sizeof(struct bss_element),
-                                             GFP_KERNEL);
-
-       if (!priv->bss_xbss_data) {
-               printk(KERN_WARNING "Out of memory allocating beacons");
-               return -ENOMEM;
-       }
-       return 0;
-}
-
-static void orinoco_bss_data_free(struct orinoco_private *priv)
-{
-       kfree(priv->bss_xbss_data);
-       priv->bss_xbss_data = NULL;
-}
-
-#define PRIV_BSS       ((struct bss_element *)priv->bss_xbss_data)
-#define PRIV_XBSS      ((struct xbss_element *)priv->bss_xbss_data)
-static void orinoco_bss_data_init(struct orinoco_private *priv)
-{
-       int i;
-
-       INIT_LIST_HEAD(&priv->bss_free_list);
-       INIT_LIST_HEAD(&priv->bss_list);
-       if (priv->has_ext_scan)
-               for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
-                       list_add_tail(&(PRIV_XBSS[i].list),
-                                     &priv->bss_free_list);
-       else
-               for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
-                       list_add_tail(&(PRIV_BSS[i].list),
-                                     &priv->bss_free_list);
-
-}
-
-static inline u8 *orinoco_get_ie(u8 *data, size_t len,
-                                enum ieee80211_mfie eid)
-{
-       u8 *p = data;
-       while ((p + 2) < (data + len)) {
-               if (p[0] == eid)
-                       return p;
-               p += p[1] + 2;
-       }
-       return NULL;
-}
-
-#define WPA_OUI_TYPE   "\x00\x50\xF2\x01"
-#define WPA_SELECTOR_LEN 4
-static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len)
-{
-       u8 *p = data;
-       while ((p + 2 + WPA_SELECTOR_LEN) < (data + len)) {
-               if ((p[0] == MFIE_TYPE_GENERIC) &&
-                   (memcmp(&p[2], WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0))
-                       return p;
-               p += p[1] + 2;
-       }
-       return NULL;
-}
-
-
-/********************************************************************/
-/* Download functionality                                           */
-/********************************************************************/
-
-struct fw_info {
-       char *pri_fw;
-       char *sta_fw;
-       char *ap_fw;
-       u32 pda_addr;
-       u16 pda_size;
-};
-
-const static struct fw_info orinoco_fw[] = {
-       { "", "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 },
-       { "", "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 },
-       { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", "", 0x00003100, 512 }
-};
-
-/* Structure used to access fields in FW
- * Make sure LE decoding macros are used
- */
-struct orinoco_fw_header {
-       char hdr_vers[6];       /* ASCII string for header version */
-       __le16 headersize;      /* Total length of header */
-       __le32 entry_point;     /* NIC entry point */
-       __le32 blocks;          /* Number of blocks to program */
-       __le32 block_offset;    /* Offset of block data from eof header */
-       __le32 pdr_offset;      /* Offset to PDR data from eof header */
-       __le32 pri_offset;      /* Offset to primary plug data */
-       __le32 compat_offset;   /* Offset to compatibility data*/
-       char signature[0];      /* FW signature length headersize-20 */
-} __attribute__ ((packed));
-
-/* Download either STA or AP firmware into the card. */
-static int
-orinoco_dl_firmware(struct orinoco_private *priv,
-                   const struct fw_info *fw,
-                   int ap)
-{
-       /* Plug Data Area (PDA) */
-       __le16 *pda;
-
-       hermes_t *hw = &priv->hw;
-       const struct firmware *fw_entry;
-       const struct orinoco_fw_header *hdr;
-       const unsigned char *first_block;
-       const unsigned char *end;
-       const char *firmware;
-       struct net_device *dev = priv->ndev;
-       int err = 0;
-
-       pda = kzalloc(fw->pda_size, GFP_KERNEL);
-       if (!pda)
-               return -ENOMEM;
-
-       if (ap)
-               firmware = fw->ap_fw;
-       else
-               firmware = fw->sta_fw;
-
-       printk(KERN_DEBUG "%s: Attempting to download firmware %s\n",
-              dev->name, firmware);
-
-       /* Read current plug data */
-       err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
-       printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
-       if (err)
-               goto free;
-
-       err = request_firmware(&fw_entry, firmware, priv->dev);
-       if (err) {
-               printk(KERN_ERR "%s: Cannot find firmware %s\n",
-                      dev->name, firmware);
-               err = -ENOENT;
-               goto free;
-       }
-
-       hdr = (const struct orinoco_fw_header *) fw_entry->data;
-
-       /* Enable aux port to allow programming */
-       err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
-       printk(KERN_DEBUG "%s: Program init returned %d\n", dev->name, err);
-       if (err != 0)
-               goto abort;
-
-       /* Program data */
-       first_block = (fw_entry->data +
-                      le16_to_cpu(hdr->headersize) +
-                      le32_to_cpu(hdr->block_offset));
-       end = fw_entry->data + fw_entry->size;
-
-       err = hermes_program(hw, first_block, end);
-       printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
-       if (err != 0)
-               goto abort;
-
-       /* Update production data */
-       first_block = (fw_entry->data +
-                      le16_to_cpu(hdr->headersize) +
-                      le32_to_cpu(hdr->pdr_offset));
-
-       err = hermes_apply_pda_with_defaults(hw, first_block, pda);
-       printk(KERN_DEBUG "%s: Apply PDA returned %d\n", dev->name, err);
-       if (err)
-               goto abort;
-
-       /* Tell card we've finished */
-       err = hermesi_program_end(hw);
-       printk(KERN_DEBUG "%s: Program end returned %d\n", dev->name, err);
-       if (err != 0)
-               goto abort;
-
-       /* Check if we're running */
-       printk(KERN_DEBUG "%s: hermes_present returned %d\n",
-              dev->name, hermes_present(hw));
-
-abort:
-       release_firmware(fw_entry);
-
-free:
-       kfree(pda);
-       return err;
-}
-
-/* End markers */
-#define TEXT_END       0x1A            /* End of text header */
-
-/*
- * Process a firmware image - stop the card, load the firmware, reset
- * the card and make sure it responds.  For the secondary firmware take
- * care of the PDA - read it and then write it on top of the firmware.
- */
-static int
-symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
-               const unsigned char *image, const unsigned char *end,
-               int secondary)
-{
-       hermes_t *hw = &priv->hw;
-       int ret = 0;
-       const unsigned char *ptr;
-       const unsigned char *first_block;
-
-       /* Plug Data Area (PDA) */
-       __le16 *pda = NULL;
-
-       /* Binary block begins after the 0x1A marker */
-       ptr = image;
-       while (*ptr++ != TEXT_END);
-       first_block = ptr;
-
-       /* Read the PDA from EEPROM */
-       if (secondary) {
-               pda = kzalloc(fw->pda_size, GFP_KERNEL);
-               if (!pda)
-                       return -ENOMEM;
-
-               ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1);
-               if (ret)
-                       goto free;
-       }
-
-       /* Stop the firmware, so that it can be safely rewritten */
-       if (priv->stop_fw) {
-               ret = priv->stop_fw(priv, 1);
-               if (ret)
-                       goto free;
-       }
-
-       /* Program the adapter with new firmware */
-       ret = hermes_program(hw, first_block, end);
-       if (ret)
-               goto free;
-
-       /* Write the PDA to the adapter */
-       if (secondary) {
-               size_t len = hermes_blocks_length(first_block);
-               ptr = first_block + len;
-               ret = hermes_apply_pda(hw, ptr, pda);
-               kfree(pda);
-               if (ret)
-                       return ret;
-       }
-
-       /* Run the firmware */
-       if (priv->stop_fw) {
-               ret = priv->stop_fw(priv, 0);
-               if (ret)
-                       return ret;
-       }
-
-       /* Reset hermes chip and make sure it responds */
-       ret = hermes_init(hw);
-
-       /* hermes_reset() should return 0 with the secondary firmware */
-       if (secondary && ret != 0)
-               return -ENODEV;
-
-       /* And this should work with any firmware */
-       if (!hermes_present(hw))
-               return -ENODEV;
-
-       return 0;
-
-free:
-       kfree(pda);
-       return ret;
-}
-
-
-/*
- * Download the firmware into the card, this also does a PCMCIA soft
- * reset on the card, to make sure it's in a sane state.
- */
-static int
-symbol_dl_firmware(struct orinoco_private *priv,
-                  const struct fw_info *fw)
-{
-       struct net_device *dev = priv->ndev;
-       int ret;
-       const struct firmware *fw_entry;
-
-       if (request_firmware(&fw_entry, fw->pri_fw,
-                            priv->dev) != 0) {
-               printk(KERN_ERR "%s: Cannot find firmware: %s\n",
-                      dev->name, fw->pri_fw);
-               return -ENOENT;
-       }
-
-       /* Load primary firmware */
-       ret = symbol_dl_image(priv, fw, fw_entry->data,
-                             fw_entry->data + fw_entry->size, 0);
-       release_firmware(fw_entry);
-       if (ret) {
-               printk(KERN_ERR "%s: Primary firmware download failed\n",
-                      dev->name);
-               return ret;
-       }
-
-       if (request_firmware(&fw_entry, fw->sta_fw,
-                            priv->dev) != 0) {
-               printk(KERN_ERR "%s: Cannot find firmware: %s\n",
-                      dev->name, fw->sta_fw);
-               return -ENOENT;
-       }
-
-       /* Load secondary firmware */
-       ret = symbol_dl_image(priv, fw, fw_entry->data,
-                             fw_entry->data + fw_entry->size, 1);
-       release_firmware(fw_entry);
-       if (ret) {
-               printk(KERN_ERR "%s: Secondary firmware download failed\n",
-                      dev->name);
-       }
-
-       return ret;
-}
-
-static int orinoco_download(struct orinoco_private *priv)
-{
-       int err = 0;
-       /* Reload firmware */
-       switch (priv->firmware_type) {
-       case FIRMWARE_TYPE_AGERE:
-               /* case FIRMWARE_TYPE_INTERSIL: */
-               err = orinoco_dl_firmware(priv,
-                                         &orinoco_fw[priv->firmware_type], 0);
-               break;
-
-       case FIRMWARE_TYPE_SYMBOL:
-               err = symbol_dl_firmware(priv,
-                                        &orinoco_fw[priv->firmware_type]);
-               break;
-       case FIRMWARE_TYPE_INTERSIL:
-               break;
-       }
-       /* TODO: if we fail we probably need to reinitialise
-        * the driver */
-
-       return err;
-}
-
-/********************************************************************/
-/* Device methods                                                   */
-/********************************************************************/
-
-static int orinoco_open(struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       unsigned long flags;
-       int err;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       err = __orinoco_up(dev);
-
-       if (! err)
-               priv->open = 1;
-
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
-static int orinoco_stop(struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int err = 0;
-
-       /* We mustn't use orinoco_lock() here, because we need to be
-          able to close the interface even if hw_unavailable is set
-          (e.g. as we're released after a PC Card removal) */
-       spin_lock_irq(&priv->lock);
-
-       priv->open = 0;
-
-       err = __orinoco_down(dev);
-
-       spin_unlock_irq(&priv->lock);
-
-       return err;
-}
-
-static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       
-       return &priv->stats;
-}
-
-static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       struct iw_statistics *wstats = &priv->wstats;
-       int err;
-       unsigned long flags;
-
-       if (! netif_device_present(dev)) {
-               printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
-                      dev->name);
-               return NULL; /* FIXME: Can we do better than this? */
-       }
-
-       /* If busy, return the old stats.  Returning NULL may cause
-        * the interface to disappear from /proc/net/wireless */
-       if (orinoco_lock(priv, &flags) != 0)
-               return wstats;
-
-       /* We can't really wait for the tallies inquiry command to
-        * complete, so we just use the previous results and trigger
-        * a new tallies inquiry command for next time - Jean II */
-       /* FIXME: Really we should wait for the inquiry to come back -
-        * as it is the stats we give don't make a whole lot of sense.
-        * Unfortunately, it's not clear how to do that within the
-        * wireless extensions framework: I think we're in user
-        * context, but a lock seems to be held by the time we get in
-        * here so we're not safe to sleep here. */
-       hermes_inquire(hw, HERMES_INQ_TALLIES);
-
-       if (priv->iw_mode == IW_MODE_ADHOC) {
-               memset(&wstats->qual, 0, sizeof(wstats->qual));
-               /* If a spy address is defined, we report stats of the
-                * first spy address - Jean II */
-               if (SPY_NUMBER(priv)) {
-                       wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
-                       wstats->qual.level = priv->spy_data.spy_stat[0].level;
-                       wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
-                       wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
-               }
-       } else {
-               struct {
-                       __le16 qual, signal, noise, unused;
-               } __attribute__ ((packed)) cq;
-
-               err = HERMES_READ_RECORD(hw, USER_BAP,
-                                        HERMES_RID_COMMSQUALITY, &cq);
-
-               if (!err) {
-                       wstats->qual.qual = (int)le16_to_cpu(cq.qual);
-                       wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
-                       wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
-                       wstats->qual.updated = 7;
-               }
-       }
-
-       orinoco_unlock(priv, &flags);
-       return wstats;
-}
-
-static void orinoco_set_multicast_list(struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0) {
-               printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
-                      "called when hw_unavailable\n", dev->name);
-               return;
-       }
-
-       __orinoco_set_multicast_list(dev);
-       orinoco_unlock(priv, &flags);
-}
-
-static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-
-       if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
-               return -EINVAL;
-
-       if ( (new_mtu + ENCAPS_OVERHEAD + IEEE80211_HLEN) >
-            (priv->nicbuf_size - ETH_HLEN) )
-               return -EINVAL;
-
-       dev->mtu = new_mtu;
-
-       return 0;
-}
-
-/********************************************************************/
-/* Tx path                                                          */
-/********************************************************************/
-
-static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct net_device_stats *stats = &priv->stats;
-       hermes_t *hw = &priv->hw;
-       int err = 0;
-       u16 txfid = priv->txfid;
-       struct ethhdr *eh;
-       int tx_control;
-       unsigned long flags;
-
-       if (! netif_running(dev)) {
-               printk(KERN_ERR "%s: Tx on stopped device!\n",
-                      dev->name);
-               return NETDEV_TX_BUSY;
-       }
-       
-       if (netif_queue_stopped(dev)) {
-               printk(KERN_DEBUG "%s: Tx while transmitter busy!\n", 
-                      dev->name);
-               return NETDEV_TX_BUSY;
-       }
-       
-       if (orinoco_lock(priv, &flags) != 0) {
-               printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
-                      dev->name);
-               return NETDEV_TX_BUSY;
-       }
-
-       if (! netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
-               /* Oops, the firmware hasn't established a connection,
-                   silently drop the packet (this seems to be the
-                   safest approach). */
-               goto drop;
-       }
-
-       /* Check packet length */
-       if (skb->len < ETH_HLEN)
-               goto drop;
-
-       tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
-
-       if (priv->encode_alg == IW_ENCODE_ALG_TKIP)
-               tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
-                       HERMES_TXCTRL_MIC;
-
-       if (priv->has_alt_txcntl) {
-               /* WPA enabled firmwares have tx_cntl at the end of
-                * the 802.11 header.  So write zeroed descriptor and
-                * 802.11 header at the same time
-                */
-               char desc[HERMES_802_3_OFFSET];
-               __le16 *txcntl = (__le16 *) &desc[HERMES_TXCNTL2_OFFSET];
-
-               memset(&desc, 0, sizeof(desc));
-
-               *txcntl = cpu_to_le16(tx_control);
-               err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
-                                       txfid, 0);
-               if (err) {
-                       if (net_ratelimit())
-                               printk(KERN_ERR "%s: Error %d writing Tx "
-                                      "descriptor to BAP\n", dev->name, err);
-                       goto busy;
-               }
-       } else {
-               struct hermes_tx_descriptor desc;
-
-               memset(&desc, 0, sizeof(desc));
-
-               desc.tx_control = cpu_to_le16(tx_control);
-               err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
-                                       txfid, 0);
-               if (err) {
-                       if (net_ratelimit())
-                               printk(KERN_ERR "%s: Error %d writing Tx "
-                                      "descriptor to BAP\n", dev->name, err);
-                       goto busy;
-               }
-
-               /* Clear the 802.11 header and data length fields - some
-                * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
-                * if this isn't done. */
-               hermes_clear_words(hw, HERMES_DATA0,
-                                  HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
-       }
-
-       eh = (struct ethhdr *)skb->data;
-
-       /* Encapsulate Ethernet-II frames */
-       if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
-               struct header_struct {
-                       struct ethhdr eth;      /* 802.3 header */
-                       u8 encap[6];            /* 802.2 header */
-               } __attribute__ ((packed)) hdr;
-
-               /* Strip destination and source from the data */
-               skb_pull(skb, 2 * ETH_ALEN);
-
-               /* And move them to a separate header */
-               memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
-               hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
-               memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
-
-               /* Insert the SNAP header */
-               if (skb_headroom(skb) < sizeof(hdr)) {
-                       printk(KERN_ERR
-                              "%s: Not enough headroom for 802.2 headers %d\n",
-                              dev->name, skb_headroom(skb));
-                       goto drop;
-               }
-               eh = (struct ethhdr *) skb_push(skb, sizeof(hdr));
-               memcpy(eh, &hdr, sizeof(hdr));
-       }
-
-       err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len,
-                               txfid, HERMES_802_3_OFFSET);
-       if (err) {
-               printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
-                      dev->name, err);
-               goto busy;
-       }
-
-       /* Calculate Michael MIC */
-       if (priv->encode_alg == IW_ENCODE_ALG_TKIP) {
-               u8 mic_buf[MICHAEL_MIC_LEN + 1];
-               u8 *mic;
-               size_t offset;
-               size_t len;
-
-               if (skb->len % 2) {
-                       /* MIC start is on an odd boundary */
-                       mic_buf[0] = skb->data[skb->len - 1];
-                       mic = &mic_buf[1];
-                       offset = skb->len - 1;
-                       len = MICHAEL_MIC_LEN + 1;
-               } else {
-                       mic = &mic_buf[0];
-                       offset = skb->len;
-                       len = MICHAEL_MIC_LEN;
-               }
-
-               michael_mic(priv->tx_tfm_mic,
-                           priv->tkip_key[priv->tx_key].tx_mic,
-                           eh->h_dest, eh->h_source, 0 /* priority */,
-                           skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic);
-
-               /* Write the MIC */
-               err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
-                                       txfid, HERMES_802_3_OFFSET + offset);
-               if (err) {
-                       printk(KERN_ERR "%s: Error %d writing MIC to BAP\n",
-                              dev->name, err);
-                       goto busy;
-               }
-       }
-
-       /* Finally, we actually initiate the send */
-       netif_stop_queue(dev);
-
-       err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
-                               txfid, NULL);
-       if (err) {
-               netif_start_queue(dev);
-               if (net_ratelimit())
-                       printk(KERN_ERR "%s: Error %d transmitting packet\n",
-                               dev->name, err);
-               goto busy;
-       }
-
-       dev->trans_start = jiffies;
-       stats->tx_bytes += HERMES_802_3_OFFSET + skb->len;
-       goto ok;
-
- drop:
-       stats->tx_errors++;
-       stats->tx_dropped++;
-
- ok:
-       orinoco_unlock(priv, &flags);
-       dev_kfree_skb(skb);
-       return NETDEV_TX_OK;
-
- busy:
-       if (err == -EIO)
-               schedule_work(&priv->reset_work);
-       orinoco_unlock(priv, &flags);
-       return NETDEV_TX_BUSY;
-}
-
-static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       u16 fid = hermes_read_regn(hw, ALLOCFID);
-
-       if (fid != priv->txfid) {
-               if (fid != DUMMY_FID)
-                       printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
-                              dev->name, fid);
-               return;
-       }
-
-       hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
-}
-
-static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct net_device_stats *stats = &priv->stats;
-
-       stats->tx_packets++;
-
-       netif_wake_queue(dev);
-
-       hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
-}
-
-static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct net_device_stats *stats = &priv->stats;
-       u16 fid = hermes_read_regn(hw, TXCOMPLFID);
-       u16 status;
-       struct hermes_txexc_data hdr;
-       int err = 0;
-
-       if (fid == DUMMY_FID)
-               return; /* Nothing's really happened */
-
-       /* Read part of the frame header - we need status and addr1 */
-       err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
-                              sizeof(struct hermes_txexc_data),
-                              fid, 0);
-
-       hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
-       stats->tx_errors++;
-
-       if (err) {
-               printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
-                      "(FID=%04X error %d)\n",
-                      dev->name, fid, err);
-               return;
-       }
-       
-       DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name,
-             err, fid);
-    
-       /* We produce a TXDROP event only for retry or lifetime
-        * exceeded, because that's the only status that really mean
-        * that this particular node went away.
-        * Other errors means that *we* screwed up. - Jean II */
-       status = le16_to_cpu(hdr.desc.status);
-       if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
-               union iwreq_data        wrqu;
-
-               /* Copy 802.11 dest address.
-                * We use the 802.11 header because the frame may
-                * not be 802.3 or may be mangled...
-                * In Ad-Hoc mode, it will be the node address.
-                * In managed mode, it will be most likely the AP addr
-                * User space will figure out how to convert it to
-                * whatever it needs (IP address or else).
-                * - Jean II */
-               memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN);
-               wrqu.addr.sa_family = ARPHRD_ETHER;
-
-               /* Send event to user space */
-               wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
-       }
-
-       netif_wake_queue(dev);
-}
-
-static void orinoco_tx_timeout(struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct net_device_stats *stats = &priv->stats;
-       struct hermes *hw = &priv->hw;
-
-       printk(KERN_WARNING "%s: Tx timeout! "
-              "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
-              dev->name, hermes_read_regn(hw, ALLOCFID),
-              hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
-
-       stats->tx_errors++;
-
-       schedule_work(&priv->reset_work);
-}
-
-/********************************************************************/
-/* Rx path (data frames)                                            */
-/********************************************************************/
-
-/* Does the frame have a SNAP header indicating it should be
- * de-encapsulated to Ethernet-II? */
-static inline int is_ethersnap(void *_hdr)
-{
-       u8 *hdr = _hdr;
-
-       /* We de-encapsulate all packets which, a) have SNAP headers
-        * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
-        * and where b) the OUI of the SNAP header is 00:00:00 or
-        * 00:00:f8 - we need both because different APs appear to use
-        * different OUIs for some reason */
-       return (memcmp(hdr, &encaps_hdr, 5) == 0)
-               && ( (hdr[5] == 0x00) || (hdr[5] == 0xf8) );
-}
-
-static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
-                                     int level, int noise)
-{
-       struct iw_quality wstats;
-       wstats.level = level - 0x95;
-       wstats.noise = noise - 0x95;
-       wstats.qual = (level > noise) ? (level - noise) : 0;
-       wstats.updated = 7;
-       /* Update spy records */
-       wireless_spy_update(dev, mac, &wstats);
-}
-
-static void orinoco_stat_gather(struct net_device *dev,
-                               struct sk_buff *skb,
-                               struct hermes_rx_descriptor *desc)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-
-       /* Using spy support with lots of Rx packets, like in an
-        * infrastructure (AP), will really slow down everything, because
-        * the MAC address must be compared to each entry of the spy list.
-        * If the user really asks for it (set some address in the
-        * spy list), we do it, but he will pay the price.
-        * Note that to get here, you need both WIRELESS_SPY
-        * compiled in AND some addresses in the list !!!
-        */
-       /* Note : gcc will optimise the whole section away if
-        * WIRELESS_SPY is not defined... - Jean II */
-       if (SPY_NUMBER(priv)) {
-               orinoco_spy_gather(dev, skb_mac_header(skb) + ETH_ALEN,
-                                  desc->signal, desc->silence);
-       }
-}
-
-/*
- * orinoco_rx_monitor - handle received monitor frames.
- *
- * Arguments:
- *     dev             network device
- *     rxfid           received FID
- *     desc            rx descriptor of the frame
- *
- * Call context: interrupt
- */
-static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
-                              struct hermes_rx_descriptor *desc)
-{
-       u32 hdrlen = 30;        /* return full header by default */
-       u32 datalen = 0;
-       u16 fc;
-       int err;
-       int len;
-       struct sk_buff *skb;
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct net_device_stats *stats = &priv->stats;
-       hermes_t *hw = &priv->hw;
-
-       len = le16_to_cpu(desc->data_len);
-
-       /* Determine the size of the header and the data */
-       fc = le16_to_cpu(desc->frame_ctl);
-       switch (fc & IEEE80211_FCTL_FTYPE) {
-       case IEEE80211_FTYPE_DATA:
-               if ((fc & IEEE80211_FCTL_TODS)
-                   && (fc & IEEE80211_FCTL_FROMDS))
-                       hdrlen = 30;
-               else
-                       hdrlen = 24;
-               datalen = len;
-               break;
-       case IEEE80211_FTYPE_MGMT:
-               hdrlen = 24;
-               datalen = len;
-               break;
-       case IEEE80211_FTYPE_CTL:
-               switch (fc & IEEE80211_FCTL_STYPE) {
-               case IEEE80211_STYPE_PSPOLL:
-               case IEEE80211_STYPE_RTS:
-               case IEEE80211_STYPE_CFEND:
-               case IEEE80211_STYPE_CFENDACK:
-                       hdrlen = 16;
-                       break;
-               case IEEE80211_STYPE_CTS:
-               case IEEE80211_STYPE_ACK:
-                       hdrlen = 10;
-                       break;
-               }
-               break;
-       default:
-               /* Unknown frame type */
-               break;
-       }
-
-       /* sanity check the length */
-       if (datalen > IEEE80211_DATA_LEN + 12) {
-               printk(KERN_DEBUG "%s: oversized monitor frame, "
-                      "data length = %d\n", dev->name, datalen);
-               stats->rx_length_errors++;
-               goto update_stats;
-       }
-
-       skb = dev_alloc_skb(hdrlen + datalen);
-       if (!skb) {
-               printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
-                      dev->name);
-               goto update_stats;
-       }
-
-       /* Copy the 802.11 header to the skb */
-       memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
-       skb_reset_mac_header(skb);
-
-       /* If any, copy the data from the card to the skb */
-       if (datalen > 0) {
-               err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
-                                      ALIGN(datalen, 2), rxfid,
-                                      HERMES_802_2_OFFSET);
-               if (err) {
-                       printk(KERN_ERR "%s: error %d reading monitor frame\n",
-                              dev->name, err);
-                       goto drop;
-               }
-       }
-
-       skb->dev = dev;
-       skb->ip_summed = CHECKSUM_NONE;
-       skb->pkt_type = PACKET_OTHERHOST;
-       skb->protocol = __constant_htons(ETH_P_802_2);
-       
-       dev->last_rx = jiffies;
-       stats->rx_packets++;
-       stats->rx_bytes += skb->len;
-
-       netif_rx(skb);
-       return;
-
- drop:
-       dev_kfree_skb_irq(skb);
- update_stats:
-       stats->rx_errors++;
-       stats->rx_dropped++;
-}
-
-/* Get tsc from the firmware */
-static int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key,
-                                 u8 *tsc)
-{
-       hermes_t *hw = &priv->hw;
-       int err = 0;
-       u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE];
-
-       if ((key < 0) || (key > 4))
-               return -EINVAL;
-
-       err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV,
-                             sizeof(tsc_arr), NULL, &tsc_arr);
-       if (!err)
-               memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0]));
-
-       return err;
-}
-
-static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct net_device_stats *stats = &priv->stats;
-       struct iw_statistics *wstats = &priv->wstats;
-       struct sk_buff *skb = NULL;
-       u16 rxfid, status;
-       int length;
-       struct hermes_rx_descriptor *desc;
-       struct orinoco_rx_data *rx_data;
-       int err;
-
-       desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
-       if (!desc) {
-               printk(KERN_WARNING
-                      "%s: Can't allocate space for RX descriptor\n",
-                      dev->name);
-               goto update_stats;
-       }
-
-       rxfid = hermes_read_regn(hw, RXFID);
-
-       err = hermes_bap_pread(hw, IRQ_BAP, desc, sizeof(*desc),
-                              rxfid, 0);
-       if (err) {
-               printk(KERN_ERR "%s: error %d reading Rx descriptor. "
-                      "Frame dropped.\n", dev->name, err);
-               goto update_stats;
-       }
-
-       status = le16_to_cpu(desc->status);
-
-       if (status & HERMES_RXSTAT_BADCRC) {
-               DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n",
-                     dev->name);
-               stats->rx_crc_errors++;
-               goto update_stats;
-       }
-
-       /* Handle frames in monitor mode */
-       if (priv->iw_mode == IW_MODE_MONITOR) {
-               orinoco_rx_monitor(dev, rxfid, desc);
-               goto out;
-       }
-
-       if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
-               DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
-                     dev->name);
-               wstats->discard.code++;
-               goto update_stats;
-       }
-
-       length = le16_to_cpu(desc->data_len);
-
-       /* Sanity checks */
-       if (length < 3) { /* No for even an 802.2 LLC header */
-               /* At least on Symbol firmware with PCF we get quite a
-                   lot of these legitimately - Poll frames with no
-                   data. */
-               goto out;
-       }
-       if (length > IEEE80211_DATA_LEN) {
-               printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
-                      dev->name, length);
-               stats->rx_length_errors++;
-               goto update_stats;
-       }
-
-       /* Payload size does not include Michael MIC. Increase payload
-        * size to read it together with the data. */
-       if (status & HERMES_RXSTAT_MIC)
-               length += MICHAEL_MIC_LEN;
-
-       /* We need space for the packet data itself, plus an ethernet
-          header, plus 2 bytes so we can align the IP header on a
-          32bit boundary, plus 1 byte so we can read in odd length
-          packets from the card, which has an IO granularity of 16
-          bits */  
-       skb = dev_alloc_skb(length+ETH_HLEN+2+1);
-       if (!skb) {
-               printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
-                      dev->name);
-               goto update_stats;
-       }
-
-       /* We'll prepend the header, so reserve space for it.  The worst
-          case is no decapsulation, when 802.3 header is prepended and
-          nothing is removed.  2 is for aligning the IP header.  */
-       skb_reserve(skb, ETH_HLEN + 2);
-
-       err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length),
-                              ALIGN(length, 2), rxfid,
-                              HERMES_802_2_OFFSET);
-       if (err) {
-               printk(KERN_ERR "%s: error %d reading frame. "
-                      "Frame dropped.\n", dev->name, err);
-               goto drop;
-       }
-
-       /* Add desc and skb to rx queue */
-       rx_data = kzalloc(sizeof(*rx_data), GFP_ATOMIC);
-       if (!rx_data) {
-               printk(KERN_WARNING "%s: Can't allocate RX packet\n",
-                       dev->name);
-               goto drop;
-       }
-       rx_data->desc = desc;
-       rx_data->skb = skb;
-       list_add_tail(&rx_data->list, &priv->rx_list);
-       tasklet_schedule(&priv->rx_tasklet);
-
-       return;
-
-drop:
-       dev_kfree_skb_irq(skb);
-update_stats:
-       stats->rx_errors++;
-       stats->rx_dropped++;
-out:
-       kfree(desc);
-}
-
-static void orinoco_rx(struct net_device *dev,
-                      struct hermes_rx_descriptor *desc,
-                      struct sk_buff *skb)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct net_device_stats *stats = &priv->stats;
-       u16 status, fc;
-       int length;
-       struct ethhdr *hdr;
-
-       status = le16_to_cpu(desc->status);
-       length = le16_to_cpu(desc->data_len);
-       fc = le16_to_cpu(desc->frame_ctl);
-
-       /* Calculate and check MIC */
-       if (status & HERMES_RXSTAT_MIC) {
-               int key_id = ((status & HERMES_RXSTAT_MIC_KEY_ID) >>
-                             HERMES_MIC_KEY_ID_SHIFT);
-               u8 mic[MICHAEL_MIC_LEN];
-               u8 *rxmic;
-               u8 *src = (fc & IEEE80211_FCTL_FROMDS) ?
-                       desc->addr3 : desc->addr2;
-
-               /* Extract Michael MIC from payload */
-               rxmic = skb->data + skb->len - MICHAEL_MIC_LEN;
-
-               skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
-               length -= MICHAEL_MIC_LEN;
-
-               michael_mic(priv->rx_tfm_mic,
-                           priv->tkip_key[key_id].rx_mic,
-                           desc->addr1,
-                           src,
-                           0, /* priority or QoS? */
-                           skb->data,
-                           skb->len,
-                           &mic[0]);
-
-               if (memcmp(mic, rxmic,
-                          MICHAEL_MIC_LEN)) {
-                       union iwreq_data wrqu;
-                       struct iw_michaelmicfailure wxmic;
-                       DECLARE_MAC_BUF(mac);
-
-                       printk(KERN_WARNING "%s: "
-                              "Invalid Michael MIC in data frame from %s, "
-                              "using key %i\n",
-                              dev->name, print_mac(mac, src), key_id);
-
-                       /* TODO: update stats */
-
-                       /* Notify userspace */
-                       memset(&wxmic, 0, sizeof(wxmic));
-                       wxmic.flags = key_id & IW_MICFAILURE_KEY_ID;
-                       wxmic.flags |= (desc->addr1[0] & 1) ?
-                               IW_MICFAILURE_GROUP : IW_MICFAILURE_PAIRWISE;
-                       wxmic.src_addr.sa_family = ARPHRD_ETHER;
-                       memcpy(wxmic.src_addr.sa_data, src, ETH_ALEN);
-
-                       (void) orinoco_hw_get_tkip_iv(priv, key_id,
-                                                     &wxmic.tsc[0]);
-
-                       memset(&wrqu, 0, sizeof(wrqu));
-                       wrqu.data.length = sizeof(wxmic);
-                       wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu,
-                                           (char *) &wxmic);
-
-                       goto drop;
-               }
-       }
-
-       /* Handle decapsulation
-        * In most cases, the firmware tell us about SNAP frames.
-        * For some reason, the SNAP frames sent by LinkSys APs
-        * are not properly recognised by most firmwares.
-        * So, check ourselves */
-       if (length >= ENCAPS_OVERHEAD &&
-           (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
-            ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
-            is_ethersnap(skb->data))) {
-               /* These indicate a SNAP within 802.2 LLC within
-                  802.11 frame which we'll need to de-encapsulate to
-                  the original EthernetII frame. */
-               hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN - ENCAPS_OVERHEAD);
-       } else {
-               /* 802.3 frame - prepend 802.3 header as is */
-               hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN);
-               hdr->h_proto = htons(length);
-       }
-       memcpy(hdr->h_dest, desc->addr1, ETH_ALEN);
-       if (fc & IEEE80211_FCTL_FROMDS)
-               memcpy(hdr->h_source, desc->addr3, ETH_ALEN);
-       else
-               memcpy(hdr->h_source, desc->addr2, ETH_ALEN);
-
-       dev->last_rx = jiffies;
-       skb->protocol = eth_type_trans(skb, dev);
-       skb->ip_summed = CHECKSUM_NONE;
-       if (fc & IEEE80211_FCTL_TODS)
-               skb->pkt_type = PACKET_OTHERHOST;
-       
-       /* Process the wireless stats if needed */
-       orinoco_stat_gather(dev, skb, desc);
-
-       /* Pass the packet to the networking stack */
-       netif_rx(skb);
-       stats->rx_packets++;
-       stats->rx_bytes += length;
-
-       return;
-
- drop:
-       dev_kfree_skb(skb);
-       stats->rx_errors++;
-       stats->rx_dropped++;
-}
-
-static void orinoco_rx_isr_tasklet(unsigned long data)
-{
-       struct net_device *dev = (struct net_device *) data;
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct orinoco_rx_data *rx_data, *temp;
-       struct hermes_rx_descriptor *desc;
-       struct sk_buff *skb;
-
-       /* extract desc and skb from queue */
-       list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
-               desc = rx_data->desc;
-               skb = rx_data->skb;
-               list_del(&rx_data->list);
-               kfree(rx_data);
-
-               orinoco_rx(dev, desc, skb);
-
-               kfree(desc);
-       }
-}
-
-/********************************************************************/
-/* Rx path (info frames)                                            */
-/********************************************************************/
-
-static void print_linkstatus(struct net_device *dev, u16 status)
-{
-       char * s;
-
-       if (suppress_linkstatus)
-               return;
-
-       switch (status) {
-       case HERMES_LINKSTATUS_NOT_CONNECTED:
-               s = "Not Connected";
-               break;
-       case HERMES_LINKSTATUS_CONNECTED:
-               s = "Connected";
-               break;
-       case HERMES_LINKSTATUS_DISCONNECTED:
-               s = "Disconnected";
-               break;
-       case HERMES_LINKSTATUS_AP_CHANGE:
-               s = "AP Changed";
-               break;
-       case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
-               s = "AP Out of Range";
-               break;
-       case HERMES_LINKSTATUS_AP_IN_RANGE:
-               s = "AP In Range";
-               break;
-       case HERMES_LINKSTATUS_ASSOC_FAILED:
-               s = "Association Failed";
-               break;
-       default:
-               s = "UNKNOWN";
-       }
-       
-       printk(KERN_INFO "%s: New link status: %s (%04x)\n",
-              dev->name, s, status);
-}
-
-/* Search scan results for requested BSSID, join it if found */
-static void orinoco_join_ap(struct work_struct *work)
-{
-       struct orinoco_private *priv =
-               container_of(work, struct orinoco_private, join_work);
-       struct net_device *dev = priv->ndev;
-       struct hermes *hw = &priv->hw;
-       int err;
-       unsigned long flags;
-       struct join_req {
-               u8 bssid[ETH_ALEN];
-               __le16 channel;
-       } __attribute__ ((packed)) req;
-       const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
-       struct prism2_scan_apinfo *atom = NULL;
-       int offset = 4;
-       int found = 0;
-       u8 *buf;
-       u16 len;
-
-       /* Allocate buffer for scan results */
-       buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL);
-       if (! buf)
-               return;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               goto fail_lock;
-
-       /* Sanity checks in case user changed something in the meantime */
-       if (! priv->bssid_fixed)
-               goto out;
-
-       if (strlen(priv->desired_essid) == 0)
-               goto out;
-
-       /* Read scan results from the firmware */
-       err = hermes_read_ltv(hw, USER_BAP,
-                             HERMES_RID_SCANRESULTSTABLE,
-                             MAX_SCAN_LEN, &len, buf);
-       if (err) {
-               printk(KERN_ERR "%s: Cannot read scan results\n",
-                      dev->name);
-               goto out;
-       }
-
-       len = HERMES_RECLEN_TO_BYTES(len);
-
-       /* Go through the scan results looking for the channel of the AP
-        * we were requested to join */
-       for (; offset + atom_len <= len; offset += atom_len) {
-               atom = (struct prism2_scan_apinfo *) (buf + offset);
-               if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) {
-                       found = 1;
-                       break;
-               }
-       }
-
-       if (! found) {
-               DEBUG(1, "%s: Requested AP not found in scan results\n",
-                     dev->name);
-               goto out;
-       }
-
-       memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
-       req.channel = atom->channel;    /* both are little-endian */
-       err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
-                                 &req);
-       if (err)
-               printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
-
- out:
-       orinoco_unlock(priv, &flags);
-
- fail_lock:
-       kfree(buf);
-}
-
-/* Send new BSSID to userspace */
-static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
-{
-       struct net_device *dev = priv->ndev;
-       struct hermes *hw = &priv->hw;
-       union iwreq_data wrqu;
-       int err;
-
-       err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
-                             ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
-       if (err != 0)
-               return;
-
-       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-
-       /* Send event to user space */
-       wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
-}
-
-static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv)
-{
-       struct net_device *dev = priv->ndev;
-       struct hermes *hw = &priv->hw;
-       union iwreq_data wrqu;
-       int err;
-       u8 buf[88];
-       u8 *ie;
-
-       if (!priv->has_wpa)
-               return;
-
-       err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
-                             sizeof(buf), NULL, &buf);
-       if (err != 0)
-               return;
-
-       ie = orinoco_get_wpa_ie(buf, sizeof(buf));
-       if (ie) {
-               int rem = sizeof(buf) - (ie - &buf[0]);
-               wrqu.data.length = ie[1] + 2;
-               if (wrqu.data.length > rem)
-                       wrqu.data.length = rem;
-
-               if (wrqu.data.length)
-                       /* Send event to user space */
-                       wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, ie);
-       }
-}
-
-static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv)
-{
-       struct net_device *dev = priv->ndev;
-       struct hermes *hw = &priv->hw;
-       union iwreq_data wrqu;
-       int err;
-       u8 buf[88]; /* TODO: verify max size or IW_GENERIC_IE_MAX */
-       u8 *ie;
-
-       if (!priv->has_wpa)
-               return;
-
-       err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO,
-                             sizeof(buf), NULL, &buf);
-       if (err != 0)
-               return;
-
-       ie = orinoco_get_wpa_ie(buf, sizeof(buf));
-       if (ie) {
-               int rem = sizeof(buf) - (ie - &buf[0]);
-               wrqu.data.length = ie[1] + 2;
-               if (wrqu.data.length > rem)
-                       wrqu.data.length = rem;
-
-               if (wrqu.data.length)
-                       /* Send event to user space */
-                       wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, ie);
-       }
-}
-
-static void orinoco_send_wevents(struct work_struct *work)
-{
-       struct orinoco_private *priv =
-               container_of(work, struct orinoco_private, wevent_work);
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return;
-
-       orinoco_send_assocreqie_wevent(priv);
-       orinoco_send_assocrespie_wevent(priv);
-       orinoco_send_bssid_wevent(priv);
-
-       orinoco_unlock(priv, &flags);
-}
-
-static inline void orinoco_clear_scan_results(struct orinoco_private *priv,
-                                             unsigned long scan_age)
-{
-       if (priv->has_ext_scan) {
-               struct xbss_element *bss;
-               struct xbss_element *tmp_bss;
-
-               /* Blow away current list of scan results */
-               list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
-                       if (!scan_age ||
-                           time_after(jiffies, bss->last_scanned + scan_age)) {
-                               list_move_tail(&bss->list,
-                                              &priv->bss_free_list);
-                               /* Don't blow away ->list, just BSS data */
-                               memset(&bss->bss, 0, sizeof(bss->bss));
-                               bss->last_scanned = 0;
-                       }
-               }
-       } else {
-               struct bss_element *bss;
-               struct bss_element *tmp_bss;
-
-               /* Blow away current list of scan results */
-               list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
-                       if (!scan_age ||
-                           time_after(jiffies, bss->last_scanned + scan_age)) {
-                               list_move_tail(&bss->list,
-                                              &priv->bss_free_list);
-                               /* Don't blow away ->list, just BSS data */
-                               memset(&bss->bss, 0, sizeof(bss->bss));
-                               bss->last_scanned = 0;
-                       }
-               }
-       }
-}
-
-static void orinoco_add_ext_scan_result(struct orinoco_private *priv,
-                                       struct agere_ext_scan_info *atom)
-{
-       struct xbss_element *bss = NULL;
-       int found = 0;
-
-       /* Try to update an existing bss first */
-       list_for_each_entry(bss, &priv->bss_list, list) {
-               if (compare_ether_addr(bss->bss.bssid, atom->bssid))
-                       continue;
-               /* ESSID lengths */
-               if (bss->bss.data[1] != atom->data[1])
-                       continue;
-               if (memcmp(&bss->bss.data[2], &atom->data[2],
-                          atom->data[1]))
-                       continue;
-               found = 1;
-               break;
-       }
-
-       /* Grab a bss off the free list */
-       if (!found && !list_empty(&priv->bss_free_list)) {
-               bss = list_entry(priv->bss_free_list.next,
-                                struct xbss_element, list);
-               list_del(priv->bss_free_list.next);
-
-               list_add_tail(&bss->list, &priv->bss_list);
-       }
-
-       if (bss) {
-               /* Always update the BSS to get latest beacon info */
-               memcpy(&bss->bss, atom, sizeof(bss->bss));
-               bss->last_scanned = jiffies;
-       }
-}
-
-static int orinoco_process_scan_results(struct net_device *dev,
-                                       unsigned char *buf,
-                                       int len)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int                     offset;         /* In the scan data */
-       union hermes_scan_info *atom;
-       int                     atom_len;
-
-       switch (priv->firmware_type) {
-       case FIRMWARE_TYPE_AGERE:
-               atom_len = sizeof(struct agere_scan_apinfo);
-               offset = 0;
-               break;
-       case FIRMWARE_TYPE_SYMBOL:
-               /* Lack of documentation necessitates this hack.
-                * Different firmwares have 68 or 76 byte long atoms.
-                * We try modulo first.  If the length divides by both,
-                * we check what would be the channel in the second
-                * frame for a 68-byte atom.  76-byte atoms have 0 there.
-                * Valid channel cannot be 0.  */
-               if (len % 76)
-                       atom_len = 68;
-               else if (len % 68)
-                       atom_len = 76;
-               else if (len >= 1292 && buf[68] == 0)
-                       atom_len = 76;
-               else
-                       atom_len = 68;
-               offset = 0;
-               break;
-       case FIRMWARE_TYPE_INTERSIL:
-               offset = 4;
-               if (priv->has_hostscan) {
-                       atom_len = le16_to_cpup((__le16 *)buf);
-                       /* Sanity check for atom_len */
-                       if (atom_len < sizeof(struct prism2_scan_apinfo)) {
-                               printk(KERN_ERR "%s: Invalid atom_len in scan "
-                                      "data: %d\n", dev->name, atom_len);
-                               return -EIO;
-                       }
-               } else
-                       atom_len = offsetof(struct prism2_scan_apinfo, atim);
-               break;
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       /* Check that we got an whole number of atoms */
-       if ((len - offset) % atom_len) {
-               printk(KERN_ERR "%s: Unexpected scan data length %d, "
-                      "atom_len %d, offset %d\n", dev->name, len,
-                      atom_len, offset);
-               return -EIO;
-       }
-
-       orinoco_clear_scan_results(priv, msecs_to_jiffies(15000));
-
-       /* Read the entries one by one */
-       for (; offset + atom_len <= len; offset += atom_len) {
-               int found = 0;
-               struct bss_element *bss = NULL;
-
-               /* Get next atom */
-               atom = (union hermes_scan_info *) (buf + offset);
-
-               /* Try to update an existing bss first */
-               list_for_each_entry(bss, &priv->bss_list, list) {
-                       if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid))
-                               continue;
-                       if (le16_to_cpu(bss->bss.a.essid_len) !=
-                             le16_to_cpu(atom->a.essid_len))
-                               continue;
-                       if (memcmp(bss->bss.a.essid, atom->a.essid,
-                             le16_to_cpu(atom->a.essid_len)))
-                               continue;
-                       found = 1;
-                       break;
-               }
-
-               /* Grab a bss off the free list */
-               if (!found && !list_empty(&priv->bss_free_list)) {
-                       bss = list_entry(priv->bss_free_list.next,
-                                        struct bss_element, list);
-                       list_del(priv->bss_free_list.next);
-
-                       list_add_tail(&bss->list, &priv->bss_list);
-               }
-
-               if (bss) {
-                       /* Always update the BSS to get latest beacon info */
-                       memcpy(&bss->bss, atom, sizeof(bss->bss));
-                       bss->last_scanned = jiffies;
-               }
-       }
-
-       return 0;
-}
-
-static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       u16 infofid;
-       struct {
-               __le16 len;
-               __le16 type;
-       } __attribute__ ((packed)) info;
-       int len, type;
-       int err;
-
-       /* This is an answer to an INQUIRE command that we did earlier,
-        * or an information "event" generated by the card
-        * The controller return to us a pseudo frame containing
-        * the information in question - Jean II */
-       infofid = hermes_read_regn(hw, INFOFID);
-
-       /* Read the info frame header - don't try too hard */
-       err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
-                              infofid, 0);
-       if (err) {
-               printk(KERN_ERR "%s: error %d reading info frame. "
-                      "Frame dropped.\n", dev->name, err);
-               return;
-       }
-       
-       len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
-       type = le16_to_cpu(info.type);
-
-       switch (type) {
-       case HERMES_INQ_TALLIES: {
-               struct hermes_tallies_frame tallies;
-               struct iw_statistics *wstats = &priv->wstats;
-               
-               if (len > sizeof(tallies)) {
-                       printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
-                              dev->name, len);
-                       len = sizeof(tallies);
-               }
-               
-               err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
-                                      infofid, sizeof(info));
-               if (err)
-                       break;
-               
-               /* Increment our various counters */
-               /* wstats->discard.nwid - no wrong BSSID stuff */
-               wstats->discard.code +=
-                       le16_to_cpu(tallies.RxWEPUndecryptable);
-               if (len == sizeof(tallies))  
-                       wstats->discard.code +=
-                               le16_to_cpu(tallies.RxDiscards_WEPICVError) +
-                               le16_to_cpu(tallies.RxDiscards_WEPExcluded);
-               wstats->discard.misc +=
-                       le16_to_cpu(tallies.TxDiscardsWrongSA);
-               wstats->discard.fragment +=
-                       le16_to_cpu(tallies.RxMsgInBadMsgFragments);
-               wstats->discard.retries +=
-                       le16_to_cpu(tallies.TxRetryLimitExceeded);
-               /* wstats->miss.beacon - no match */
-       }
-       break;
-       case HERMES_INQ_LINKSTATUS: {
-               struct hermes_linkstatus linkstatus;
-               u16 newstatus;
-               int connected;
-
-               if (priv->iw_mode == IW_MODE_MONITOR)
-                       break;
-
-               if (len != sizeof(linkstatus)) {
-                       printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
-                              dev->name, len);
-                       break;
-               }
-
-               err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
-                                      infofid, sizeof(info));
-               if (err)
-                       break;
-               newstatus = le16_to_cpu(linkstatus.linkstatus);
-
-               /* Symbol firmware uses "out of range" to signal that
-                * the hostscan frame can be requested.  */
-               if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
-                   priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
-                   priv->has_hostscan && priv->scan_inprogress) {
-                       hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
-                       break;
-               }
-
-               connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
-                       || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
-                       || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
-
-               if (connected)
-                       netif_carrier_on(dev);
-               else if (!ignore_disconnect)
-                       netif_carrier_off(dev);
-
-               if (newstatus != priv->last_linkstatus) {
-                       priv->last_linkstatus = newstatus;
-                       print_linkstatus(dev, newstatus);
-                       /* The info frame contains only one word which is the
-                        * status (see hermes.h). The status is pretty boring
-                        * in itself, that's why we export the new BSSID...
-                        * Jean II */
-                       schedule_work(&priv->wevent_work);
-               }
-       }
-       break;
-       case HERMES_INQ_SCAN:
-               if (!priv->scan_inprogress && priv->bssid_fixed &&
-                   priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
-                       schedule_work(&priv->join_work);
-                       break;
-               }
-               /* fall through */
-       case HERMES_INQ_HOSTSCAN:
-       case HERMES_INQ_HOSTSCAN_SYMBOL: {
-               /* Result of a scanning. Contains information about
-                * cells in the vicinity - Jean II */
-               union iwreq_data        wrqu;
-               unsigned char *buf;
-
-               /* Scan is no longer in progress */
-               priv->scan_inprogress = 0;
-
-               /* Sanity check */
-               if (len > 4096) {
-                       printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
-                              dev->name, len);
-                       break;
-               }
-
-               /* Allocate buffer for results */
-               buf = kmalloc(len, GFP_ATOMIC);
-               if (buf == NULL)
-                       /* No memory, so can't printk()... */
-                       break;
-
-               /* Read scan data */
-               err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
-                                      infofid, sizeof(info));
-               if (err) {
-                       kfree(buf);
-                       break;
-               }
-
-#ifdef ORINOCO_DEBUG
-               {
-                       int     i;
-                       printk(KERN_DEBUG "Scan result [%02X", buf[0]);
-                       for(i = 1; i < (len * 2); i++)
-                               printk(":%02X", buf[i]);
-                       printk("]\n");
-               }
-#endif /* ORINOCO_DEBUG */
-
-               if (orinoco_process_scan_results(dev, buf, len) == 0) {
-                       /* Send an empty event to user space.
-                        * We don't send the received data on the event because
-                        * it would require us to do complex transcoding, and
-                        * we want to minimise the work done in the irq handler
-                        * Use a request to extract the data - Jean II */
-                       wrqu.data.length = 0;
-                       wrqu.data.flags = 0;
-                       wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
-               }
-               kfree(buf);
-       }
-       break;
-       case HERMES_INQ_CHANNELINFO:
-       {
-               struct agere_ext_scan_info *bss;
-
-               if (!priv->scan_inprogress) {
-                       printk(KERN_DEBUG "%s: Got chaninfo without scan, "
-                              "len=%d\n", dev->name, len);
-                       break;
-               }
-
-               /* An empty result indicates that the scan is complete */
-               if (len == 0) {
-                       union iwreq_data        wrqu;
-
-                       /* Scan is no longer in progress */
-                       priv->scan_inprogress = 0;
-
-                       wrqu.data.length = 0;
-                       wrqu.data.flags = 0;
-                       wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
-                       break;
-               }
-
-               /* Sanity check */
-               else if (len > sizeof(*bss)) {
-                       printk(KERN_WARNING
-                              "%s: Ext scan results too large (%d bytes). "
-                              "Truncating results to %zd bytes.\n",
-                              dev->name, len, sizeof(*bss));
-                       len = sizeof(*bss);
-               } else if (len < (offsetof(struct agere_ext_scan_info,
-                                          data) + 2)) {
-                       /* Drop this result now so we don't have to
-                        * keep checking later */
-                       printk(KERN_WARNING
-                              "%s: Ext scan results too short (%d bytes)\n",
-                              dev->name, len);
-                       break;
-               }
-
-               bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
-               if (bss == NULL)
-                       break;
-
-               /* Read scan data */
-               err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len,
-                                      infofid, sizeof(info));
-               if (err) {
-                       kfree(bss);
-                       break;
-               }
-
-               orinoco_add_ext_scan_result(priv, bss);
-
-               kfree(bss);
-               break;
-       }
-       case HERMES_INQ_SEC_STAT_AGERE:
-               /* Security status (Agere specific) */
-               /* Ignore this frame for now */
-               if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
-                       break;
-               /* fall through */
-       default:
-               printk(KERN_DEBUG "%s: Unknown information frame received: "
-                      "type 0x%04x, length %d\n", dev->name, type, len);
-               /* We don't actually do anything about it */
-               break;
-       }
-}
-
-static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
-{
-       if (net_ratelimit())
-               printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
-}
-
-/********************************************************************/
-/* Internal hardware control routines                               */
-/********************************************************************/
-
-int __orinoco_up(struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct hermes *hw = &priv->hw;
-       int err;
-
-       netif_carrier_off(dev); /* just to make sure */
-
-       err = __orinoco_program_rids(dev);
-       if (err) {
-               printk(KERN_ERR "%s: Error %d configuring card\n",
-                      dev->name, err);
-               return err;
-       }
-
-       /* Fire things up again */
-       hermes_set_irqmask(hw, ORINOCO_INTEN);
-       err = hermes_enable_port(hw, 0);
-       if (err) {
-               printk(KERN_ERR "%s: Error %d enabling MAC port\n",
-                      dev->name, err);
-               return err;
-       }
-
-       netif_start_queue(dev);
-
-       return 0;
-}
-
-int __orinoco_down(struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct hermes *hw = &priv->hw;
-       int err;
-
-       netif_stop_queue(dev);
-
-       if (! priv->hw_unavailable) {
-               if (! priv->broken_disableport) {
-                       err = hermes_disable_port(hw, 0);
-                       if (err) {
-                               /* Some firmwares (e.g. Intersil 1.3.x) seem
-                                * to have problems disabling the port, oh
-                                * well, too bad. */
-                               printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
-                                      dev->name, err);
-                               priv->broken_disableport = 1;
-                       }
-               }
-               hermes_set_irqmask(hw, 0);
-               hermes_write_regn(hw, EVACK, 0xffff);
-       }
-       
-       /* firmware will have to reassociate */
-       netif_carrier_off(dev);
-       priv->last_linkstatus = 0xffff;
-
-       return 0;
-}
-
-static int orinoco_allocate_fid(struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct hermes *hw = &priv->hw;
-       int err;
-
-       err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
-       if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
-               /* Try workaround for old Symbol firmware bug */
-               printk(KERN_WARNING "%s: firmware ALLOC bug detected "
-                      "(old Symbol firmware?). Trying to work around... ",
-                      dev->name);
-               
-               priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
-               err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
-               if (err)
-                       printk("failed!\n");
-               else
-                       printk("ok.\n");
-       }
-
-       return err;
-}
-
-int orinoco_reinit_firmware(struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct hermes *hw = &priv->hw;
-       int err;
-
-       err = hermes_init(hw);
-       if (!err)
-               err = orinoco_allocate_fid(dev);
-
-       return err;
-}
-
-static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
-{
-       hermes_t *hw = &priv->hw;
-       int err = 0;
-
-       if (priv->bitratemode >= BITRATE_TABLE_SIZE) {
-               printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
-                      priv->ndev->name, priv->bitratemode);
-               return -EINVAL;
-       }
-
-       switch (priv->firmware_type) {
-       case FIRMWARE_TYPE_AGERE:
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFTXRATECONTROL,
-                                          bitrate_table[priv->bitratemode].agere_txratectrl);
-               break;
-       case FIRMWARE_TYPE_INTERSIL:
-       case FIRMWARE_TYPE_SYMBOL:
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFTXRATECONTROL,
-                                          bitrate_table[priv->bitratemode].intersil_txratectrl);
-               break;
-       default:
-               BUG();
-       }
-
-       return err;
-}
-
-/* Set fixed AP address */
-static int __orinoco_hw_set_wap(struct orinoco_private *priv)
-{
-       int roaming_flag;
-       int err = 0;
-       hermes_t *hw = &priv->hw;
-
-       switch (priv->firmware_type) {
-       case FIRMWARE_TYPE_AGERE:
-               /* not supported */
-               break;
-       case FIRMWARE_TYPE_INTERSIL:
-               if (priv->bssid_fixed)
-                       roaming_flag = 2;
-               else
-                       roaming_flag = 1;
-
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFROAMINGMODE,
-                                          roaming_flag);
-               break;
-       case FIRMWARE_TYPE_SYMBOL:
-               err = HERMES_WRITE_RECORD(hw, USER_BAP,
-                                         HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
-                                         &priv->desired_bssid);
-               break;
-       }
-       return err;
-}
-
-/* Change the WEP keys and/or the current keys.  Can be called
- * either from __orinoco_hw_setup_enc() or directly from
- * orinoco_ioctl_setiwencode().  In the later case the association
- * with the AP is not broken (if the firmware can handle it),
- * which is needed for 802.1x implementations. */
-static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
-{
-       hermes_t *hw = &priv->hw;
-       int err = 0;
-
-       switch (priv->firmware_type) {
-       case FIRMWARE_TYPE_AGERE:
-               err = HERMES_WRITE_RECORD(hw, USER_BAP,
-                                         HERMES_RID_CNFWEPKEYS_AGERE,
-                                         &priv->keys);
-               if (err)
-                       return err;
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFTXKEY_AGERE,
-                                          priv->tx_key);
-               if (err)
-                       return err;
-               break;
-       case FIRMWARE_TYPE_INTERSIL:
-       case FIRMWARE_TYPE_SYMBOL:
-               {
-                       int keylen;
-                       int i;
-
-                       /* Force uniform key length to work around firmware bugs */
-                       keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
-                       
-                       if (keylen > LARGE_KEY_SIZE) {
-                               printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
-                                      priv->ndev->name, priv->tx_key, keylen);
-                               return -E2BIG;
-                       }
-
-                       /* Write all 4 keys */
-                       for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
-                               err = hermes_write_ltv(hw, USER_BAP,
-                                                      HERMES_RID_CNFDEFAULTKEY0 + i,
-                                                      HERMES_BYTES_TO_RECLEN(keylen),
-                                                      priv->keys[i].data);
-                               if (err)
-                                       return err;
-                       }
-
-                       /* Write the index of the key used in transmission */
-                       err = hermes_write_wordrec(hw, USER_BAP,
-                                                  HERMES_RID_CNFWEPDEFAULTKEYID,
-                                                  priv->tx_key);
-                       if (err)
-                               return err;
-               }
-               break;
-       }
-
-       return 0;
-}
-
-static int __orinoco_hw_setup_enc(struct orinoco_private *priv)
-{
-       hermes_t *hw = &priv->hw;
-       int err = 0;
-       int master_wep_flag;
-       int auth_flag;
-       int enc_flag;
-
-       /* Setup WEP keys for WEP and WPA */
-       if (priv->encode_alg)
-               __orinoco_hw_setup_wepkeys(priv);
-
-       if (priv->wep_restrict)
-               auth_flag = HERMES_AUTH_SHARED_KEY;
-       else
-               auth_flag = HERMES_AUTH_OPEN;
-
-       if (priv->wpa_enabled)
-               enc_flag = 2;
-       else if (priv->encode_alg == IW_ENCODE_ALG_WEP)
-               enc_flag = 1;
-       else
-               enc_flag = 0;
-
-       switch (priv->firmware_type) {
-       case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
-               if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
-                       /* Enable the shared-key authentication. */
-                       err = hermes_write_wordrec(hw, USER_BAP,
-                                                  HERMES_RID_CNFAUTHENTICATION_AGERE,
-                                                  auth_flag);
-               }
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFWEPENABLED_AGERE,
-                                          enc_flag);
-               if (err)
-                       return err;
-
-               if (priv->has_wpa) {
-                       /* Set WPA key management */
-                       err = hermes_write_wordrec(hw, USER_BAP,
-                                 HERMES_RID_CNFSETWPAAUTHMGMTSUITE_AGERE,
-                                 priv->key_mgmt);
-                       if (err)
-                               return err;
-               }
-
-               break;
-
-       case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
-       case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
-               if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
-                       if (priv->wep_restrict ||
-                           (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
-                               master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
-                                                 HERMES_WEP_EXCL_UNENCRYPTED;
-                       else
-                               master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
-
-                       err = hermes_write_wordrec(hw, USER_BAP,
-                                                  HERMES_RID_CNFAUTHENTICATION,
-                                                  auth_flag);
-                       if (err)
-                               return err;
-               } else
-                       master_wep_flag = 0;
-
-               if (priv->iw_mode == IW_MODE_MONITOR)
-                       master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
-
-               /* Master WEP setting : on/off */
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFWEPFLAGS_INTERSIL,
-                                          master_wep_flag);
-               if (err)
-                       return err;     
-
-               break;
-       }
-
-       return 0;
-}
-
-/* key must be 32 bytes, including the tx and rx MIC keys.
- * rsc must be 8 bytes
- * tsc must be 8 bytes or NULL
- */
-static int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
-                                    u8 *key, u8 *rsc, u8 *tsc)
-{
-       struct {
-               __le16 idx;
-               u8 rsc[IW_ENCODE_SEQ_MAX_SIZE];
-               u8 key[TKIP_KEYLEN];
-               u8 tx_mic[MIC_KEYLEN];
-               u8 rx_mic[MIC_KEYLEN];
-               u8 tsc[IW_ENCODE_SEQ_MAX_SIZE];
-       } __attribute__ ((packed)) buf;
-       int ret;
-       int err;
-       int k;
-       u16 xmitting;
-
-       key_idx &= 0x3;
-
-       if (set_tx)
-               key_idx |= 0x8000;
-
-       buf.idx = cpu_to_le16(key_idx);
-       memcpy(buf.key, key,
-              sizeof(buf.key) + sizeof(buf.tx_mic) + sizeof(buf.rx_mic));
-
-       if (rsc == NULL)
-               memset(buf.rsc, 0, sizeof(buf.rsc));
-       else
-               memcpy(buf.rsc, rsc, sizeof(buf.rsc));
-
-       if (tsc == NULL) {
-               memset(buf.tsc, 0, sizeof(buf.tsc));
-               buf.tsc[4] = 0x10;
-       } else {
-               memcpy(buf.tsc, tsc, sizeof(buf.tsc));
-       }
-
-       /* Wait upto 100ms for tx queue to empty */
-       k = 100;
-       do {
-               k--;
-               udelay(1000);
-               ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY,
-                                         &xmitting);
-               if (ret)
-                       break;
-       } while ((k > 0) && xmitting);
-
-       if (k == 0)
-               ret = -ETIMEDOUT;
-
-       err = HERMES_WRITE_RECORD(hw, USER_BAP,
-                                 HERMES_RID_CNFADDDEFAULTTKIPKEY_AGERE,
-                                 &buf);
-
-       return ret ? ret : err;
-}
-
-static int orinoco_clear_tkip_key(struct orinoco_private *priv,
-                                 int key_idx)
-{
-       hermes_t *hw = &priv->hw;
-       int err;
-
-       memset(&priv->tkip_key[key_idx], 0, sizeof(priv->tkip_key[key_idx]));
-       err = hermes_write_wordrec(hw, USER_BAP,
-                                  HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE,
-                                  key_idx);
-       if (err)
-               printk(KERN_WARNING "%s: Error %d clearing TKIP key %d\n",
-                      priv->ndev->name, err, key_idx);
-       return err;
-}
-
-static int __orinoco_program_rids(struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       int err;
-       struct hermes_idstring idbuf;
-
-       /* Set the MAC address */
-       err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
-                              HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
-       if (err) {
-               printk(KERN_ERR "%s: Error %d setting MAC address\n",
-                      dev->name, err);
-               return err;
-       }
-
-       /* Set up the link mode */
-       err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
-                                  priv->port_type);
-       if (err) {
-               printk(KERN_ERR "%s: Error %d setting port type\n",
-                      dev->name, err);
-               return err;
-       }
-       /* Set the channel/frequency */
-       if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFOWNCHANNEL,
-                                          priv->channel);
-               if (err) {
-                       printk(KERN_ERR "%s: Error %d setting channel %d\n",
-                              dev->name, err, priv->channel);
-                       return err;
-               }
-       }
-
-       if (priv->has_ibss) {
-               u16 createibss;
-
-               if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
-                       printk(KERN_WARNING "%s: This firmware requires an "
-                              "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
-                       /* With wvlan_cs, in this case, we would crash.
-                        * hopefully, this driver will behave better...
-                        * Jean II */
-                       createibss = 0;
-               } else {
-                       createibss = priv->createibss;
-               }
-               
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFCREATEIBSS,
-                                          createibss);
-               if (err) {
-                       printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
-                              dev->name, err);
-                       return err;
-               }
-       }
-
-       /* Set the desired BSSID */
-       err = __orinoco_hw_set_wap(priv);
-       if (err) {
-               printk(KERN_ERR "%s: Error %d setting AP address\n",
-                      dev->name, err);
-               return err;
-       }
-       /* Set the desired ESSID */
-       idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
-       memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
-       /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
-       err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
-                              HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
-                              &idbuf);
-       if (err) {
-               printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
-                      dev->name, err);
-               return err;
-       }
-       err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
-                              HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
-                              &idbuf);
-       if (err) {
-               printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
-                      dev->name, err);
-               return err;
-       }
-
-       /* Set the station name */
-       idbuf.len = cpu_to_le16(strlen(priv->nick));
-       memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
-       err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
-                              HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
-                              &idbuf);
-       if (err) {
-               printk(KERN_ERR "%s: Error %d setting nickname\n",
-                      dev->name, err);
-               return err;
-       }
-
-       /* Set AP density */
-       if (priv->has_sensitivity) {
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFSYSTEMSCALE,
-                                          priv->ap_density);
-               if (err) {
-                       printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE.  "
-                              "Disabling sensitivity control\n",
-                              dev->name, err);
-
-                       priv->has_sensitivity = 0;
-               }
-       }
-
-       /* Set RTS threshold */
-       err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
-                                  priv->rts_thresh);
-       if (err) {
-               printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
-                      dev->name, err);
-               return err;
-       }
-
-       /* Set fragmentation threshold or MWO robustness */
-       if (priv->has_mwo)
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFMWOROBUST_AGERE,
-                                          priv->mwo_robust);
-       else
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
-                                          priv->frag_thresh);
-       if (err) {
-               printk(KERN_ERR "%s: Error %d setting fragmentation\n",
-                      dev->name, err);
-               return err;
-       }
-
-       /* Set bitrate */
-       err = __orinoco_hw_set_bitrate(priv);
-       if (err) {
-               printk(KERN_ERR "%s: Error %d setting bitrate\n",
-                      dev->name, err);
-               return err;
-       }
-
-       /* Set power management */
-       if (priv->has_pm) {
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFPMENABLED,
-                                          priv->pm_on);
-               if (err) {
-                       printk(KERN_ERR "%s: Error %d setting up PM\n",
-                              dev->name, err);
-                       return err;
-               }
-
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFMULTICASTRECEIVE,
-                                          priv->pm_mcast);
-               if (err) {
-                       printk(KERN_ERR "%s: Error %d setting up PM\n",
-                              dev->name, err);
-                       return err;
-               }
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFMAXSLEEPDURATION,
-                                          priv->pm_period);
-               if (err) {
-                       printk(KERN_ERR "%s: Error %d setting up PM\n",
-                              dev->name, err);
-                       return err;
-               }
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFPMHOLDOVERDURATION,
-                                          priv->pm_timeout);
-               if (err) {
-                       printk(KERN_ERR "%s: Error %d setting up PM\n",
-                              dev->name, err);
-                       return err;
-               }
-       }
-
-       /* Set preamble - only for Symbol so far... */
-       if (priv->has_preamble) {
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFPREAMBLE_SYMBOL,
-                                          priv->preamble);
-               if (err) {
-                       printk(KERN_ERR "%s: Error %d setting preamble\n",
-                              dev->name, err);
-                       return err;
-               }
-       }
-
-       /* Set up encryption */
-       if (priv->has_wep || priv->has_wpa) {
-               err = __orinoco_hw_setup_enc(priv);
-               if (err) {
-                       printk(KERN_ERR "%s: Error %d activating encryption\n",
-                              dev->name, err);
-                       return err;
-               }
-       }
-
-       if (priv->iw_mode == IW_MODE_MONITOR) {
-               /* Enable monitor mode */
-               dev->type = ARPHRD_IEEE80211;
-               err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 
-                                           HERMES_TEST_MONITOR, 0, NULL);
-       } else {
-               /* Disable monitor mode */
-               dev->type = ARPHRD_ETHER;
-               err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
-                                           HERMES_TEST_STOP, 0, NULL);
-       }
-       if (err)
-               return err;
-
-       /* Set promiscuity / multicast*/
-       priv->promiscuous = 0;
-       priv->mc_count = 0;
-
-       /* FIXME: what about netif_tx_lock */
-       __orinoco_set_multicast_list(dev);
-
-       return 0;
-}
-
-/* FIXME: return int? */
-static void
-__orinoco_set_multicast_list(struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       int err = 0;
-       int promisc, mc_count;
-
-       /* The Hermes doesn't seem to have an allmulti mode, so we go
-        * into promiscuous mode and let the upper levels deal. */
-       if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
-            (dev->mc_count > MAX_MULTICAST(priv)) ) {
-               promisc = 1;
-               mc_count = 0;
-       } else {
-               promisc = 0;
-               mc_count = dev->mc_count;
-       }
-
-       if (promisc != priv->promiscuous) {
-               err = hermes_write_wordrec(hw, USER_BAP,
-                                          HERMES_RID_CNFPROMISCUOUSMODE,
-                                          promisc);
-               if (err) {
-                       printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
-                              dev->name, err);
-               } else 
-                       priv->promiscuous = promisc;
-       }
-
-       /* If we're not in promiscuous mode, then we need to set the
-        * group address if either we want to multicast, or if we were
-        * multicasting and want to stop */
-       if (! promisc && (mc_count || priv->mc_count) ) {
-               struct dev_mc_list *p = dev->mc_list;
-               struct hermes_multicast mclist;
-               int i;
-
-               for (i = 0; i < mc_count; i++) {
-                       /* paranoia: is list shorter than mc_count? */
-                       BUG_ON(! p);
-                       /* paranoia: bad address size in list? */
-                       BUG_ON(p->dmi_addrlen != ETH_ALEN);
-                       
-                       memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
-                       p = p->next;
-               }
-               
-               if (p)
-                       printk(KERN_WARNING "%s: Multicast list is "
-                              "longer than mc_count\n", dev->name);
-
-               err = hermes_write_ltv(hw, USER_BAP,
-                                  HERMES_RID_CNFGROUPADDRESSES,
-                                  HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN),
-                                  &mclist);
-               if (err)
-                       printk(KERN_ERR "%s: Error %d setting multicast list.\n",
-                              dev->name, err);
-               else
-                       priv->mc_count = mc_count;
-       }
-}
-
-/* This must be called from user context, without locks held - use
- * schedule_work() */
-static void orinoco_reset(struct work_struct *work)
-{
-       struct orinoco_private *priv =
-               container_of(work, struct orinoco_private, reset_work);
-       struct net_device *dev = priv->ndev;
-       struct hermes *hw = &priv->hw;
-       int err;
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               /* When the hardware becomes available again, whatever
-                * detects that is responsible for re-initializing
-                * it. So no need for anything further */
-               return;
-
-       netif_stop_queue(dev);
-
-       /* Shut off interrupts.  Depending on what state the hardware
-        * is in, this might not work, but we'll try anyway */
-       hermes_set_irqmask(hw, 0);
-       hermes_write_regn(hw, EVACK, 0xffff);
-
-       priv->hw_unavailable++;
-       priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
-       netif_carrier_off(dev);
-
-       orinoco_unlock(priv, &flags);
-
-       /* Scanning support: Cleanup of driver struct */
-       orinoco_clear_scan_results(priv, 0);
-       priv->scan_inprogress = 0;
-
-       if (priv->hard_reset) {
-               err = (*priv->hard_reset)(priv);
-               if (err) {
-                       printk(KERN_ERR "%s: orinoco_reset: Error %d "
-                              "performing hard reset\n", dev->name, err);
-                       goto disable;
-               }
-       }
-
-       if (priv->do_fw_download) {
-               err = orinoco_download(priv);
-               if (err)
-                       priv->do_fw_download = 0;
-       }
-
-       err = orinoco_reinit_firmware(dev);
-       if (err) {
-               printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
-                      dev->name, err);
-               goto disable;
-       }
-
-       spin_lock_irq(&priv->lock); /* This has to be called from user context */
-
-       priv->hw_unavailable--;
-
-       /* priv->open or priv->hw_unavailable might have changed while
-        * we dropped the lock */
-       if (priv->open && (! priv->hw_unavailable)) {
-               err = __orinoco_up(dev);
-               if (err) {
-                       printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
-                              dev->name, err);
-               } else
-                       dev->trans_start = jiffies;
-       }
-
-       spin_unlock_irq(&priv->lock);
-
-       return;
- disable:
-       hermes_set_irqmask(hw, 0);
-       netif_device_detach(dev);
-       printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
-}
-
-/********************************************************************/
-/* Interrupt handler                                                */
-/********************************************************************/
-
-static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
-{
-       printk(KERN_DEBUG "%s: TICK\n", dev->name);
-}
-
-static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
-{
-       /* This seems to happen a fair bit under load, but ignoring it
-          seems to work fine...*/
-       printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
-              dev->name);
-}
-
-irqreturn_t orinoco_interrupt(int irq, void *dev_id)
-{
-       struct net_device *dev = dev_id;
-       struct orinoco_private *priv = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       int count = MAX_IRQLOOPS_PER_IRQ;
-       u16 evstat, events;
-       /* These are used to detect a runaway interrupt situation */
-       /* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
-        * we panic and shut down the hardware */
-       static int last_irq_jiffy = 0; /* jiffies value the last time
-                                       * we were called */
-       static int loops_this_jiffy = 0;
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0) {
-               /* If hw is unavailable - we don't know if the irq was
-                * for us or not */
-               return IRQ_HANDLED;
-       }
-
-       evstat = hermes_read_regn(hw, EVSTAT);
-       events = evstat & hw->inten;
-       if (! events) {
-               orinoco_unlock(priv, &flags);
-               return IRQ_NONE;
-       }
-       
-       if (jiffies != last_irq_jiffy)
-               loops_this_jiffy = 0;
-       last_irq_jiffy = jiffies;
-
-       while (events && count--) {
-               if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
-                       printk(KERN_WARNING "%s: IRQ handler is looping too "
-                              "much! Resetting.\n", dev->name);
-                       /* Disable interrupts for now */
-                       hermes_set_irqmask(hw, 0);
-                       schedule_work(&priv->reset_work);
-                       break;
-               }
-
-               /* Check the card hasn't been removed */
-               if (! hermes_present(hw)) {
-                       DEBUG(0, "orinoco_interrupt(): card removed\n");
-                       break;
-               }
-
-               if (events & HERMES_EV_TICK)
-                       __orinoco_ev_tick(dev, hw);
-               if (events & HERMES_EV_WTERR)
-                       __orinoco_ev_wterr(dev, hw);
-               if (events & HERMES_EV_INFDROP)
-                       __orinoco_ev_infdrop(dev, hw);
-               if (events & HERMES_EV_INFO)
-                       __orinoco_ev_info(dev, hw);
-               if (events & HERMES_EV_RX)
-                       __orinoco_ev_rx(dev, hw);
-               if (events & HERMES_EV_TXEXC)
-                       __orinoco_ev_txexc(dev, hw);
-               if (events & HERMES_EV_TX)
-                       __orinoco_ev_tx(dev, hw);
-               if (events & HERMES_EV_ALLOC)
-                       __orinoco_ev_alloc(dev, hw);
-               
-               hermes_write_regn(hw, EVACK, evstat);
-
-               evstat = hermes_read_regn(hw, EVSTAT);
-               events = evstat & hw->inten;
-       };
-
-       orinoco_unlock(priv, &flags);
-       return IRQ_HANDLED;
-}
-
-/********************************************************************/
-/* Initialization                                                   */
-/********************************************************************/
-
-struct comp_id {
-       u16 id, variant, major, minor;
-} __attribute__ ((packed));
-
-static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
-{
-       if (nic_id->id < 0x8000)
-               return FIRMWARE_TYPE_AGERE;
-       else if (nic_id->id == 0x8000 && nic_id->major == 0)
-               return FIRMWARE_TYPE_SYMBOL;
-       else
-               return FIRMWARE_TYPE_INTERSIL;
-}
-
-/* Set priv->firmware type, determine firmware properties */
-static int determine_firmware(struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       int err;
-       struct comp_id nic_id, sta_id;
-       unsigned int firmver;
-       char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
-
-       /* Get the hardware version */
-       err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
-       if (err) {
-               printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
-                      dev->name, err);
-               return err;
-       }
-
-       le16_to_cpus(&nic_id.id);
-       le16_to_cpus(&nic_id.variant);
-       le16_to_cpus(&nic_id.major);
-       le16_to_cpus(&nic_id.minor);
-       printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
-              dev->name, nic_id.id, nic_id.variant,
-              nic_id.major, nic_id.minor);
-
-       priv->firmware_type = determine_firmware_type(&nic_id);
-
-       /* Get the firmware version */
-       err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
-       if (err) {
-               printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
-                      dev->name, err);
-               return err;
-       }
-
-       le16_to_cpus(&sta_id.id);
-       le16_to_cpus(&sta_id.variant);
-       le16_to_cpus(&sta_id.major);
-       le16_to_cpus(&sta_id.minor);
-       printk(KERN_DEBUG "%s: Station identity  %04x:%04x:%04x:%04x\n",
-              dev->name, sta_id.id, sta_id.variant,
-              sta_id.major, sta_id.minor);
-
-       switch (sta_id.id) {
-       case 0x15:
-               printk(KERN_ERR "%s: Primary firmware is active\n",
-                      dev->name);
-               return -ENODEV;
-       case 0x14b:
-               printk(KERN_ERR "%s: Tertiary firmware is active\n",
-                      dev->name);
-               return -ENODEV;
-       case 0x1f:      /* Intersil, Agere, Symbol Spectrum24 */
-       case 0x21:      /* Symbol Spectrum24 Trilogy */
-               break;
-       default:
-               printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
-                      dev->name);
-               break;
-       }
-
-       /* Default capabilities */
-       priv->has_sensitivity = 1;
-       priv->has_mwo = 0;
-       priv->has_preamble = 0;
-       priv->has_port3 = 1;
-       priv->has_ibss = 1;
-       priv->has_wep = 0;
-       priv->has_big_wep = 0;
-       priv->has_alt_txcntl = 0;
-       priv->has_ext_scan = 0;
-       priv->has_wpa = 0;
-       priv->do_fw_download = 0;
-
-       /* Determine capabilities from the firmware version */
-       switch (priv->firmware_type) {
-       case FIRMWARE_TYPE_AGERE:
-               /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
-                  ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
-               snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
-                        "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
-
-               firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
-
-               priv->has_ibss = (firmver >= 0x60006);
-               priv->has_wep = (firmver >= 0x40020);
-               priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
-                                         Gold cards from the others? */
-               priv->has_mwo = (firmver >= 0x60000);
-               priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
-               priv->ibss_port = 1;
-               priv->has_hostscan = (firmver >= 0x8000a);
-               priv->do_fw_download = 1;
-               priv->broken_monitor = (firmver >= 0x80000);
-               priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
-               priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
-               priv->has_wpa = (firmver >= 0x9002a);
-               /* Tested with Agere firmware :
-                *      1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
-                * Tested CableTron firmware : 4.32 => Anton */
-               break;
-       case FIRMWARE_TYPE_SYMBOL:
-               /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
-               /* Intel MAC : 00:02:B3:* */
-               /* 3Com MAC : 00:50:DA:* */
-               memset(tmp, 0, sizeof(tmp));
-               /* Get the Symbol firmware version */
-               err = hermes_read_ltv(hw, USER_BAP,
-                                     HERMES_RID_SECONDARYVERSION_SYMBOL,
-                                     SYMBOL_MAX_VER_LEN, NULL, &tmp);
-               if (err) {
-                       printk(KERN_WARNING
-                              "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n",
-                              dev->name, err);
-                       firmver = 0;
-                       tmp[0] = '\0';
-               } else {
-                       /* The firmware revision is a string, the format is
-                        * something like : "V2.20-01".
-                        * Quick and dirty parsing... - Jean II
-                        */
-                       firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12)
-                               | ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4)
-                               | (tmp[7] - '0');
-
-                       tmp[SYMBOL_MAX_VER_LEN] = '\0';
-               }
-
-               snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
-                        "Symbol %s", tmp);
-
-               priv->has_ibss = (firmver >= 0x20000);
-               priv->has_wep = (firmver >= 0x15012);
-               priv->has_big_wep = (firmver >= 0x20000);
-               priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) || 
-                              (firmver >= 0x29000 && firmver < 0x30000) ||
-                              firmver >= 0x31000;
-               priv->has_preamble = (firmver >= 0x20000);
-               priv->ibss_port = 4;
-
-               /* Symbol firmware is found on various cards, but
-                * there has been no attempt to check firmware
-                * download on non-spectrum_cs based cards.
-                *
-                * Given that the Agere firmware download works
-                * differently, we should avoid doing a firmware
-                * download with the Symbol algorithm on non-spectrum
-                * cards.
-                *
-                * For now we can identify a spectrum_cs based card
-                * because it has a firmware reset function.
-                */
-               priv->do_fw_download = (priv->stop_fw != NULL);
-
-               priv->broken_disableport = (firmver == 0x25013) ||
-                                          (firmver >= 0x30000 && firmver <= 0x31000);
-               priv->has_hostscan = (firmver >= 0x31001) ||
-                                    (firmver >= 0x29057 && firmver < 0x30000);
-               /* Tested with Intel firmware : 0x20015 => Jean II */
-               /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
-               break;
-       case FIRMWARE_TYPE_INTERSIL:
-               /* D-Link, Linksys, Adtron, ZoomAir, and many others...
-                * Samsung, Compaq 100/200 and Proxim are slightly
-                * different and less well tested */
-               /* D-Link MAC : 00:40:05:* */
-               /* Addtron MAC : 00:90:D1:* */
-               snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
-                        "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
-                        sta_id.variant);
-
-               firmver = ((unsigned long)sta_id.major << 16) |
-                       ((unsigned long)sta_id.minor << 8) | sta_id.variant;
-
-               priv->has_ibss = (firmver >= 0x000700); /* FIXME */
-               priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
-               priv->has_pm = (firmver >= 0x000700);
-               priv->has_hostscan = (firmver >= 0x010301);
-
-               if (firmver >= 0x000800)
-                       priv->ibss_port = 0;
-               else {
-                       printk(KERN_NOTICE "%s: Intersil firmware earlier "
-                              "than v0.8.x - several features not supported\n",
-                              dev->name);
-                       priv->ibss_port = 1;
-               }
-               break;
-       }
-       printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
-              priv->fw_name);
-
-       return 0;
-}
-
-static int orinoco_init(struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       int err = 0;
-       struct hermes_idstring nickbuf;
-       u16 reclen;
-       int len;
-       DECLARE_MAC_BUF(mac);
-
-       /* No need to lock, the hw_unavailable flag is already set in
-        * alloc_orinocodev() */
-       priv->nicbuf_size = IEEE80211_FRAME_LEN + ETH_HLEN;
-
-       /* Initialize the firmware */
-       err = hermes_init(hw);
-       if (err != 0) {
-               printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
-                      dev->name, err);
-               goto out;
-       }
-
-       err = determine_firmware(dev);
-       if (err != 0) {
-               printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
-                      dev->name);
-               goto out;
-       }
-
-       if (priv->do_fw_download) {
-               err = orinoco_download(priv);
-               if (err)
-                       priv->do_fw_download = 0;
-
-               /* Check firmware version again */
-               err = determine_firmware(dev);
-               if (err != 0) {
-                       printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
-                              dev->name);
-                       goto out;
-               }
-       }
-
-       if (priv->has_port3)
-               printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);
-       if (priv->has_ibss)
-               printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
-                      dev->name);
-       if (priv->has_wep) {
-               printk(KERN_DEBUG "%s: WEP supported, ", dev->name);
-               if (priv->has_big_wep)
-                       printk("104-bit key\n");
-               else
-                       printk("40-bit key\n");
-       }
-       if (priv->has_wpa) {
-               printk(KERN_DEBUG "%s: WPA-PSK supported\n", dev->name);
-               if (orinoco_mic_init(priv)) {
-                       printk(KERN_ERR "%s: Failed to setup MIC crypto "
-                              "algorithm. Disabling WPA support\n", dev->name);
-                       priv->has_wpa = 0;
-               }
-       }
-
-       /* Now we have the firmware capabilities, allocate appropiate
-        * sized scan buffers */
-       if (orinoco_bss_data_allocate(priv))
-               goto out;
-       orinoco_bss_data_init(priv);
-
-       /* Get the MAC address */
-       err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
-                             ETH_ALEN, NULL, dev->dev_addr);
-       if (err) {
-               printk(KERN_WARNING "%s: failed to read MAC address!\n",
-                      dev->name);
-               goto out;
-       }
-
-       printk(KERN_DEBUG "%s: MAC address %s\n",
-              dev->name, print_mac(mac, dev->dev_addr));
-
-       /* Get the station name */
-       err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
-                             sizeof(nickbuf), &reclen, &nickbuf);
-       if (err) {
-               printk(KERN_ERR "%s: failed to read station name\n",
-                      dev->name);
-               goto out;
-       }
-       if (nickbuf.len)
-               len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
-       else
-               len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
-       memcpy(priv->nick, &nickbuf.val, len);
-       priv->nick[len] = '\0';
-
-       printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
-
-       err = orinoco_allocate_fid(dev);
-       if (err) {
-               printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
-                      dev->name);
-               goto out;
-       }
-
-       /* Get allowed channels */
-       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
-                                 &priv->channel_mask);
-       if (err) {
-               printk(KERN_ERR "%s: failed to read channel list!\n",
-                      dev->name);
-               goto out;
-       }
-
-       /* Get initial AP density */
-       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
-                                 &priv->ap_density);
-       if (err || priv->ap_density < 1 || priv->ap_density > 3) {
-               priv->has_sensitivity = 0;
-       }
-
-       /* Get initial RTS threshold */
-       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
-                                 &priv->rts_thresh);
-       if (err) {
-               printk(KERN_ERR "%s: failed to read RTS threshold!\n",
-                      dev->name);
-               goto out;
-       }
-
-       /* Get initial fragmentation settings */
-       if (priv->has_mwo)
-               err = hermes_read_wordrec(hw, USER_BAP,
-                                         HERMES_RID_CNFMWOROBUST_AGERE,
-                                         &priv->mwo_robust);
-       else
-               err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
-                                         &priv->frag_thresh);
-       if (err) {
-               printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
-                      dev->name);
-               goto out;
-       }
-
-       /* Power management setup */
-       if (priv->has_pm) {
-               priv->pm_on = 0;
-               priv->pm_mcast = 1;
-               err = hermes_read_wordrec(hw, USER_BAP,
-                                         HERMES_RID_CNFMAXSLEEPDURATION,
-                                         &priv->pm_period);
-               if (err) {
-                       printk(KERN_ERR "%s: failed to read power management period!\n",
-                              dev->name);
-                       goto out;
-               }
-               err = hermes_read_wordrec(hw, USER_BAP,
-                                         HERMES_RID_CNFPMHOLDOVERDURATION,
-                                         &priv->pm_timeout);
-               if (err) {
-                       printk(KERN_ERR "%s: failed to read power management timeout!\n",
-                              dev->name);
-                       goto out;
-               }
-       }
-
-       /* Preamble setup */
-       if (priv->has_preamble) {
-               err = hermes_read_wordrec(hw, USER_BAP,
-                                         HERMES_RID_CNFPREAMBLE_SYMBOL,
-                                         &priv->preamble);
-               if (err)
-                       goto out;
-       }
-               
-       /* Set up the default configuration */
-       priv->iw_mode = IW_MODE_INFRA;
-       /* By default use IEEE/IBSS ad-hoc mode if we have it */
-       priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
-       set_port_type(priv);
-       priv->channel = 0; /* use firmware default */
-
-       priv->promiscuous = 0;
-       priv->encode_alg = IW_ENCODE_ALG_NONE;
-       priv->tx_key = 0;
-       priv->wpa_enabled = 0;
-       priv->tkip_cm_active = 0;
-       priv->key_mgmt = 0;
-       priv->wpa_ie_len = 0;
-       priv->wpa_ie = NULL;
-
-       /* Make the hardware available, as long as it hasn't been
-        * removed elsewhere (e.g. by PCMCIA hot unplug) */
-       spin_lock_irq(&priv->lock);
-       priv->hw_unavailable--;
-       spin_unlock_irq(&priv->lock);
-
-       printk(KERN_DEBUG "%s: ready\n", dev->name);
-
- out:
-       return err;
-}
-
-struct net_device
-*alloc_orinocodev(int sizeof_card,
-                 struct device *device,
-                 int (*hard_reset)(struct orinoco_private *),
-                 int (*stop_fw)(struct orinoco_private *, int))
-{
-       struct net_device *dev;
-       struct orinoco_private *priv;
-
-       dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
-       if (! dev)
-               return NULL;
-       priv = netdev_priv(dev);
-       priv->ndev = dev;
-       if (sizeof_card)
-               priv->card = (void *)((unsigned long)priv
-                                     + sizeof(struct orinoco_private));
-       else
-               priv->card = NULL;
-       priv->dev = device;
-
-       /* Setup / override net_device fields */
-       dev->init = orinoco_init;
-       dev->hard_start_xmit = orinoco_xmit;
-       dev->tx_timeout = orinoco_tx_timeout;
-       dev->watchdog_timeo = HZ; /* 1 second timeout */
-       dev->get_stats = orinoco_get_stats;
-       dev->ethtool_ops = &orinoco_ethtool_ops;
-       dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
-#ifdef WIRELESS_SPY
-       priv->wireless_data.spy_data = &priv->spy_data;
-       dev->wireless_data = &priv->wireless_data;
-#endif
-       dev->change_mtu = orinoco_change_mtu;
-       dev->set_multicast_list = orinoco_set_multicast_list;
-       /* we use the default eth_mac_addr for setting the MAC addr */
-
-       /* Reserve space in skb for the SNAP header */
-       dev->hard_header_len += ENCAPS_OVERHEAD;
-
-       /* Set up default callbacks */
-       dev->open = orinoco_open;
-       dev->stop = orinoco_stop;
-       priv->hard_reset = hard_reset;
-       priv->stop_fw = stop_fw;
-
-       spin_lock_init(&priv->lock);
-       priv->open = 0;
-       priv->hw_unavailable = 1; /* orinoco_init() must clear this
-                                  * before anything else touches the
-                                  * hardware */
-       INIT_WORK(&priv->reset_work, orinoco_reset);
-       INIT_WORK(&priv->join_work, orinoco_join_ap);
-       INIT_WORK(&priv->wevent_work, orinoco_send_wevents);
-
-       INIT_LIST_HEAD(&priv->rx_list);
-       tasklet_init(&priv->rx_tasklet, orinoco_rx_isr_tasklet,
-                    (unsigned long) dev);
-
-       netif_carrier_off(dev);
-       priv->last_linkstatus = 0xffff;
-
-       return dev;
-}
-
-void free_orinocodev(struct net_device *dev)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-
-       /* No need to empty priv->rx_list: if the tasklet is scheduled
-        * when we call tasklet_kill it will run one final time,
-        * emptying the list */
-       tasklet_kill(&priv->rx_tasklet);
-       priv->wpa_ie_len = 0;
-       kfree(priv->wpa_ie);
-       orinoco_mic_free(priv);
-       orinoco_bss_data_free(priv);
-       free_netdev(dev);
-}
-
-/********************************************************************/
-/* Wireless extensions                                              */
-/********************************************************************/
-
-/* Return : < 0 -> error code ; >= 0 -> length */
-static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
-                               char buf[IW_ESSID_MAX_SIZE+1])
-{
-       hermes_t *hw = &priv->hw;
-       int err = 0;
-       struct hermes_idstring essidbuf;
-       char *p = (char *)(&essidbuf.val);
-       int len;
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       if (strlen(priv->desired_essid) > 0) {
-               /* We read the desired SSID from the hardware rather
-                  than from priv->desired_essid, just in case the
-                  firmware is allowed to change it on us. I'm not
-                  sure about this */
-               /* My guess is that the OWNSSID should always be whatever
-                * we set to the card, whereas CURRENT_SSID is the one that
-                * may change... - Jean II */
-               u16 rid;
-
-               *active = 1;
-
-               rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
-                       HERMES_RID_CNFDESIREDSSID;
-               
-               err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
-                                     NULL, &essidbuf);
-               if (err)
-                       goto fail_unlock;
-       } else {
-               *active = 0;
-
-               err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
-                                     sizeof(essidbuf), NULL, &essidbuf);
-               if (err)
-                       goto fail_unlock;
-       }
-
-       len = le16_to_cpu(essidbuf.len);
-       BUG_ON(len > IW_ESSID_MAX_SIZE);
-
-       memset(buf, 0, IW_ESSID_MAX_SIZE);
-       memcpy(buf, p, len);
-       err = len;
-
- fail_unlock:
-       orinoco_unlock(priv, &flags);
-
-       return err;       
-}
-
-static long orinoco_hw_get_freq(struct orinoco_private *priv)
-{
-       
-       hermes_t *hw = &priv->hw;
-       int err = 0;
-       u16 channel;
-       long freq = 0;
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-       
-       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
-       if (err)
-               goto out;
-
-       /* Intersil firmware 1.3.5 returns 0 when the interface is down */
-       if (channel == 0) {
-               err = -EBUSY;
-               goto out;
-       }
-
-       if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
-               printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
-                      priv->ndev->name, channel);
-               err = -EBUSY;
-               goto out;
-
-       }
-       freq = channel_frequency[channel-1] * 100000;
-
- out:
-       orinoco_unlock(priv, &flags);
-
-       if (err > 0)
-               err = -EBUSY;
-       return err ? err : freq;
-}
-
-static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
-                                     int *numrates, s32 *rates, int max)
-{
-       hermes_t *hw = &priv->hw;
-       struct hermes_idstring list;
-       unsigned char *p = (unsigned char *)&list.val;
-       int err = 0;
-       int num;
-       int i;
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
-                             sizeof(list), NULL, &list);
-       orinoco_unlock(priv, &flags);
-
-       if (err)
-               return err;
-       
-       num = le16_to_cpu(list.len);
-       *numrates = num;
-       num = min(num, max);
-
-       for (i = 0; i < num; i++) {
-               rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
-       }
-
-       return 0;
-}
-
-static int orinoco_ioctl_getname(struct net_device *dev,
-                                struct iw_request_info *info,
-                                char *name,
-                                char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int numrates;
-       int err;
-
-       err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
-
-       if (!err && (numrates > 2))
-               strcpy(name, "IEEE 802.11b");
-       else
-               strcpy(name, "IEEE 802.11-DS");
-
-       return 0;
-}
-
-static int orinoco_ioctl_setwap(struct net_device *dev,
-                               struct iw_request_info *info,
-                               struct sockaddr *ap_addr,
-                               char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int err = -EINPROGRESS;         /* Call commit handler */
-       unsigned long flags;
-       static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-       static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       /* Enable automatic roaming - no sanity checks are needed */
-       if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
-           memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
-               priv->bssid_fixed = 0;
-               memset(priv->desired_bssid, 0, ETH_ALEN);
-
-               /* "off" means keep existing connection */
-               if (ap_addr->sa_data[0] == 0) {
-                       __orinoco_hw_set_wap(priv);
-                       err = 0;
-               }
-               goto out;
-       }
-
-       if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
-               printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
-                      "support manual roaming\n",
-                      dev->name);
-               err = -EOPNOTSUPP;
-               goto out;
-       }
-
-       if (priv->iw_mode != IW_MODE_INFRA) {
-               printk(KERN_WARNING "%s: Manual roaming supported only in "
-                      "managed mode\n", dev->name);
-               err = -EOPNOTSUPP;
-               goto out;
-       }
-
-       /* Intersil firmware hangs without Desired ESSID */
-       if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
-           strlen(priv->desired_essid) == 0) {
-               printk(KERN_WARNING "%s: Desired ESSID must be set for "
-                      "manual roaming\n", dev->name);
-               err = -EOPNOTSUPP;
-               goto out;
-       }
-
-       /* Finally, enable manual roaming */
-       priv->bssid_fixed = 1;
-       memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
-
- out:
-       orinoco_unlock(priv, &flags);
-       return err;
-}
-
-static int orinoco_ioctl_getwap(struct net_device *dev,
-                               struct iw_request_info *info,
-                               struct sockaddr *ap_addr,
-                               char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-
-       hermes_t *hw = &priv->hw;
-       int err = 0;
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       ap_addr->sa_family = ARPHRD_ETHER;
-       err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
-                             ETH_ALEN, NULL, ap_addr->sa_data);
-
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
-static int orinoco_ioctl_setmode(struct net_device *dev,
-                                struct iw_request_info *info,
-                                u32 *mode,
-                                char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int err = -EINPROGRESS;         /* Call commit handler */
-       unsigned long flags;
-
-       if (priv->iw_mode == *mode)
-               return 0;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       switch (*mode) {
-       case IW_MODE_ADHOC:
-               if (!priv->has_ibss && !priv->has_port3)
-                       err = -EOPNOTSUPP;
-               break;
-
-       case IW_MODE_INFRA:
-               break;
-
-       case IW_MODE_MONITOR:
-               if (priv->broken_monitor && !force_monitor) {
-                       printk(KERN_WARNING "%s: Monitor mode support is "
-                              "buggy in this firmware, not enabling\n",
-                              dev->name);
-                       err = -EOPNOTSUPP;
-               }
-               break;
-
-       default:
-               err = -EOPNOTSUPP;
-               break;
-       }
-
-       if (err == -EINPROGRESS) {
-               priv->iw_mode = *mode;
-               set_port_type(priv);
-       }
-
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
-static int orinoco_ioctl_getmode(struct net_device *dev,
-                                struct iw_request_info *info,
-                                u32 *mode,
-                                char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-
-       *mode = priv->iw_mode;
-       return 0;
-}
-
-static int orinoco_ioctl_getiwrange(struct net_device *dev,
-                                   struct iw_request_info *info,
-                                   struct iw_point *rrq,
-                                   char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int err = 0;
-       struct iw_range *range = (struct iw_range *) extra;
-       int numrates;
-       int i, k;
-
-       rrq->length = sizeof(struct iw_range);
-       memset(range, 0, sizeof(struct iw_range));
-
-       range->we_version_compiled = WIRELESS_EXT;
-       range->we_version_source = 22;
-
-       /* Set available channels/frequencies */
-       range->num_channels = NUM_CHANNELS;
-       k = 0;
-       for (i = 0; i < NUM_CHANNELS; i++) {
-               if (priv->channel_mask & (1 << i)) {
-                       range->freq[k].i = i + 1;
-                       range->freq[k].m = channel_frequency[i] * 100000;
-                       range->freq[k].e = 1;
-                       k++;
-               }
-               
-               if (k >= IW_MAX_FREQUENCIES)
-                       break;
-       }
-       range->num_frequency = k;
-       range->sensitivity = 3;
-
-       if (priv->has_wep) {
-               range->max_encoding_tokens = ORINOCO_MAX_KEYS;
-               range->encoding_size[0] = SMALL_KEY_SIZE;
-               range->num_encoding_sizes = 1;
-
-               if (priv->has_big_wep) {
-                       range->encoding_size[1] = LARGE_KEY_SIZE;
-                       range->num_encoding_sizes = 2;
-               }
-       }
-
-       if (priv->has_wpa)
-               range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
-
-       if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
-               /* Quality stats meaningless in ad-hoc mode */
-       } else {
-               range->max_qual.qual = 0x8b - 0x2f;
-               range->max_qual.level = 0x2f - 0x95 - 1;
-               range->max_qual.noise = 0x2f - 0x95 - 1;
-               /* Need to get better values */
-               range->avg_qual.qual = 0x24;
-               range->avg_qual.level = 0xC2;
-               range->avg_qual.noise = 0x9E;
-       }
-
-       err = orinoco_hw_get_bitratelist(priv, &numrates,
-                                        range->bitrate, IW_MAX_BITRATES);
-       if (err)
-               return err;
-       range->num_bitrates = numrates;
-
-       /* Set an indication of the max TCP throughput in bit/s that we can
-        * expect using this interface. May be use for QoS stuff...
-        * Jean II */
-       if (numrates > 2)
-               range->throughput = 5 * 1000 * 1000;    /* ~5 Mb/s */
-       else
-               range->throughput = 1.5 * 1000 * 1000;  /* ~1.5 Mb/s */
-
-       range->min_rts = 0;
-       range->max_rts = 2347;
-       range->min_frag = 256;
-       range->max_frag = 2346;
-
-       range->min_pmp = 0;
-       range->max_pmp = 65535000;
-       range->min_pmt = 0;
-       range->max_pmt = 65535 * 1000;  /* ??? */
-       range->pmp_flags = IW_POWER_PERIOD;
-       range->pmt_flags = IW_POWER_TIMEOUT;
-       range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
-
-       range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
-       range->retry_flags = IW_RETRY_LIMIT;
-       range->r_time_flags = IW_RETRY_LIFETIME;
-       range->min_retry = 0;
-       range->max_retry = 65535;       /* ??? */
-       range->min_r_time = 0;
-       range->max_r_time = 65535 * 1000;       /* ??? */
-
-       if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
-               range->scan_capa = IW_SCAN_CAPA_ESSID;
-       else
-               range->scan_capa = IW_SCAN_CAPA_NONE;
-
-       /* Event capability (kernel) */
-       IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
-       /* Event capability (driver) */
-       IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
-       IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
-       IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
-       IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
-
-       return 0;
-}
-
-static int orinoco_ioctl_setiwencode(struct net_device *dev,
-                                    struct iw_request_info *info,
-                                    struct iw_point *erq,
-                                    char *keybuf)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int index = (erq->flags & IW_ENCODE_INDEX) - 1;
-       int setindex = priv->tx_key;
-       int encode_alg = priv->encode_alg;
-       int restricted = priv->wep_restrict;
-       u16 xlen = 0;
-       int err = -EINPROGRESS;         /* Call commit handler */
-       unsigned long flags;
-
-       if (! priv->has_wep)
-               return -EOPNOTSUPP;
-
-       if (erq->pointer) {
-               /* We actually have a key to set - check its length */
-               if (erq->length > LARGE_KEY_SIZE)
-                       return -E2BIG;
-
-               if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep )
-                       return -E2BIG;
-       }
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       /* Clear any TKIP key we have */
-       if ((priv->has_wpa) && (priv->encode_alg == IW_ENCODE_ALG_TKIP))
-               (void) orinoco_clear_tkip_key(priv, setindex);
-
-       if (erq->length > 0) {
-               if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
-                       index = priv->tx_key;
-
-               /* Adjust key length to a supported value */
-               if (erq->length > SMALL_KEY_SIZE) {
-                       xlen = LARGE_KEY_SIZE;
-               } else if (erq->length > 0) {
-                       xlen = SMALL_KEY_SIZE;
-               } else
-                       xlen = 0;
-
-               /* Switch on WEP if off */
-               if ((encode_alg != IW_ENCODE_ALG_WEP) && (xlen > 0)) {
-                       setindex = index;
-                       encode_alg = IW_ENCODE_ALG_WEP;
-               }
-       } else {
-               /* Important note : if the user do "iwconfig eth0 enc off",
-                * we will arrive there with an index of -1. This is valid
-                * but need to be taken care off... Jean II */
-               if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
-                       if((index != -1) || (erq->flags == 0)) {
-                               err = -EINVAL;
-                               goto out;
-                       }
-               } else {
-                       /* Set the index : Check that the key is valid */
-                       if(priv->keys[index].len == 0) {
-                               err = -EINVAL;
-                               goto out;
-                       }
-                       setindex = index;
-               }
-       }
-
-       if (erq->flags & IW_ENCODE_DISABLED)
-               encode_alg = IW_ENCODE_ALG_NONE;
-       if (erq->flags & IW_ENCODE_OPEN)
-               restricted = 0;
-       if (erq->flags & IW_ENCODE_RESTRICTED)
-               restricted = 1;
-
-       if (erq->pointer && erq->length > 0) {
-               priv->keys[index].len = cpu_to_le16(xlen);
-               memset(priv->keys[index].data, 0,
-                      sizeof(priv->keys[index].data));
-               memcpy(priv->keys[index].data, keybuf, erq->length);
-       }
-       priv->tx_key = setindex;
-
-       /* Try fast key change if connected and only keys are changed */
-       if ((priv->encode_alg == encode_alg) &&
-           (priv->wep_restrict == restricted) &&
-           netif_carrier_ok(dev)) {
-               err = __orinoco_hw_setup_wepkeys(priv);
-               /* No need to commit if successful */
-               goto out;
-       }
-
-       priv->encode_alg = encode_alg;
-       priv->wep_restrict = restricted;
-
- out:
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
-static int orinoco_ioctl_getiwencode(struct net_device *dev,
-                                    struct iw_request_info *info,
-                                    struct iw_point *erq,
-                                    char *keybuf)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int index = (erq->flags & IW_ENCODE_INDEX) - 1;
-       u16 xlen = 0;
-       unsigned long flags;
-
-       if (! priv->has_wep)
-               return -EOPNOTSUPP;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
-               index = priv->tx_key;
-
-       erq->flags = 0;
-       if (!priv->encode_alg)
-               erq->flags |= IW_ENCODE_DISABLED;
-       erq->flags |= index + 1;
-
-       if (priv->wep_restrict)
-               erq->flags |= IW_ENCODE_RESTRICTED;
-       else
-               erq->flags |= IW_ENCODE_OPEN;
-
-       xlen = le16_to_cpu(priv->keys[index].len);
-
-       erq->length = xlen;
-
-       memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
-
-       orinoco_unlock(priv, &flags);
-       return 0;
-}
-
-static int orinoco_ioctl_setessid(struct net_device *dev,
-                                 struct iw_request_info *info,
-                                 struct iw_point *erq,
-                                 char *essidbuf)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       unsigned long flags;
-
-       /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
-        * anyway... - Jean II */
-
-       /* Hum... Should not use Wireless Extension constant (may change),
-        * should use our own... - Jean II */
-       if (erq->length > IW_ESSID_MAX_SIZE)
-               return -E2BIG;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       /* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
-       memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
-
-       /* If not ANY, get the new ESSID */
-       if (erq->flags) {
-               memcpy(priv->desired_essid, essidbuf, erq->length);
-       }
-
-       orinoco_unlock(priv, &flags);
-
-       return -EINPROGRESS;            /* Call commit handler */
-}
-
-static int orinoco_ioctl_getessid(struct net_device *dev,
-                                 struct iw_request_info *info,
-                                 struct iw_point *erq,
-                                 char *essidbuf)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int active;
-       int err = 0;
-       unsigned long flags;
-
-       if (netif_running(dev)) {
-               err = orinoco_hw_get_essid(priv, &active, essidbuf);
-               if (err < 0)
-                       return err;
-               erq->length = err;
-       } else {
-               if (orinoco_lock(priv, &flags) != 0)
-                       return -EBUSY;
-               memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
-               erq->length = strlen(priv->desired_essid);
-               orinoco_unlock(priv, &flags);
-       }
-
-       erq->flags = 1;
-
-       return 0;
-}
-
-static int orinoco_ioctl_setnick(struct net_device *dev,
-                                struct iw_request_info *info,
-                                struct iw_point *nrq,
-                                char *nickbuf)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       unsigned long flags;
-
-       if (nrq->length > IW_ESSID_MAX_SIZE)
-               return -E2BIG;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       memset(priv->nick, 0, sizeof(priv->nick));
-       memcpy(priv->nick, nickbuf, nrq->length);
-
-       orinoco_unlock(priv, &flags);
-
-       return -EINPROGRESS;            /* Call commit handler */
-}
-
-static int orinoco_ioctl_getnick(struct net_device *dev,
-                                struct iw_request_info *info,
-                                struct iw_point *nrq,
-                                char *nickbuf)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
-       orinoco_unlock(priv, &flags);
-
-       nrq->length = strlen(priv->nick);
-
-       return 0;
-}
-
-static int orinoco_ioctl_setfreq(struct net_device *dev,
-                                struct iw_request_info *info,
-                                struct iw_freq *frq,
-                                char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int chan = -1;
-       unsigned long flags;
-       int err = -EINPROGRESS;         /* Call commit handler */
-
-       /* In infrastructure mode the AP sets the channel */
-       if (priv->iw_mode == IW_MODE_INFRA)
-               return -EBUSY;
-
-       if ( (frq->e == 0) && (frq->m <= 1000) ) {
-               /* Setting by channel number */
-               chan = frq->m;
-       } else {
-               /* Setting by frequency - search the table */
-               int mult = 1;
-               int i;
-
-               for (i = 0; i < (6 - frq->e); i++)
-                       mult *= 10;
-
-               for (i = 0; i < NUM_CHANNELS; i++)
-                       if (frq->m == (channel_frequency[i] * mult))
-                               chan = i+1;
-       }
-
-       if ( (chan < 1) || (chan > NUM_CHANNELS) ||
-            ! (priv->channel_mask & (1 << (chan-1)) ) )
-               return -EINVAL;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       priv->channel = chan;
-       if (priv->iw_mode == IW_MODE_MONITOR) {
-               /* Fast channel change - no commit if successful */
-               hermes_t *hw = &priv->hw;
-               err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
-                                           HERMES_TEST_SET_CHANNEL,
-                                       chan, NULL);
-       }
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
-static int orinoco_ioctl_getfreq(struct net_device *dev,
-                                struct iw_request_info *info,
-                                struct iw_freq *frq,
-                                char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int tmp;
-
-       /* Locking done in there */
-       tmp = orinoco_hw_get_freq(priv);
-       if (tmp < 0) {
-               return tmp;
-       }
-
-       frq->m = tmp;
-       frq->e = 1;
-
-       return 0;
-}
-
-static int orinoco_ioctl_getsens(struct net_device *dev,
-                                struct iw_request_info *info,
-                                struct iw_param *srq,
-                                char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       u16 val;
-       int err;
-       unsigned long flags;
-
-       if (!priv->has_sensitivity)
-               return -EOPNOTSUPP;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-       err = hermes_read_wordrec(hw, USER_BAP,
-                                 HERMES_RID_CNFSYSTEMSCALE, &val);
-       orinoco_unlock(priv, &flags);
-
-       if (err)
-               return err;
-
-       srq->value = val;
-       srq->fixed = 0; /* auto */
-
-       return 0;
-}
-
-static int orinoco_ioctl_setsens(struct net_device *dev,
-                                struct iw_request_info *info,
-                                struct iw_param *srq,
-                                char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int val = srq->value;
-       unsigned long flags;
-
-       if (!priv->has_sensitivity)
-               return -EOPNOTSUPP;
-
-       if ((val < 1) || (val > 3))
-               return -EINVAL;
-       
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-       priv->ap_density = val;
-       orinoco_unlock(priv, &flags);
-
-       return -EINPROGRESS;            /* Call commit handler */
-}
-
-static int orinoco_ioctl_setrts(struct net_device *dev,
-                               struct iw_request_info *info,
-                               struct iw_param *rrq,
-                               char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int val = rrq->value;
-       unsigned long flags;
-
-       if (rrq->disabled)
-               val = 2347;
-
-       if ( (val < 0) || (val > 2347) )
-               return -EINVAL;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       priv->rts_thresh = val;
-       orinoco_unlock(priv, &flags);
-
-       return -EINPROGRESS;            /* Call commit handler */
-}
-
-static int orinoco_ioctl_getrts(struct net_device *dev,
-                               struct iw_request_info *info,
-                               struct iw_param *rrq,
-                               char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-
-       rrq->value = priv->rts_thresh;
-       rrq->disabled = (rrq->value == 2347);
-       rrq->fixed = 1;
-
-       return 0;
-}
-
-static int orinoco_ioctl_setfrag(struct net_device *dev,
-                                struct iw_request_info *info,
-                                struct iw_param *frq,
-                                char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int err = -EINPROGRESS;         /* Call commit handler */
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       if (priv->has_mwo) {
-               if (frq->disabled)
-                       priv->mwo_robust = 0;
-               else {
-                       if (frq->fixed)
-                               printk(KERN_WARNING "%s: Fixed fragmentation is "
-                                      "not supported on this firmware. "
-                                      "Using MWO robust instead.\n", dev->name);
-                       priv->mwo_robust = 1;
-               }
-       } else {
-               if (frq->disabled)
-                       priv->frag_thresh = 2346;
-               else {
-                       if ( (frq->value < 256) || (frq->value > 2346) )
-                               err = -EINVAL;
-                       else
-                               priv->frag_thresh = frq->value & ~0x1; /* must be even */
-               }
-       }
-
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
-static int orinoco_ioctl_getfrag(struct net_device *dev,
-                                struct iw_request_info *info,
-                                struct iw_param *frq,
-                                char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       int err;
-       u16 val;
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-       
-       if (priv->has_mwo) {
-               err = hermes_read_wordrec(hw, USER_BAP,
-                                         HERMES_RID_CNFMWOROBUST_AGERE,
-                                         &val);
-               if (err)
-                       val = 0;
-
-               frq->value = val ? 2347 : 0;
-               frq->disabled = ! val;
-               frq->fixed = 0;
-       } else {
-               err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
-                                         &val);
-               if (err)
-                       val = 0;
-
-               frq->value = val;
-               frq->disabled = (val >= 2346);
-               frq->fixed = 1;
-       }
-
-       orinoco_unlock(priv, &flags);
-       
-       return err;
-}
-
-static int orinoco_ioctl_setrate(struct net_device *dev,
-                                struct iw_request_info *info,
-                                struct iw_param *rrq,
-                                char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int ratemode = -1;
-       int bitrate; /* 100s of kilobits */
-       int i;
-       unsigned long flags;
-       
-       /* As the user space doesn't know our highest rate, it uses -1
-        * to ask us to set the highest rate.  Test it using "iwconfig
-        * ethX rate auto" - Jean II */
-       if (rrq->value == -1)
-               bitrate = 110;
-       else {
-               if (rrq->value % 100000)
-                       return -EINVAL;
-               bitrate = rrq->value / 100000;
-       }
-
-       if ( (bitrate != 10) && (bitrate != 20) &&
-            (bitrate != 55) && (bitrate != 110) )
-               return -EINVAL;
-
-       for (i = 0; i < BITRATE_TABLE_SIZE; i++)
-               if ( (bitrate_table[i].bitrate == bitrate) &&
-                    (bitrate_table[i].automatic == ! rrq->fixed) ) {
-                       ratemode = i;
-                       break;
-               }
-       
-       if (ratemode == -1)
-               return -EINVAL;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-       priv->bitratemode = ratemode;
-       orinoco_unlock(priv, &flags);
-
-       return -EINPROGRESS;
-}
-
-static int orinoco_ioctl_getrate(struct net_device *dev,
-                                struct iw_request_info *info,
-                                struct iw_param *rrq,
-                                char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       int err = 0;
-       int ratemode;
-       int i;
-       u16 val;
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       ratemode = priv->bitratemode;
-
-       BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
-
-       rrq->value = bitrate_table[ratemode].bitrate * 100000;
-       rrq->fixed = ! bitrate_table[ratemode].automatic;
-       rrq->disabled = 0;
-
-       /* If the interface is running we try to find more about the
-          current mode */
-       if (netif_running(dev)) {
-               err = hermes_read_wordrec(hw, USER_BAP,
-                                         HERMES_RID_CURRENTTXRATE, &val);
-               if (err)
-                       goto out;
-               
-               switch (priv->firmware_type) {
-               case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
-                       /* Note : in Lucent firmware, the return value of
-                        * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
-                        * and therefore is totally different from the
-                        * encoding of HERMES_RID_CNFTXRATECONTROL.
-                        * Don't forget that 6Mb/s is really 5.5Mb/s */
-                       if (val == 6)
-                               rrq->value = 5500000;
-                       else
-                               rrq->value = val * 1000000;
-                       break;
-               case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
-               case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
-                       for (i = 0; i < BITRATE_TABLE_SIZE; i++)
-                               if (bitrate_table[i].intersil_txratectrl == val) {
-                                       ratemode = i;
-                                       break;
-                               }
-                       if (i >= BITRATE_TABLE_SIZE)
-                               printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
-                                      dev->name, val);
-
-                       rrq->value = bitrate_table[ratemode].bitrate * 100000;
-                       break;
-               default:
-                       BUG();
-               }
-       }
-
- out:
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
-static int orinoco_ioctl_setpower(struct net_device *dev,
-                                 struct iw_request_info *info,
-                                 struct iw_param *prq,
-                                 char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int err = -EINPROGRESS;         /* Call commit handler */
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       if (prq->disabled) {
-               priv->pm_on = 0;
-       } else {
-               switch (prq->flags & IW_POWER_MODE) {
-               case IW_POWER_UNICAST_R:
-                       priv->pm_mcast = 0;
-                       priv->pm_on = 1;
-                       break;
-               case IW_POWER_ALL_R:
-                       priv->pm_mcast = 1;
-                       priv->pm_on = 1;
-                       break;
-               case IW_POWER_ON:
-                       /* No flags : but we may have a value - Jean II */
-                       break;
-               default:
-                       err = -EINVAL;
-                       goto out;
-               }
-               
-               if (prq->flags & IW_POWER_TIMEOUT) {
-                       priv->pm_on = 1;
-                       priv->pm_timeout = prq->value / 1000;
-               }
-               if (prq->flags & IW_POWER_PERIOD) {
-                       priv->pm_on = 1;
-                       priv->pm_period = prq->value / 1000;
-               }
-               /* It's valid to not have a value if we are just toggling
-                * the flags... Jean II */
-               if(!priv->pm_on) {
-                       err = -EINVAL;
-                       goto out;
-               }                       
-       }
-
- out:
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
-static int orinoco_ioctl_getpower(struct net_device *dev,
-                                 struct iw_request_info *info,
-                                 struct iw_param *prq,
-                                 char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       int err = 0;
-       u16 enable, period, timeout, mcast;
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-       
-       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
-       if (err)
-               goto out;
-
-       err = hermes_read_wordrec(hw, USER_BAP,
-                                 HERMES_RID_CNFMAXSLEEPDURATION, &period);
-       if (err)
-               goto out;
-
-       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
-       if (err)
-               goto out;
-
-       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
-       if (err)
-               goto out;
-
-       prq->disabled = !enable;
-       /* Note : by default, display the period */
-       if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
-               prq->flags = IW_POWER_TIMEOUT;
-               prq->value = timeout * 1000;
-       } else {
-               prq->flags = IW_POWER_PERIOD;
-               prq->value = period * 1000;
-       }
-       if (mcast)
-               prq->flags |= IW_POWER_ALL_R;
-       else
-               prq->flags |= IW_POWER_UNICAST_R;
-
- out:
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
-static int orinoco_ioctl_set_encodeext(struct net_device *dev,
-                                      struct iw_request_info *info,
-                                      union iwreq_data *wrqu,
-                                      char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct iw_point *encoding = &wrqu->encoding;
-       struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-       int idx, alg = ext->alg, set_key = 1;
-       unsigned long flags;
-       int err = -EINVAL;
-       u16 key_len;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       /* Determine and validate the key index */
-       idx = encoding->flags & IW_ENCODE_INDEX;
-       if (idx) {
-               if ((idx < 1) || (idx > WEP_KEYS))
-                       goto out;
-               idx--;
-       } else
-               idx = priv->tx_key;
-
-       if (encoding->flags & IW_ENCODE_DISABLED)
-           alg = IW_ENCODE_ALG_NONE;
-
-       if (priv->has_wpa && (alg != IW_ENCODE_ALG_TKIP)) {
-               /* Clear any TKIP TX key we had */
-               (void) orinoco_clear_tkip_key(priv, priv->tx_key);
-       }
-
-       if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
-               priv->tx_key = idx;
-               set_key = ((alg == IW_ENCODE_ALG_TKIP) ||
-                          (ext->key_len > 0)) ? 1 : 0;
-       }
-
-       if (set_key) {
-               /* Set the requested key first */
-               switch (alg) {
-               case IW_ENCODE_ALG_NONE:
-                       priv->encode_alg = alg;
-                       priv->keys[idx].len = 0;
-                       break;
-
-               case IW_ENCODE_ALG_WEP:
-                       if (ext->key_len > SMALL_KEY_SIZE)
-                               key_len = LARGE_KEY_SIZE;
-                       else if (ext->key_len > 0)
-                               key_len = SMALL_KEY_SIZE;
-                       else
-                               goto out;
-
-                       priv->encode_alg = alg;
-                       priv->keys[idx].len = cpu_to_le16(key_len);
-
-                       key_len = min(ext->key_len, key_len);
-
-                       memset(priv->keys[idx].data, 0, ORINOCO_MAX_KEY_SIZE);
-                       memcpy(priv->keys[idx].data, ext->key, key_len);
-                       break;
-
-               case IW_ENCODE_ALG_TKIP:
-               {
-                       hermes_t *hw = &priv->hw;
-                       u8 *tkip_iv = NULL;
-
-                       if (!priv->has_wpa ||
-                           (ext->key_len > sizeof(priv->tkip_key[0])))
-                               goto out;
-
-                       priv->encode_alg = alg;
-                       memset(&priv->tkip_key[idx], 0,
-                              sizeof(priv->tkip_key[idx]));
-                       memcpy(&priv->tkip_key[idx], ext->key, ext->key_len);
-
-                       if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
-                               tkip_iv = &ext->rx_seq[0];
-
-                       err = __orinoco_hw_set_tkip_key(hw, idx,
-                                ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
-                                (u8 *) &priv->tkip_key[idx],
-                                tkip_iv, NULL);
-                       if (err)
-                               printk(KERN_ERR "%s: Error %d setting TKIP key"
-                                      "\n", dev->name, err);
-
-                       goto out;
-               }
-               default:
-                       goto out;
-               }
-       }
-       err = -EINPROGRESS;
- out:
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
-static int orinoco_ioctl_get_encodeext(struct net_device *dev,
-                                      struct iw_request_info *info,
-                                      union iwreq_data *wrqu,
-                                      char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct iw_point *encoding = &wrqu->encoding;
-       struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-       int idx, max_key_len;
-       unsigned long flags;
-       int err;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       err = -EINVAL;
-       max_key_len = encoding->length - sizeof(*ext);
-       if (max_key_len < 0)
-               goto out;
-
-       idx = encoding->flags & IW_ENCODE_INDEX;
-       if (idx) {
-               if ((idx < 1) || (idx > WEP_KEYS))
-                       goto out;
-               idx--;
-       } else
-               idx = priv->tx_key;
-
-       encoding->flags = idx + 1;
-       memset(ext, 0, sizeof(*ext));
-
-       ext->alg = priv->encode_alg;
-       switch (priv->encode_alg) {
-       case IW_ENCODE_ALG_NONE:
-               ext->key_len = 0;
-               encoding->flags |= IW_ENCODE_DISABLED;
-               break;
-       case IW_ENCODE_ALG_WEP:
-               ext->key_len = min_t(u16, le16_to_cpu(priv->keys[idx].len),
-                                    max_key_len);
-               memcpy(ext->key, priv->keys[idx].data, ext->key_len);
-               encoding->flags |= IW_ENCODE_ENABLED;
-               break;
-       case IW_ENCODE_ALG_TKIP:
-               ext->key_len = min_t(u16, sizeof(struct orinoco_tkip_key),
-                                    max_key_len);
-               memcpy(ext->key, &priv->tkip_key[idx], ext->key_len);
-               encoding->flags |= IW_ENCODE_ENABLED;
-               break;
-       }
-
-       err = 0;
- out:
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
-static int orinoco_ioctl_set_auth(struct net_device *dev,
-                                 struct iw_request_info *info,
-                                 union iwreq_data *wrqu, char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       struct iw_param *param = &wrqu->param;
-       unsigned long flags;
-       int ret = -EINPROGRESS;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       switch (param->flags & IW_AUTH_INDEX) {
-       case IW_AUTH_WPA_VERSION:
-       case IW_AUTH_CIPHER_PAIRWISE:
-       case IW_AUTH_CIPHER_GROUP:
-       case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-       case IW_AUTH_PRIVACY_INVOKED:
-       case IW_AUTH_DROP_UNENCRYPTED:
-               /*
-                * orinoco does not use these parameters
-                */
-               break;
-
-       case IW_AUTH_KEY_MGMT:
-               /* wl_lkm implies value 2 == PSK for Hermes I
-                * which ties in with WEXT
-                * no other hints tho :(
-                */
-               priv->key_mgmt = param->value;
-               break;
-
-       case IW_AUTH_TKIP_COUNTERMEASURES:
-               /* When countermeasures are enabled, shut down the
-                * card; when disabled, re-enable the card. This must
-                * take effect immediately.
-                *
-                * TODO: Make sure that the EAPOL message is getting
-                *       out before card disabled
-                */
-               if (param->value) {
-                       priv->tkip_cm_active = 1;
-                       ret = hermes_enable_port(hw, 0);
-               } else {
-                       priv->tkip_cm_active = 0;
-                       ret = hermes_disable_port(hw, 0);
-               }
-               break;
-
-       case IW_AUTH_80211_AUTH_ALG:
-               if (param->value & IW_AUTH_ALG_SHARED_KEY)
-                       priv->wep_restrict = 1;
-               else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
-                       priv->wep_restrict = 0;
-               else
-                       ret = -EINVAL;
-               break;
-
-       case IW_AUTH_WPA_ENABLED:
-               if (priv->has_wpa) {
-                       priv->wpa_enabled = param->value ? 1 : 0;
-               } else {
-                       if (param->value)
-                               ret = -EOPNOTSUPP;
-                       /* else silently accept disable of WPA */
-                       priv->wpa_enabled = 0;
-               }
-               break;
-
-       default:
-               ret = -EOPNOTSUPP;
-       }
-
-       orinoco_unlock(priv, &flags);
-       return ret;
-}
-
-static int orinoco_ioctl_get_auth(struct net_device *dev,
-                                 struct iw_request_info *info,
-                                 union iwreq_data *wrqu, char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct iw_param *param = &wrqu->param;
-       unsigned long flags;
-       int ret = 0;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       switch (param->flags & IW_AUTH_INDEX) {
-       case IW_AUTH_KEY_MGMT:
-               param->value = priv->key_mgmt;
-               break;
-
-       case IW_AUTH_TKIP_COUNTERMEASURES:
-               param->value = priv->tkip_cm_active;
-               break;
-
-       case IW_AUTH_80211_AUTH_ALG:
-               if (priv->wep_restrict)
-                       param->value = IW_AUTH_ALG_SHARED_KEY;
-               else
-                       param->value = IW_AUTH_ALG_OPEN_SYSTEM;
-               break;
-
-       case IW_AUTH_WPA_ENABLED:
-               param->value = priv->wpa_enabled;
-               break;
-
-       default:
-               ret = -EOPNOTSUPP;
-       }
-
-       orinoco_unlock(priv, &flags);
-       return ret;
-}
-
-static int orinoco_ioctl_set_genie(struct net_device *dev,
-                                  struct iw_request_info *info,
-                                  union iwreq_data *wrqu, char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       u8 *buf;
-       unsigned long flags;
-       int err = 0;
-
-       if ((wrqu->data.length > MAX_WPA_IE_LEN) ||
-           (wrqu->data.length && (extra == NULL)))
-               return -EINVAL;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       if (wrqu->data.length) {
-               buf = kmalloc(wrqu->data.length, GFP_KERNEL);
-               if (buf == NULL) {
-                       err = -ENOMEM;
-                       goto out;
-               }
-
-               memcpy(buf, extra, wrqu->data.length);
-               kfree(priv->wpa_ie);
-               priv->wpa_ie = buf;
-               priv->wpa_ie_len = wrqu->data.length;
-       } else {
-               kfree(priv->wpa_ie);
-               priv->wpa_ie = NULL;
-               priv->wpa_ie_len = 0;
-       }
-
-       if (priv->wpa_ie) {
-               /* Looks like wl_lkm wants to check the auth alg, and
-                * somehow pass it to the firmware.
-                * Instead it just calls the key mgmt rid
-                *   - we do this in set auth.
-                */
-       }
-
-out:
-       orinoco_unlock(priv, &flags);
-       return err;
-}
-
-static int orinoco_ioctl_get_genie(struct net_device *dev,
-                                  struct iw_request_info *info,
-                                  union iwreq_data *wrqu, char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       unsigned long flags;
-       int err = 0;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       if ((priv->wpa_ie_len == 0) || (priv->wpa_ie == NULL)) {
-               wrqu->data.length = 0;
-               goto out;
-       }
-
-       if (wrqu->data.length < priv->wpa_ie_len) {
-               err = -E2BIG;
-               goto out;
-       }
-
-       wrqu->data.length = priv->wpa_ie_len;
-       memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
-
-out:
-       orinoco_unlock(priv, &flags);
-       return err;
-}
-
-static int orinoco_ioctl_set_mlme(struct net_device *dev,
-                                 struct iw_request_info *info,
-                                 union iwreq_data *wrqu, char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       struct iw_mlme *mlme = (struct iw_mlme *)extra;
-       unsigned long flags;
-       int ret = 0;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       switch (mlme->cmd) {
-       case IW_MLME_DEAUTH:
-               /* silently ignore */
-               break;
-
-       case IW_MLME_DISASSOC:
-       {
-               struct {
-                       u8 addr[ETH_ALEN];
-                       __le16 reason_code;
-               } __attribute__ ((packed)) buf;
-
-               memcpy(buf.addr, mlme->addr.sa_data, ETH_ALEN);
-               buf.reason_code = cpu_to_le16(mlme->reason_code);
-               ret = HERMES_WRITE_RECORD(hw, USER_BAP,
-                                         HERMES_RID_CNFDISASSOCIATE,
-                                         &buf);
-               break;
-       }
-       default:
-               ret = -EOPNOTSUPP;
-       }
-
-       orinoco_unlock(priv, &flags);
-       return ret;
-}
-
-static int orinoco_ioctl_getretry(struct net_device *dev,
-                                 struct iw_request_info *info,
-                                 struct iw_param *rrq,
-                                 char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       int err = 0;
-       u16 short_limit, long_limit, lifetime;
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-       
-       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
-                                 &short_limit);
-       if (err)
-               goto out;
-
-       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
-                                 &long_limit);
-       if (err)
-               goto out;
-
-       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
-                                 &lifetime);
-       if (err)
-               goto out;
-
-       rrq->disabled = 0;              /* Can't be disabled */
-
-       /* Note : by default, display the retry number */
-       if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
-               rrq->flags = IW_RETRY_LIFETIME;
-               rrq->value = lifetime * 1000;   /* ??? */
-       } else {
-               /* By default, display the min number */
-               if ((rrq->flags & IW_RETRY_LONG)) {
-                       rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
-                       rrq->value = long_limit;
-               } else {
-                       rrq->flags = IW_RETRY_LIMIT;
-                       rrq->value = short_limit;
-                       if(short_limit != long_limit)
-                               rrq->flags |= IW_RETRY_SHORT;
-               }
-       }
-
- out:
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
-static int orinoco_ioctl_reset(struct net_device *dev,
-                              struct iw_request_info *info,
-                              void *wrqu,
-                              char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-
-       if (! capable(CAP_NET_ADMIN))
-               return -EPERM;
-
-       if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
-               printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
-
-               /* Firmware reset */
-               orinoco_reset(&priv->reset_work);
-       } else {
-               printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
-
-               schedule_work(&priv->reset_work);
-       }
-
-       return 0;
-}
-
-static int orinoco_ioctl_setibssport(struct net_device *dev,
-                                    struct iw_request_info *info,
-                                    void *wrqu,
-                                    char *extra)
-
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int val = *( (int *) extra );
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       priv->ibss_port = val ;
-
-       /* Actually update the mode we are using */
-       set_port_type(priv);
-
-       orinoco_unlock(priv, &flags);
-       return -EINPROGRESS;            /* Call commit handler */
-}
-
-static int orinoco_ioctl_getibssport(struct net_device *dev,
-                                    struct iw_request_info *info,
-                                    void *wrqu,
-                                    char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int *val = (int *) extra;
-
-       *val = priv->ibss_port;
-       return 0;
-}
-
-static int orinoco_ioctl_setport3(struct net_device *dev,
-                                 struct iw_request_info *info,
-                                 void *wrqu,
-                                 char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int val = *( (int *) extra );
-       int err = 0;
-       unsigned long flags;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       switch (val) {
-       case 0: /* Try to do IEEE ad-hoc mode */
-               if (! priv->has_ibss) {
-                       err = -EINVAL;
-                       break;
-               }
-               priv->prefer_port3 = 0;
-                       
-               break;
-
-       case 1: /* Try to do Lucent proprietary ad-hoc mode */
-               if (! priv->has_port3) {
-                       err = -EINVAL;
-                       break;
-               }
-               priv->prefer_port3 = 1;
-               break;
-
-       default:
-               err = -EINVAL;
-       }
-
-       if (! err) {
-               /* Actually update the mode we are using */
-               set_port_type(priv);
-               err = -EINPROGRESS;
-       }
-
-       orinoco_unlock(priv, &flags);
-
-       return err;
-}
-
-static int orinoco_ioctl_getport3(struct net_device *dev,
-                                 struct iw_request_info *info,
-                                 void *wrqu,
-                                 char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int *val = (int *) extra;
-
-       *val = priv->prefer_port3;
-       return 0;
-}
-
-static int orinoco_ioctl_setpreamble(struct net_device *dev,
-                                    struct iw_request_info *info,
-                                    void *wrqu,
-                                    char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       unsigned long flags;
-       int val;
-
-       if (! priv->has_preamble)
-               return -EOPNOTSUPP;
-
-       /* 802.11b has recently defined some short preamble.
-        * Basically, the Phy header has been reduced in size.
-        * This increase performance, especially at high rates
-        * (the preamble is transmitted at 1Mb/s), unfortunately
-        * this give compatibility troubles... - Jean II */
-       val = *( (int *) extra );
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       if (val)
-               priv->preamble = 1;
-       else
-               priv->preamble = 0;
-
-       orinoco_unlock(priv, &flags);
-
-       return -EINPROGRESS;            /* Call commit handler */
-}
-
-static int orinoco_ioctl_getpreamble(struct net_device *dev,
-                                    struct iw_request_info *info,
-                                    void *wrqu,
-                                    char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int *val = (int *) extra;
-
-       if (! priv->has_preamble)
-               return -EOPNOTSUPP;
-
-       *val = priv->preamble;
-       return 0;
-}
-
-/* ioctl interface to hermes_read_ltv()
- * To use with iwpriv, pass the RID as the token argument, e.g.
- * iwpriv get_rid [0xfc00]
- * At least Wireless Tools 25 is required to use iwpriv.
- * For Wireless Tools 25 and 26 append "dummy" are the end. */
-static int orinoco_ioctl_getrid(struct net_device *dev,
-                               struct iw_request_info *info,
-                               struct iw_point *data,
-                               char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       int rid = data->flags;
-       u16 length;
-       int err;
-       unsigned long flags;
-
-       /* It's a "get" function, but we don't want users to access the
-        * WEP key and other raw firmware data */
-       if (! capable(CAP_NET_ADMIN))
-               return -EPERM;
-
-       if (rid < 0xfc00 || rid > 0xffff)
-               return -EINVAL;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
-                             extra);
-       if (err)
-               goto out;
-
-       data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
-                            MAX_RID_LEN);
-
- out:
-       orinoco_unlock(priv, &flags);
-       return err;
-}
-
-/* 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_point *srq,
-                                char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       hermes_t *hw = &priv->hw;
-       struct iw_scan_req *si = (struct iw_scan_req *) extra;
-       int err = 0;
-       unsigned long flags;
-
-       /* Note : you may have realised that, as this is a SET operation,
-        * this is privileged and therefore a normal user can't
-        * perform scanning.
-        * This is not an error, while the device perform scanning,
-        * traffic doesn't flow, so it's a perfect DoS...
-        * Jean II */
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       /* Scanning with port 0 disabled would fail */
-       if (!netif_running(dev)) {
-               err = -ENETDOWN;
-               goto out;
-       }
-
-       /* In monitor mode, the scan results are always empty.
-        * Probe responses are passed to the driver as received
-        * frames and could be processed in software. */
-       if (priv->iw_mode == IW_MODE_MONITOR) {
-               err = -EOPNOTSUPP;
-               goto out;
-       }
-
-       /* Note : because we don't lock out the irq handler, the way
-        * we access scan variables in priv is critical.
-        *      o scan_inprogress : not touched by irq handler
-        *      o scan_mode : not touched by irq handler
-        * Before modifying anything on those variables, please think hard !
-        * Jean II */
-
-       /* Save flags */
-       priv->scan_mode = srq->flags;
-
-       /* Always trigger scanning, even if it's in progress.
-        * This way, if the info frame get lost, we will recover somewhat
-        * gracefully  - Jean II */
-
-       if (priv->has_hostscan) {
-               switch (priv->firmware_type) {
-               case FIRMWARE_TYPE_SYMBOL:
-                       err = hermes_write_wordrec(hw, USER_BAP,
-                                                  HERMES_RID_CNFHOSTSCAN_SYMBOL,
-                                                  HERMES_HOSTSCAN_SYMBOL_ONCE |
-                                                  HERMES_HOSTSCAN_SYMBOL_BCAST);
-                       break;
-               case FIRMWARE_TYPE_INTERSIL: {
-                       __le16 req[3];
-
-                       req[0] = cpu_to_le16(0x3fff);   /* All channels */
-                       req[1] = cpu_to_le16(0x0001);   /* rate 1 Mbps */
-                       req[2] = 0;                     /* Any ESSID */
-                       err = HERMES_WRITE_RECORD(hw, USER_BAP,
-                                                 HERMES_RID_CNFHOSTSCAN, &req);
-               }
-               break;
-               case FIRMWARE_TYPE_AGERE:
-                       if (priv->scan_mode & IW_SCAN_THIS_ESSID) {
-                               struct hermes_idstring idbuf;
-                               size_t len = min(sizeof(idbuf.val),
-                                                (size_t) si->essid_len);
-                               idbuf.len = cpu_to_le16(len);
-                               memcpy(idbuf.val, si->essid, len);
-
-                               err = hermes_write_ltv(hw, USER_BAP,
-                                              HERMES_RID_CNFSCANSSID_AGERE,
-                                              HERMES_BYTES_TO_RECLEN(len + 2),
-                                              &idbuf);
-                       } else
-                               err = hermes_write_wordrec(hw, USER_BAP,
-                                                  HERMES_RID_CNFSCANSSID_AGERE,
-                                                  0);  /* Any ESSID */
-                       if (err)
-                               break;
-
-                       if (priv->has_ext_scan) {
-                               /* Clear scan results at the start of
-                                * an extended scan */
-                               orinoco_clear_scan_results(priv,
-                                               msecs_to_jiffies(15000));
-
-                               /* TODO: Is this available on older firmware?
-                                *   Can we use it to scan specific channels
-                                *   for IW_SCAN_THIS_FREQ? */
-                               err = hermes_write_wordrec(hw, USER_BAP,
-                                               HERMES_RID_CNFSCANCHANNELS2GHZ,
-                                               0x7FFF);
-                               if (err)
-                                       goto out;
-
-                               err = hermes_inquire(hw,
-                                                    HERMES_INQ_CHANNELINFO);
-                       } else
-                               err = hermes_inquire(hw, HERMES_INQ_SCAN);
-                       break;
-               }
-       } else
-               err = hermes_inquire(hw, HERMES_INQ_SCAN);
-
-       /* One more client */
-       if (! err)
-               priv->scan_inprogress = 1;
-
- out:
-       orinoco_unlock(priv, &flags);
-       return err;
-}
-
-#define MAX_CUSTOM_LEN 64
-
-/* Translate scan data returned from the card to a card independant
- * format that the Wireless Tools will understand - Jean II */
-static inline char *orinoco_translate_scan(struct net_device *dev,
-                                          struct iw_request_info *info,
-                                          char *current_ev,
-                                          char *end_buf,
-                                          union hermes_scan_info *bss,
-                                          unsigned int last_scanned)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       u16                     capabilities;
-       u16                     channel;
-       struct iw_event         iwe;            /* Temporary buffer */
-       char custom[MAX_CUSTOM_LEN];
-
-       memset(&iwe, 0, sizeof(iwe));
-
-       /* First entry *MUST* be the AP MAC address */
-       iwe.cmd = SIOCGIWAP;
-       iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-       memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
-       current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-                                         &iwe, IW_EV_ADDR_LEN);
-
-       /* Other entries will be displayed in the order we give them */
-
-       /* Add the ESSID */
-       iwe.u.data.length = le16_to_cpu(bss->a.essid_len);
-       if (iwe.u.data.length > 32)
-               iwe.u.data.length = 32;
-       iwe.cmd = SIOCGIWESSID;
-       iwe.u.data.flags = 1;
-       current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-                                         &iwe, bss->a.essid);
-
-       /* Add mode */
-       iwe.cmd = SIOCGIWMODE;
-       capabilities = le16_to_cpu(bss->a.capabilities);
-       if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
-               if (capabilities & WLAN_CAPABILITY_ESS)
-                       iwe.u.mode = IW_MODE_MASTER;
-               else
-                       iwe.u.mode = IW_MODE_ADHOC;
-               current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-                                                 &iwe, IW_EV_UINT_LEN);
-       }
-
-       channel = bss->s.channel;
-       if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
-               /* Add channel and frequency */
-               iwe.cmd = SIOCGIWFREQ;
-               iwe.u.freq.m = channel;
-               iwe.u.freq.e = 0;
-               current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-                                                 &iwe, IW_EV_FREQ_LEN);
-
-               iwe.u.freq.m = channel_frequency[channel-1] * 100000;
-               iwe.u.freq.e = 1;
-               current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-                                                 &iwe, IW_EV_FREQ_LEN);
-       }
-
-       /* Add quality statistics. level and noise in dB. No link quality */
-       iwe.cmd = IWEVQUAL;
-       iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
-       iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95;
-       iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95;
-       /* Wireless tools prior to 27.pre22 will show link quality
-        * anyway, so we provide a reasonable value. */
-       if (iwe.u.qual.level > iwe.u.qual.noise)
-               iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
-       else
-               iwe.u.qual.qual = 0;
-       current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-                                         &iwe, IW_EV_QUAL_LEN);
-
-       /* Add encryption capability */
-       iwe.cmd = SIOCGIWENCODE;
-       if (capabilities & WLAN_CAPABILITY_PRIVACY)
-               iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-       else
-               iwe.u.data.flags = IW_ENCODE_DISABLED;
-       iwe.u.data.length = 0;
-       current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-                                         &iwe, NULL);
-
-       /* Bit rate is not available in Lucent/Agere firmwares */
-       if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
-               char *current_val = current_ev + iwe_stream_lcp_len(info);
-               int i;
-               int step;
-
-               if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
-                       step = 2;
-               else
-                       step = 1;
-
-               iwe.cmd = SIOCGIWRATE;
-               /* Those two flags are ignored... */
-               iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-               /* Max 10 values */
-               for (i = 0; i < 10; i += step) {
-                       /* NULL terminated */
-                       if (bss->p.rates[i] == 0x0)
-                               break;
-                       /* Bit rate given in 500 kb/s units (+ 0x80) */
-                       iwe.u.bitrate.value =
-                               ((bss->p.rates[i] & 0x7f) * 500000);
-                       current_val = iwe_stream_add_value(info, current_ev,
-                                                          current_val,
-                                                          end_buf, &iwe,
-                                                          IW_EV_PARAM_LEN);
-               }
-               /* Check if we added any event */
-               if ((current_val - current_ev) > iwe_stream_lcp_len(info))
-                       current_ev = current_val;
-       }
-
-       /* Beacon interval */
-       iwe.cmd = IWEVCUSTOM;
-       iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-                                    "bcn_int=%d",
-                                    le16_to_cpu(bss->a.beacon_interv));
-       if (iwe.u.data.length)
-               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-                                                 &iwe, custom);
-
-       /* Capabilites */
-       iwe.cmd = IWEVCUSTOM;
-       iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-                                    "capab=0x%04x",
-                                    capabilities);
-       if (iwe.u.data.length)
-               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-                                                 &iwe, custom);
-
-       /* Add EXTRA: Age to display seconds since last beacon/probe response
-        * for given network. */
-       iwe.cmd = IWEVCUSTOM;
-       iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-                                    " Last beacon: %dms ago",
-                                    jiffies_to_msecs(jiffies - last_scanned));
-       if (iwe.u.data.length)
-               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-                                                 &iwe, custom);
-
-       return current_ev;
-}
-
-static inline char *orinoco_translate_ext_scan(struct net_device *dev,
-                                              struct iw_request_info *info,
-                                              char *current_ev,
-                                              char *end_buf,
-                                              struct agere_ext_scan_info *bss,
-                                              unsigned int last_scanned)
-{
-       u16                     capabilities;
-       u16                     channel;
-       struct iw_event         iwe;            /* Temporary buffer */
-       char custom[MAX_CUSTOM_LEN];
-       u8 *ie;
-
-       memset(&iwe, 0, sizeof(iwe));
-
-       /* First entry *MUST* be the AP MAC address */
-       iwe.cmd = SIOCGIWAP;
-       iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-       memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
-       current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-                                         &iwe, IW_EV_ADDR_LEN);
-
-       /* Other entries will be displayed in the order we give them */
-
-       /* Add the ESSID */
-       ie = bss->data;
-       iwe.u.data.length = ie[1];
-       if (iwe.u.data.length) {
-               if (iwe.u.data.length > 32)
-                       iwe.u.data.length = 32;
-               iwe.cmd = SIOCGIWESSID;
-               iwe.u.data.flags = 1;
-               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-                                                 &iwe, &ie[2]);
-       }
-
-       /* Add mode */
-       capabilities = le16_to_cpu(bss->capabilities);
-       if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
-               iwe.cmd = SIOCGIWMODE;
-               if (capabilities & WLAN_CAPABILITY_ESS)
-                       iwe.u.mode = IW_MODE_MASTER;
-               else
-                       iwe.u.mode = IW_MODE_ADHOC;
-               current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-                                                 &iwe, IW_EV_UINT_LEN);
-       }
-
-       ie = orinoco_get_ie(bss->data, sizeof(bss->data), MFIE_TYPE_DS_SET);
-       channel = ie ? ie[2] : 0;
-       if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
-               /* Add channel and frequency */
-               iwe.cmd = SIOCGIWFREQ;
-               iwe.u.freq.m = channel;
-               iwe.u.freq.e = 0;
-               current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-                                                 &iwe, IW_EV_FREQ_LEN);
-
-               iwe.u.freq.m = channel_frequency[channel-1] * 100000;
-               iwe.u.freq.e = 1;
-               current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-                                                 &iwe, IW_EV_FREQ_LEN);
-       }
-
-       /* Add quality statistics. level and noise in dB. No link quality */
-       iwe.cmd = IWEVQUAL;
-       iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
-       iwe.u.qual.level = bss->level - 0x95;
-       iwe.u.qual.noise = bss->noise - 0x95;
-       /* Wireless tools prior to 27.pre22 will show link quality
-        * anyway, so we provide a reasonable value. */
-       if (iwe.u.qual.level > iwe.u.qual.noise)
-               iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
-       else
-               iwe.u.qual.qual = 0;
-       current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-                                         &iwe, IW_EV_QUAL_LEN);
-
-       /* Add encryption capability */
-       iwe.cmd = SIOCGIWENCODE;
-       if (capabilities & WLAN_CAPABILITY_PRIVACY)
-               iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-       else
-               iwe.u.data.flags = IW_ENCODE_DISABLED;
-       iwe.u.data.length = 0;
-       current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-                                         &iwe, NULL);
-
-       /* WPA IE */
-       ie = orinoco_get_wpa_ie(bss->data, sizeof(bss->data));
-       if (ie) {
-               iwe.cmd = IWEVGENIE;
-               iwe.u.data.length = ie[1] + 2;
-               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-                                                 &iwe, ie);
-       }
-
-       /* RSN IE */
-       ie = orinoco_get_ie(bss->data, sizeof(bss->data), MFIE_TYPE_RSN);
-       if (ie) {
-               iwe.cmd = IWEVGENIE;
-               iwe.u.data.length = ie[1] + 2;
-               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-                                                 &iwe, ie);
-       }
-
-       ie = orinoco_get_ie(bss->data, sizeof(bss->data), MFIE_TYPE_RATES);
-       if (ie) {
-               char *p = current_ev + iwe_stream_lcp_len(info);
-               int i;
-
-               iwe.cmd = SIOCGIWRATE;
-               /* Those two flags are ignored... */
-               iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-
-               for (i = 2; i < (ie[1] + 2); i++) {
-                       iwe.u.bitrate.value = ((ie[i] & 0x7F) * 500000);
-                       p = iwe_stream_add_value(info, current_ev, p, end_buf,
-                                                &iwe, IW_EV_PARAM_LEN);
-               }
-               /* Check if we added any event */
-               if (p > (current_ev + iwe_stream_lcp_len(info)))
-                       current_ev = p;
-       }
-
-       /* Timestamp */
-       iwe.cmd = IWEVCUSTOM;
-       iwe.u.data.length =
-               snprintf(custom, MAX_CUSTOM_LEN, "tsf=%016llx",
-                        (unsigned long long) le64_to_cpu(bss->timestamp));
-       if (iwe.u.data.length)
-               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-                                                 &iwe, custom);
-
-       /* Beacon interval */
-       iwe.cmd = IWEVCUSTOM;
-       iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-                                    "bcn_int=%d",
-                                    le16_to_cpu(bss->beacon_interval));
-       if (iwe.u.data.length)
-               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-                                                 &iwe, custom);
-
-       /* Capabilites */
-       iwe.cmd = IWEVCUSTOM;
-       iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-                                    "capab=0x%04x",
-                                    capabilities);
-       if (iwe.u.data.length)
-               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-                                                 &iwe, custom);
-
-       /* Add EXTRA: Age to display seconds since last beacon/probe response
-        * for given network. */
-       iwe.cmd = IWEVCUSTOM;
-       iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-                                    " Last beacon: %dms ago",
-                                    jiffies_to_msecs(jiffies - last_scanned));
-       if (iwe.u.data.length)
-               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-                                                 &iwe, custom);
-
-       return current_ev;
-}
-
-/* Return results of a scan */
-static int orinoco_ioctl_getscan(struct net_device *dev,
-                                struct iw_request_info *info,
-                                struct iw_point *srq,
-                                char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       int err = 0;
-       unsigned long flags;
-       char *current_ev = extra;
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return -EBUSY;
-
-       if (priv->scan_inprogress) {
-               /* Important note : we don't want to block the caller
-                * until results are ready for various reasons.
-                * First, managing wait queues is complex and racy.
-                * Second, we grab some rtnetlink lock before comming
-                * here (in dev_ioctl()).
-                * Third, we generate an Wireless Event, so the
-                * caller can wait itself on that - Jean II */
-               err = -EAGAIN;
-               goto out;
-       }
-
-       if (priv->has_ext_scan) {
-               struct xbss_element *bss;
-
-               list_for_each_entry(bss, &priv->bss_list, list) {
-                       /* Translate this entry to WE format */
-                       current_ev =
-                               orinoco_translate_ext_scan(dev, info,
-                                                          current_ev,
-                                                          extra + srq->length,
-                                                          &bss->bss,
-                                                          bss->last_scanned);
-
-                       /* Check if there is space for one more entry */
-                       if ((extra + srq->length - current_ev)
-                           <= IW_EV_ADDR_LEN) {
-                               /* Ask user space to try again with a
-                                * bigger buffer */
-                               err = -E2BIG;
-                               goto out;
-                       }
-               }
-
-       } else {
-               struct bss_element *bss;
-
-               list_for_each_entry(bss, &priv->bss_list, list) {
-                       /* Translate this entry to WE format */
-                       current_ev = orinoco_translate_scan(dev, info,
-                                                           current_ev,
-                                                           extra + srq->length,
-                                                           &bss->bss,
-                                                           bss->last_scanned);
-
-                       /* Check if there is space for one more entry */
-                       if ((extra + srq->length - current_ev)
-                           <= IW_EV_ADDR_LEN) {
-                               /* Ask user space to try again with a
-                                * bigger buffer */
-                               err = -E2BIG;
-                               goto out;
-                       }
-               }
-       }
-
-       srq->length = (current_ev - extra);
-       srq->flags = (__u16) priv->scan_mode;
-
-out:
-       orinoco_unlock(priv, &flags);
-       return err;
-}
-
-/* Commit handler, called after set operations */
-static int orinoco_ioctl_commit(struct net_device *dev,
-                               struct iw_request_info *info,
-                               void *wrqu,
-                               char *extra)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct hermes *hw = &priv->hw;
-       unsigned long flags;
-       int err = 0;
-
-       if (!priv->open)
-               return 0;
-
-       if (priv->broken_disableport) {
-               orinoco_reset(&priv->reset_work);
-               return 0;
-       }
-
-       if (orinoco_lock(priv, &flags) != 0)
-               return err;
-
-       err = hermes_disable_port(hw, 0);
-       if (err) {
-               printk(KERN_WARNING "%s: Unable to disable port "
-                      "while reconfiguring card\n", dev->name);
-               priv->broken_disableport = 1;
-               goto out;
-       }
-
-       err = __orinoco_program_rids(dev);
-       if (err) {
-               printk(KERN_WARNING "%s: Unable to reconfigure card\n",
-                      dev->name);
-               goto out;
-       }
-
-       err = hermes_enable_port(hw, 0);
-       if (err) {
-               printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
-                      dev->name);
-               goto out;
-       }
-
- out:
-       if (err) {
-               printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
-               schedule_work(&priv->reset_work);
-               err = 0;
-       }
-
-       orinoco_unlock(priv, &flags);
-       return err;
-}
-
-static const struct iw_priv_args orinoco_privtab[] = {
-       { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
-       { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
-       { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-         0, "set_port3" },
-       { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-         "get_port3" },
-       { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-         0, "set_preamble" },
-       { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-         "get_preamble" },
-       { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-         0, "set_ibssport" },
-       { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-         "get_ibssport" },
-       { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
-         "get_rid" },
-};
-
-
-/*
- * Structures to export the Wireless Handlers
- */
-
-#define STD_IW_HANDLER(id, func) \
-       [IW_IOCTL_IDX(id)] = (iw_handler) func
-static const iw_handler        orinoco_handler[] = {
-       STD_IW_HANDLER(SIOCSIWCOMMIT,   orinoco_ioctl_commit),
-       STD_IW_HANDLER(SIOCGIWNAME,     orinoco_ioctl_getname),
-       STD_IW_HANDLER(SIOCSIWFREQ,     orinoco_ioctl_setfreq),
-       STD_IW_HANDLER(SIOCGIWFREQ,     orinoco_ioctl_getfreq),
-       STD_IW_HANDLER(SIOCSIWMODE,     orinoco_ioctl_setmode),
-       STD_IW_HANDLER(SIOCGIWMODE,     orinoco_ioctl_getmode),
-       STD_IW_HANDLER(SIOCSIWSENS,     orinoco_ioctl_setsens),
-       STD_IW_HANDLER(SIOCGIWSENS,     orinoco_ioctl_getsens),
-       STD_IW_HANDLER(SIOCGIWRANGE,    orinoco_ioctl_getiwrange),
-       STD_IW_HANDLER(SIOCSIWSPY,      iw_handler_set_spy),
-       STD_IW_HANDLER(SIOCGIWSPY,      iw_handler_get_spy),
-       STD_IW_HANDLER(SIOCSIWTHRSPY,   iw_handler_set_thrspy),
-       STD_IW_HANDLER(SIOCGIWTHRSPY,   iw_handler_get_thrspy),
-       STD_IW_HANDLER(SIOCSIWAP,       orinoco_ioctl_setwap),
-       STD_IW_HANDLER(SIOCGIWAP,       orinoco_ioctl_getwap),
-       STD_IW_HANDLER(SIOCSIWSCAN,     orinoco_ioctl_setscan),
-       STD_IW_HANDLER(SIOCGIWSCAN,     orinoco_ioctl_getscan),
-       STD_IW_HANDLER(SIOCSIWESSID,    orinoco_ioctl_setessid),
-       STD_IW_HANDLER(SIOCGIWESSID,    orinoco_ioctl_getessid),
-       STD_IW_HANDLER(SIOCSIWNICKN,    orinoco_ioctl_setnick),
-       STD_IW_HANDLER(SIOCGIWNICKN,    orinoco_ioctl_getnick),
-       STD_IW_HANDLER(SIOCSIWRATE,     orinoco_ioctl_setrate),
-       STD_IW_HANDLER(SIOCGIWRATE,     orinoco_ioctl_getrate),
-       STD_IW_HANDLER(SIOCSIWRTS,      orinoco_ioctl_setrts),
-       STD_IW_HANDLER(SIOCGIWRTS,      orinoco_ioctl_getrts),
-       STD_IW_HANDLER(SIOCSIWFRAG,     orinoco_ioctl_setfrag),
-       STD_IW_HANDLER(SIOCGIWFRAG,     orinoco_ioctl_getfrag),
-       STD_IW_HANDLER(SIOCGIWRETRY,    orinoco_ioctl_getretry),
-       STD_IW_HANDLER(SIOCSIWENCODE,   orinoco_ioctl_setiwencode),
-       STD_IW_HANDLER(SIOCGIWENCODE,   orinoco_ioctl_getiwencode),
-       STD_IW_HANDLER(SIOCSIWPOWER,    orinoco_ioctl_setpower),
-       STD_IW_HANDLER(SIOCGIWPOWER,    orinoco_ioctl_getpower),
-       STD_IW_HANDLER(SIOCSIWGENIE,    orinoco_ioctl_set_genie),
-       STD_IW_HANDLER(SIOCGIWGENIE,    orinoco_ioctl_get_genie),
-       STD_IW_HANDLER(SIOCSIWMLME,     orinoco_ioctl_set_mlme),
-       STD_IW_HANDLER(SIOCSIWAUTH,     orinoco_ioctl_set_auth),
-       STD_IW_HANDLER(SIOCGIWAUTH,     orinoco_ioctl_get_auth),
-       STD_IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext),
-       STD_IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext),
-};
-
-
-/*
-  Added typecasting since we no longer use iwreq_data -- Moustafa
- */
-static const iw_handler        orinoco_private_handler[] = {
-       [0] = (iw_handler) orinoco_ioctl_reset,
-       [1] = (iw_handler) orinoco_ioctl_reset,
-       [2] = (iw_handler) orinoco_ioctl_setport3,
-       [3] = (iw_handler) orinoco_ioctl_getport3,
-       [4] = (iw_handler) orinoco_ioctl_setpreamble,
-       [5] = (iw_handler) orinoco_ioctl_getpreamble,
-       [6] = (iw_handler) orinoco_ioctl_setibssport,
-       [7] = (iw_handler) orinoco_ioctl_getibssport,
-       [9] = (iw_handler) orinoco_ioctl_getrid,
-};
-
-static const struct iw_handler_def orinoco_handler_def = {
-       .num_standard = ARRAY_SIZE(orinoco_handler),
-       .num_private = ARRAY_SIZE(orinoco_private_handler),
-       .num_private_args = ARRAY_SIZE(orinoco_privtab),
-       .standard = orinoco_handler,
-       .private = orinoco_private_handler,
-       .private_args = orinoco_privtab,
-       .get_wireless_stats = orinoco_get_wireless_stats,
-};
-
-static void orinoco_get_drvinfo(struct net_device *dev,
-                               struct ethtool_drvinfo *info)
-{
-       struct orinoco_private *priv = netdev_priv(dev);
-
-       strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
-       strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
-       strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
-       if (dev->dev.parent)
-               strncpy(info->bus_info, dev->dev.parent->bus_id,
-                       sizeof(info->bus_info) - 1);
-       else
-               snprintf(info->bus_info, sizeof(info->bus_info) - 1,
-                        "PCMCIA %p", priv->hw.iobase);
-}
-
-static const struct ethtool_ops orinoco_ethtool_ops = {
-       .get_drvinfo = orinoco_get_drvinfo,
-       .get_link = ethtool_op_get_link,
-};
-
-/********************************************************************/
-/* Module initialization                                            */
-/********************************************************************/
-
-EXPORT_SYMBOL(alloc_orinocodev);
-EXPORT_SYMBOL(free_orinocodev);
-
-EXPORT_SYMBOL(__orinoco_up);
-EXPORT_SYMBOL(__orinoco_down);
-EXPORT_SYMBOL(orinoco_reinit_firmware);
-
-EXPORT_SYMBOL(orinoco_interrupt);
-
-/* Can't be declared "const" or the whole __initdata section will
- * become const */
-static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
-       " (David Gibson <hermes@gibson.dropbear.id.au>, "
-       "Pavel Roskin <proski@gnu.org>, et al)";
-
-static int __init init_orinoco(void)
-{
-       printk(KERN_DEBUG "%s\n", version);
-       return 0;
-}
-
-static void __exit exit_orinoco(void)
-{
-}
-
-module_init(init_orinoco);
-module_exit(exit_orinoco);
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
deleted file mode 100644 (file)
index 981570b..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/* orinoco.h
- * 
- * Common definitions to all pieces of the various orinoco
- * drivers
- */
-
-#ifndef _ORINOCO_H
-#define _ORINOCO_H
-
-#define DRIVER_VERSION "0.15"
-
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include <linux/wireless.h>
-#include <net/iw_handler.h>
-
-#include "hermes.h"
-
-/* To enable debug messages */
-//#define ORINOCO_DEBUG                3
-
-#define WIRELESS_SPY           // enable iwspy support
-
-#define MAX_SCAN_LEN           4096
-
-#define ORINOCO_MAX_KEY_SIZE   14
-#define ORINOCO_MAX_KEYS       4
-
-struct orinoco_key {
-       __le16 len;     /* always stored as little-endian */
-       char data[ORINOCO_MAX_KEY_SIZE];
-} __attribute__ ((packed));
-
-#define TKIP_KEYLEN    16
-#define MIC_KEYLEN     8
-
-struct orinoco_tkip_key {
-       u8 tkip[TKIP_KEYLEN];
-       u8 tx_mic[MIC_KEYLEN];
-       u8 rx_mic[MIC_KEYLEN];
-};
-
-typedef enum {
-       FIRMWARE_TYPE_AGERE,
-       FIRMWARE_TYPE_INTERSIL,
-       FIRMWARE_TYPE_SYMBOL
-} fwtype_t;
-
-struct bss_element {
-       union hermes_scan_info bss;
-       unsigned long last_scanned;
-       struct list_head list;
-};
-
-struct xbss_element {
-       struct agere_ext_scan_info bss;
-       unsigned long last_scanned;
-       struct list_head list;
-};
-
-struct hermes_rx_descriptor;
-
-struct orinoco_rx_data {
-       struct hermes_rx_descriptor *desc;
-       struct sk_buff *skb;
-       struct list_head list;
-};
-
-struct orinoco_private {
-       void *card;     /* Pointer to card dependent structure */
-       struct device *dev;
-       int (*hard_reset)(struct orinoco_private *);
-       int (*stop_fw)(struct orinoco_private *, int);
-
-       /* Synchronisation stuff */
-       spinlock_t lock;
-       int hw_unavailable;
-       struct work_struct reset_work;
-
-       /* Interrupt tasklets */
-       struct tasklet_struct rx_tasklet;
-       struct list_head rx_list;
-       struct orinoco_rx_data *rx_data;
-
-       /* driver state */
-       int open;
-       u16 last_linkstatus;
-       struct work_struct join_work;
-       struct work_struct wevent_work;
-
-       /* Net device stuff */
-       struct net_device *ndev;
-       struct net_device_stats stats;
-       struct iw_statistics wstats;
-
-       /* Hardware control variables */
-       hermes_t hw;
-       u16 txfid;
-
-       /* Capabilities of the hardware/firmware */
-       fwtype_t firmware_type;
-       char fw_name[32];
-       int ibss_port;
-       int nicbuf_size;
-       u16 channel_mask;
-
-       /* Boolean capabilities */
-       unsigned int has_ibss:1;
-       unsigned int has_port3:1;
-       unsigned int has_wep:1;
-       unsigned int has_big_wep:1;
-       unsigned int has_mwo:1;
-       unsigned int has_pm:1;
-       unsigned int has_preamble:1;
-       unsigned int has_sensitivity:1;
-       unsigned int has_hostscan:1;
-       unsigned int has_alt_txcntl:1;
-       unsigned int has_ext_scan:1;
-       unsigned int has_wpa:1;
-       unsigned int do_fw_download:1;
-       unsigned int broken_disableport:1;
-       unsigned int broken_monitor:1;
-
-       /* Configuration paramaters */
-       u32 iw_mode;
-       int prefer_port3;
-       u16 encode_alg, wep_restrict, tx_key;
-       struct orinoco_key keys[ORINOCO_MAX_KEYS];
-       int bitratemode;
-       char nick[IW_ESSID_MAX_SIZE+1];
-       char desired_essid[IW_ESSID_MAX_SIZE+1];
-       char desired_bssid[ETH_ALEN];
-       int bssid_fixed;
-       u16 frag_thresh, mwo_robust;
-       u16 channel;
-       u16 ap_density, rts_thresh;
-       u16 pm_on, pm_mcast, pm_period, pm_timeout;
-       u16 preamble;
-#ifdef WIRELESS_SPY
-       struct iw_spy_data spy_data; /* iwspy support */
-       struct iw_public_data   wireless_data;
-#endif
-
-       /* Configuration dependent variables */
-       int port_type, createibss;
-       int promiscuous, mc_count;
-
-       /* Scanning support */
-       struct list_head bss_list;
-       struct list_head bss_free_list;
-       void *bss_xbss_data;
-
-       int     scan_inprogress;        /* Scan pending... */
-       u32     scan_mode;              /* Type of scan done */
-
-       /* WPA support */
-       u8 *wpa_ie;
-       int wpa_ie_len;
-
-       struct orinoco_tkip_key tkip_key[ORINOCO_MAX_KEYS];
-       struct crypto_hash *rx_tfm_mic;
-       struct crypto_hash *tx_tfm_mic;
-
-       unsigned int wpa_enabled:1;
-       unsigned int tkip_cm_active:1;
-       unsigned int key_mgmt:3;
-};
-
-#ifdef ORINOCO_DEBUG
-extern int orinoco_debug;
-#define DEBUG(n, args...) do { if (orinoco_debug>(n)) printk(KERN_DEBUG args); } while(0)
-#else
-#define DEBUG(n, args...) do { } while (0)
-#endif /* ORINOCO_DEBUG */
-
-/********************************************************************/
-/* Exported prototypes                                              */
-/********************************************************************/
-
-extern struct net_device *alloc_orinocodev(
-       int sizeof_card, struct device *device,
-       int (*hard_reset)(struct orinoco_private *),
-       int (*stop_fw)(struct orinoco_private *, int));
-extern void free_orinocodev(struct net_device *dev);
-extern int __orinoco_up(struct net_device *dev);
-extern int __orinoco_down(struct net_device *dev);
-extern int orinoco_reinit_firmware(struct net_device *dev);
-extern irqreturn_t orinoco_interrupt(int irq, void * dev_id);
-
-/********************************************************************/
-/* Locking and synchronization functions                            */
-/********************************************************************/
-
-static inline int orinoco_lock(struct orinoco_private *priv,
-                              unsigned long *flags)
-{
-       spin_lock_irqsave(&priv->lock, *flags);
-       if (priv->hw_unavailable) {
-               DEBUG(1, "orinoco_lock() called with hw_unavailable (dev=%p)\n",
-                      priv->ndev);
-               spin_unlock_irqrestore(&priv->lock, *flags);
-               return -EBUSY;
-       }
-       return 0;
-}
-
-static inline void orinoco_unlock(struct orinoco_private *priv,
-                                 unsigned long *flags)
-{
-       spin_unlock_irqrestore(&priv->lock, *flags);
-}
-
-#endif /* _ORINOCO_H */
diff --git a/drivers/net/wireless/orinoco/Makefile b/drivers/net/wireless/orinoco/Makefile
new file mode 100644 (file)
index 0000000..791366e
--- /dev/null
@@ -0,0 +1,12 @@
+#
+# Makefile for the orinoco wireless device drivers.
+#
+
+obj-$(CONFIG_HERMES)           += orinoco.o hermes.o hermes_dld.o
+obj-$(CONFIG_PCMCIA_HERMES)    += orinoco_cs.o
+obj-$(CONFIG_APPLE_AIRPORT)    += airport.o
+obj-$(CONFIG_PLX_HERMES)       += orinoco_plx.o
+obj-$(CONFIG_PCI_HERMES)       += orinoco_pci.o
+obj-$(CONFIG_TMD_HERMES)       += orinoco_tmd.o
+obj-$(CONFIG_NORTEL_HERMES)    += orinoco_nortel.o
+obj-$(CONFIG_PCMCIA_SPECTRUM)  += spectrum_cs.o
diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c
new file mode 100644 (file)
index 0000000..ce03a2e
--- /dev/null
@@ -0,0 +1,286 @@
+/* airport.c
+ *
+ * A driver for "Hermes" chipset based Apple Airport wireless
+ * card.
+ *
+ * Copyright notice & release notes in file orinoco.c
+ * 
+ * Note specific to airport stub:
+ * 
+ *  0.05 : first version of the new split driver
+ *  0.06 : fix possible hang on powerup, add sleep support
+ */
+
+#define DRIVER_NAME "airport"
+#define PFX DRIVER_NAME ": "
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/pmac_feature.h>
+
+#include "orinoco.h"
+
+#define AIRPORT_IO_LEN (0x1000)        /* one page */
+
+struct airport {
+       struct macio_dev *mdev;
+       void __iomem *vaddr;
+       int irq_requested;
+       int ndev_registered;
+};
+
+static int
+airport_suspend(struct macio_dev *mdev, pm_message_t state)
+{
+       struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
+       struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
+       int err;
+
+       printk(KERN_DEBUG "%s: Airport entering sleep mode\n", dev->name);
+
+       err = orinoco_lock(priv, &flags);
+       if (err) {
+               printk(KERN_ERR "%s: hw_unavailable on PBOOK_SLEEP_NOW\n",
+                      dev->name);
+               return 0;
+       }
+
+       err = __orinoco_down(dev);
+       if (err)
+               printk(KERN_WARNING "%s: PBOOK_SLEEP_NOW: Error %d downing interface\n",
+                      dev->name, err);
+
+       netif_device_detach(dev);
+
+       priv->hw_unavailable++;
+
+       orinoco_unlock(priv, &flags);
+
+       disable_irq(dev->irq);
+       pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 0);
+
+       return 0;
+}
+
+static int
+airport_resume(struct macio_dev *mdev)
+{
+       struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
+       struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
+       int err;
+
+       printk(KERN_DEBUG "%s: Airport waking up\n", dev->name);
+
+       pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1);
+       msleep(200);
+
+       enable_irq(dev->irq);
+
+       err = orinoco_reinit_firmware(dev);
+       if (err) {
+               printk(KERN_ERR "%s: Error %d re-initializing firmware on PBOOK_WAKE\n",
+                      dev->name, err);
+               return 0;
+       }
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       netif_device_attach(dev);
+
+       priv->hw_unavailable--;
+
+       if (priv->open && (! priv->hw_unavailable)) {
+               err = __orinoco_up(dev);
+               if (err)
+                       printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n",
+                              dev->name, err);
+       }
+
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return 0;
+}
+
+static int
+airport_detach(struct macio_dev *mdev)
+{
+       struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct airport *card = priv->card;
+
+       if (card->ndev_registered)
+               unregister_netdev(dev);
+       card->ndev_registered = 0;
+
+       if (card->irq_requested)
+               free_irq(dev->irq, dev);
+       card->irq_requested = 0;
+
+       if (card->vaddr)
+               iounmap(card->vaddr);
+       card->vaddr = NULL;
+
+       macio_release_resource(mdev, 0);
+
+       pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 0);
+       ssleep(1);
+
+       macio_set_drvdata(mdev, NULL);
+       free_orinocodev(dev);
+
+       return 0;
+}
+
+static int airport_hard_reset(struct orinoco_private *priv)
+{
+       /* It would be nice to power cycle the Airport for a real hard
+        * reset, but for some reason although it appears to
+        * re-initialize properly, it falls in a screaming heap
+        * shortly afterwards. */
+#if 0
+       struct net_device *dev = priv->ndev;
+       struct airport *card = priv->card;
+
+       /* Vitally important.  If we don't do this it seems we get an
+        * interrupt somewhere during the power cycle, since
+        * hw_unavailable is already set it doesn't get ACKed, we get
+        * into an interrupt loop and the PMU decides to turn us
+        * off. */
+       disable_irq(dev->irq);
+
+       pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(card->mdev), 0, 0);
+       ssleep(1);
+       pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(card->mdev), 0, 1);
+       ssleep(1);
+
+       enable_irq(dev->irq);
+       ssleep(1);
+#endif
+
+       return 0;
+}
+
+static int
+airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
+{
+       struct orinoco_private *priv;
+       struct net_device *dev;
+       struct airport *card;
+       unsigned long phys_addr;
+       hermes_t *hw;
+
+       if (macio_resource_count(mdev) < 1 || macio_irq_count(mdev) < 1) {
+               printk(KERN_ERR PFX "Wrong interrupt/addresses in OF tree\n");
+               return -ENODEV;
+       }
+
+       /* Allocate space for private device-specific data */
+       dev = alloc_orinocodev(sizeof(*card), &mdev->ofdev.dev,
+                              airport_hard_reset, NULL);
+       if (! dev) {
+               printk(KERN_ERR PFX "Cannot allocate network device\n");
+               return -ENODEV;
+       }
+       priv = netdev_priv(dev);
+       card = priv->card;
+
+       hw = &priv->hw;
+       card->mdev = mdev;
+
+       if (macio_request_resource(mdev, 0, "airport")) {
+               printk(KERN_ERR PFX "can't request IO resource !\n");
+               free_orinocodev(dev);
+               return -EBUSY;
+       }
+
+       SET_NETDEV_DEV(dev, &mdev->ofdev.dev);
+
+       macio_set_drvdata(mdev, dev);
+
+       /* Setup interrupts & base address */
+       dev->irq = macio_irq(mdev, 0);
+       phys_addr = macio_resource_start(mdev, 0);  /* Physical address */
+       printk(KERN_DEBUG PFX "Physical address %lx\n", phys_addr);
+       dev->base_addr = phys_addr;
+       card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
+       if (!card->vaddr) {
+               printk(KERN_ERR PFX "ioremap() failed\n");
+               goto failed;
+       }
+
+       hermes_struct_init(hw, card->vaddr, HERMES_16BIT_REGSPACING);
+               
+       /* Power up card */
+       pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1);
+       ssleep(1);
+
+       /* Reset it before we get the interrupt */
+       hermes_init(hw);
+
+       if (request_irq(dev->irq, orinoco_interrupt, 0, dev->name, dev)) {
+               printk(KERN_ERR PFX "Couldn't get IRQ %d\n", dev->irq);
+               goto failed;
+       }
+       card->irq_requested = 1;
+
+       /* Tell the stack we exist */
+       if (register_netdev(dev) != 0) {
+               printk(KERN_ERR PFX "register_netdev() failed\n");
+               goto failed;
+       }
+       printk(KERN_DEBUG PFX "Card registered for interface %s\n", dev->name);
+       card->ndev_registered = 1;
+       return 0;
+ failed:
+       airport_detach(mdev);
+       return -ENODEV;
+}                              /* airport_attach */
+
+
+static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
+       " (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
+MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
+MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
+MODULE_LICENSE("Dual MPL/GPL");
+
+static struct of_device_id airport_match[] = 
+{
+       {
+       .name           = "radio",
+       },
+       {},
+};
+
+MODULE_DEVICE_TABLE (of, airport_match);
+
+static struct macio_driver airport_driver = 
+{
+       .name           = DRIVER_NAME,
+       .match_table    = airport_match,
+       .probe          = airport_attach,
+       .remove         = airport_detach,
+       .suspend        = airport_suspend,
+       .resume         = airport_resume,
+};
+
+static int __init
+init_airport(void)
+{
+       printk(KERN_DEBUG "%s\n", version);
+
+       return macio_register_driver(&airport_driver);
+}
+
+static void __exit
+exit_airport(void)
+{
+       return macio_unregister_driver(&airport_driver);
+}
+
+module_init(init_airport);
+module_exit(exit_airport);
diff --git a/drivers/net/wireless/orinoco/hermes.c b/drivers/net/wireless/orinoco/hermes.c
new file mode 100644 (file)
index 0000000..bfa3753
--- /dev/null
@@ -0,0 +1,544 @@
+/* hermes.c
+ *
+ * Driver core for the "Hermes" wireless MAC controller, as used in
+ * the Lucent Orinoco and Cabletron RoamAbout cards. It should also
+ * work on the hfa3841 and hfa3842 MAC controller chips used in the
+ * Prism II chipsets.
+ *
+ * This is not a complete driver, just low-level access routines for
+ * the MAC controller itself.
+ *
+ * Based on the prism2 driver from Absolute Value Systems' linux-wlan
+ * project, the Linux wvlan_cs driver, Lucent's HCF-Light
+ * (wvlan_hcf.c) library, and the NetBSD wireless driver (in no
+ * particular order).
+ *
+ * Copyright (C) 2000, David Gibson, Linuxcare Australia.
+ * (C) Copyright David Gibson, IBM Corp. 2001-2003.
+ * 
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include "hermes.h"
+
+MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller");
+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>"
+       " & David Gibson <hermes@gibson.dropbear.id.au>");
+MODULE_LICENSE("Dual MPL/GPL");
+
+/* These are maximum timeouts. Most often, card wil react much faster */
+#define CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */
+#define CMD_INIT_TIMEOUT (50000) /* in iterations of ~10us */
+#define CMD_COMPL_TIMEOUT (20000) /* in iterations of ~10us */
+#define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */
+
+/*
+ * Debugging helpers
+ */
+
+#define DMSG(stuff...) do {printk(KERN_DEBUG "hermes @ %p: " , hw->iobase); \
+                       printk(stuff);} while (0)
+
+#undef HERMES_DEBUG
+#ifdef HERMES_DEBUG
+#include <stdarg.h>
+
+#define DEBUG(lvl, stuff...) if ( (lvl) <= HERMES_DEBUG) DMSG(stuff)
+
+#else /* ! HERMES_DEBUG */
+
+#define DEBUG(lvl, stuff...) do { } while (0)
+
+#endif /* ! HERMES_DEBUG */
+
+
+/*
+ * Internal functions
+ */
+
+/* Issue a command to the chip. Waiting for it to complete is the caller's
+   problem.
+
+   Returns -EBUSY if the command register is busy, 0 on success.
+
+   Callable from any context.
+*/
+static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0,
+                           u16 param1, u16 param2)
+{
+       int k = CMD_BUSY_TIMEOUT;
+       u16 reg;
+
+       /* First wait for the command register to unbusy */
+       reg = hermes_read_regn(hw, CMD);
+       while ( (reg & HERMES_CMD_BUSY) && k ) {
+               k--;
+               udelay(1);
+               reg = hermes_read_regn(hw, CMD);
+       }
+       if (reg & HERMES_CMD_BUSY) {
+               return -EBUSY;
+       }
+
+       hermes_write_regn(hw, PARAM2, param2);
+       hermes_write_regn(hw, PARAM1, param1);
+       hermes_write_regn(hw, PARAM0, param0);
+       hermes_write_regn(hw, CMD, cmd);
+       
+       return 0;
+}
+
+/*
+ * Function definitions
+ */
+
+/* For doing cmds that wipe the magic constant in SWSUPPORT0 */
+int hermes_doicmd_wait(hermes_t *hw, u16 cmd,
+                      u16 parm0, u16 parm1, u16 parm2,
+                      struct hermes_response *resp)
+{
+       int err = 0;
+       int k;
+       u16 status, reg;
+
+       err = hermes_issue_cmd(hw, cmd, parm0, parm1, parm2);
+       if (err)
+               return err;
+
+       reg = hermes_read_regn(hw, EVSTAT);
+       k = CMD_INIT_TIMEOUT;
+       while ((!(reg & HERMES_EV_CMD)) && k) {
+               k--;
+               udelay(10);
+               reg = hermes_read_regn(hw, EVSTAT);
+       }
+
+       hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC);
+
+       if (!hermes_present(hw)) {
+               DEBUG(0, "hermes @ 0x%x: Card removed during reset.\n",
+                      hw->iobase);
+               err = -ENODEV;
+               goto out;
+       }
+
+       if (!(reg & HERMES_EV_CMD)) {
+               printk(KERN_ERR "hermes @ %p: "
+                      "Timeout waiting for card to reset (reg=0x%04x)!\n",
+                      hw->iobase, reg);
+               err = -ETIMEDOUT;
+               goto out;
+       }
+
+       status = hermes_read_regn(hw, STATUS);
+       if (resp) {
+               resp->status = status;
+               resp->resp0 = hermes_read_regn(hw, RESP0);
+               resp->resp1 = hermes_read_regn(hw, RESP1);
+               resp->resp2 = hermes_read_regn(hw, RESP2);
+       }
+
+       hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
+
+       if (status & HERMES_STATUS_RESULT)
+               err = -EIO;
+out:
+       return err;
+}
+EXPORT_SYMBOL(hermes_doicmd_wait);
+
+void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing)
+{
+       hw->iobase = address;
+       hw->reg_spacing = reg_spacing;
+       hw->inten = 0x0;
+}
+EXPORT_SYMBOL(hermes_struct_init);
+
+int hermes_init(hermes_t *hw)
+{
+       u16 reg;
+       int err = 0;
+       int k;
+
+       /* We don't want to be interrupted while resetting the chipset */
+       hw->inten = 0x0;
+       hermes_write_regn(hw, INTEN, 0);
+       hermes_write_regn(hw, EVACK, 0xffff);
+
+       /* Normally it's a "can't happen" for the command register to
+           be busy when we go to issue a command because we are
+           serializing all commands.  However we want to have some
+           chance of resetting the card even if it gets into a stupid
+           state, so we actually wait to see if the command register
+           will unbusy itself here. */
+       k = CMD_BUSY_TIMEOUT;
+       reg = hermes_read_regn(hw, CMD);
+       while (k && (reg & HERMES_CMD_BUSY)) {
+               if (reg == 0xffff) /* Special case - the card has probably been removed,
+                                     so don't wait for the timeout */
+                       return -ENODEV;
+
+               k--;
+               udelay(1);
+               reg = hermes_read_regn(hw, CMD);
+       }
+       
+       /* No need to explicitly handle the timeout - if we've timed
+          out hermes_issue_cmd() will probably return -EBUSY below */
+
+       /* According to the documentation, EVSTAT may contain
+          obsolete event occurrence information.  We have to acknowledge
+          it by writing EVACK. */
+       reg = hermes_read_regn(hw, EVSTAT);
+       hermes_write_regn(hw, EVACK, reg);
+
+       /* We don't use hermes_docmd_wait here, because the reset wipes
+          the magic constant in SWSUPPORT0 away, and it gets confused */
+       err = hermes_doicmd_wait(hw, HERMES_CMD_INIT, 0, 0, 0, NULL);
+
+       return err;
+}
+EXPORT_SYMBOL(hermes_init);
+
+/* Issue a command to the chip, and (busy!) wait for it to
+ * complete.
+ *
+ * Returns: < 0 on internal error, 0 on success, > 0 on error returned by the firmware
+ *
+ * Callable from any context, but locking is your problem. */
+int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
+                     struct hermes_response *resp)
+{
+       int err;
+       int k;
+       u16 reg;
+       u16 status;
+
+       err = hermes_issue_cmd(hw, cmd, parm0, 0, 0);
+       if (err) {
+               if (! hermes_present(hw)) {
+                       if (net_ratelimit())
+                               printk(KERN_WARNING "hermes @ %p: "
+                                      "Card removed while issuing command "
+                                      "0x%04x.\n", hw->iobase, cmd);
+                       err = -ENODEV;
+               } else 
+                       if (net_ratelimit())
+                               printk(KERN_ERR "hermes @ %p: "
+                                      "Error %d issuing command 0x%04x.\n",
+                                      hw->iobase, err, cmd);
+               goto out;
+       }
+
+       reg = hermes_read_regn(hw, EVSTAT);
+       k = CMD_COMPL_TIMEOUT;
+       while ( (! (reg & HERMES_EV_CMD)) && k) {
+               k--;
+               udelay(10);
+               reg = hermes_read_regn(hw, EVSTAT);
+       }
+
+       if (! hermes_present(hw)) {
+               printk(KERN_WARNING "hermes @ %p: Card removed "
+                      "while waiting for command 0x%04x completion.\n",
+                      hw->iobase, cmd);
+               err = -ENODEV;
+               goto out;
+       }
+               
+       if (! (reg & HERMES_EV_CMD)) {
+               printk(KERN_ERR "hermes @ %p: Timeout waiting for "
+                      "command 0x%04x completion.\n", hw->iobase, cmd);
+               err = -ETIMEDOUT;
+               goto out;
+       }
+
+       status = hermes_read_regn(hw, STATUS);
+       if (resp) {
+               resp->status = status;
+               resp->resp0 = hermes_read_regn(hw, RESP0);
+               resp->resp1 = hermes_read_regn(hw, RESP1);
+               resp->resp2 = hermes_read_regn(hw, RESP2);
+       }
+
+       hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
+
+       if (status & HERMES_STATUS_RESULT)
+               err = -EIO;
+
+ out:
+       return err;
+}
+EXPORT_SYMBOL(hermes_docmd_wait);
+
+int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
+{
+       int err = 0;
+       int k;
+       u16 reg;
+       
+       if ( (size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX) )
+               return -EINVAL;
+
+       err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, NULL);
+       if (err) {
+               return err;
+       }
+
+       reg = hermes_read_regn(hw, EVSTAT);
+       k = ALLOC_COMPL_TIMEOUT;
+       while ( (! (reg & HERMES_EV_ALLOC)) && k) {
+               k--;
+               udelay(10);
+               reg = hermes_read_regn(hw, EVSTAT);
+       }
+       
+       if (! hermes_present(hw)) {
+               printk(KERN_WARNING "hermes @ %p: "
+                      "Card removed waiting for frame allocation.\n",
+                      hw->iobase);
+               return -ENODEV;
+       }
+               
+       if (! (reg & HERMES_EV_ALLOC)) {
+               printk(KERN_ERR "hermes @ %p: "
+                      "Timeout waiting for frame allocation\n",
+                      hw->iobase);
+               return -ETIMEDOUT;
+       }
+
+       *fid = hermes_read_regn(hw, ALLOCFID);
+       hermes_write_regn(hw, EVACK, HERMES_EV_ALLOC);
+       
+       return 0;
+}
+EXPORT_SYMBOL(hermes_allocate);
+
+/* Set up a BAP to read a particular chunk of data from card's internal buffer.
+ *
+ * Returns: < 0 on internal failure (errno), 0 on success, >0 on error
+ * from firmware
+ *
+ * Callable from any context */
+static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
+{
+       int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
+       int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
+       int k;
+       u16 reg;
+
+       /* Paranoia.. */
+       if ( (offset > HERMES_BAP_OFFSET_MAX) || (offset % 2) )
+               return -EINVAL;
+
+       k = HERMES_BAP_BUSY_TIMEOUT;
+       reg = hermes_read_reg(hw, oreg);
+       while ((reg & HERMES_OFFSET_BUSY) && k) {
+               k--;
+               udelay(1);
+               reg = hermes_read_reg(hw, oreg);
+       }
+
+       if (reg & HERMES_OFFSET_BUSY)
+               return -ETIMEDOUT;
+
+       /* Now we actually set up the transfer */
+       hermes_write_reg(hw, sreg, id);
+       hermes_write_reg(hw, oreg, offset);
+
+       /* Wait for the BAP to be ready */
+       k = HERMES_BAP_BUSY_TIMEOUT;
+       reg = hermes_read_reg(hw, oreg);
+       while ( (reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
+               k--;
+               udelay(1);
+               reg = hermes_read_reg(hw, oreg);
+       }
+
+       if (reg != offset) {
+               printk(KERN_ERR "hermes @ %p: BAP%d offset %s: "
+                      "reg=0x%x id=0x%x offset=0x%x\n", hw->iobase, bap,
+                      (reg & HERMES_OFFSET_BUSY) ? "timeout" : "error",
+                      reg, id, offset);
+
+               if (reg & HERMES_OFFSET_BUSY) {
+                       return -ETIMEDOUT;
+               }
+
+               return -EIO;            /* error or wrong offset */
+       }
+
+       return 0;
+}
+
+/* Read a block of data from the chip's buffer, via the
+ * BAP. Synchronization/serialization is the caller's problem.  len
+ * must be even.
+ *
+ * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
+ */
+int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
+                    u16 id, u16 offset)
+{
+       int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
+       int err = 0;
+
+       if ( (len < 0) || (len % 2) )
+               return -EINVAL;
+
+       err = hermes_bap_seek(hw, bap, id, offset);
+       if (err)
+               goto out;
+
+       /* Actually do the transfer */
+       hermes_read_words(hw, dreg, buf, len/2);
+
+ out:
+       return err;
+}
+EXPORT_SYMBOL(hermes_bap_pread);
+
+/* Write a block of data to the chip's buffer, via the
+ * BAP. Synchronization/serialization is the caller's problem.
+ *
+ * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
+ */
+int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
+                     u16 id, u16 offset)
+{
+       int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
+       int err = 0;
+
+       if (len < 0)
+               return -EINVAL;
+
+       err = hermes_bap_seek(hw, bap, id, offset);
+       if (err)
+               goto out;
+       
+       /* Actually do the transfer */
+       hermes_write_bytes(hw, dreg, buf, len);
+
+ out:  
+       return err;
+}
+EXPORT_SYMBOL(hermes_bap_pwrite);
+
+/* Read a Length-Type-Value record from the card.
+ *
+ * If length is NULL, we ignore the length read from the card, and
+ * read the entire buffer regardless. This is useful because some of
+ * the configuration records appear to have incorrect lengths in
+ * practice.
+ *
+ * Callable from user or bh context.  */
+int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
+                   u16 *length, void *buf)
+{
+       int err = 0;
+       int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
+       u16 rlength, rtype;
+       unsigned nwords;
+
+       if ( (bufsize < 0) || (bufsize % 2) )
+               return -EINVAL;
+
+       err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, NULL);
+       if (err)
+               return err;
+
+       err = hermes_bap_seek(hw, bap, rid, 0);
+       if (err)
+               return err;
+
+       rlength = hermes_read_reg(hw, dreg);
+
+       if (! rlength)
+               return -ENODATA;
+
+       rtype = hermes_read_reg(hw, dreg);
+
+       if (length)
+               *length = rlength;
+
+       if (rtype != rid)
+               printk(KERN_WARNING "hermes @ %p: %s(): "
+                      "rid (0x%04x) does not match type (0x%04x)\n",
+                      hw->iobase, __func__, rid, rtype);
+       if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize)
+               printk(KERN_WARNING "hermes @ %p: "
+                      "Truncating LTV record from %d to %d bytes. "
+                      "(rid=0x%04x, len=0x%04x)\n", hw->iobase,
+                      HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);
+
+       nwords = min((unsigned)rlength - 1, bufsize / 2);
+       hermes_read_words(hw, dreg, buf, nwords);
+
+       return 0;
+}
+EXPORT_SYMBOL(hermes_read_ltv);
+
+int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, 
+                    u16 length, const void *value)
+{
+       int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
+       int err = 0;
+       unsigned count;
+
+       if (length == 0)
+               return -EINVAL;
+
+       err = hermes_bap_seek(hw, bap, rid, 0);
+       if (err)
+               return err;
+
+       hermes_write_reg(hw, dreg, length);
+       hermes_write_reg(hw, dreg, rid);
+
+       count = length - 1;
+
+       hermes_write_bytes(hw, dreg, value, count << 1);
+
+       err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE,
+                               rid, NULL);
+
+       return err;
+}
+EXPORT_SYMBOL(hermes_write_ltv);
+
+static int __init init_hermes(void)
+{
+       return 0;
+}
+
+static void __exit exit_hermes(void)
+{
+}
+
+module_init(init_hermes);
+module_exit(exit_hermes);
diff --git a/drivers/net/wireless/orinoco/hermes.h b/drivers/net/wireless/orinoco/hermes.h
new file mode 100644 (file)
index 0000000..8b13c8f
--- /dev/null
@@ -0,0 +1,494 @@
+/* hermes.h
+ *
+ * Driver core for the "Hermes" wireless MAC controller, as used in
+ * the Lucent Orinoco and Cabletron RoamAbout cards. It should also
+ * work on the hfa3841 and hfa3842 MAC controller chips used in the
+ * Prism I & II chipsets.
+ *
+ * This is not a complete driver, just low-level access routines for
+ * the MAC controller itself.
+ *
+ * Based on the prism2 driver from Absolute Value Systems' linux-wlan
+ * project, the Linux wvlan_cs driver, Lucent's HCF-Light
+ * (wvlan_hcf.c) library, and the NetBSD wireless driver.
+ *
+ * Copyright (C) 2000, David Gibson, Linuxcare Australia.
+ * (C) Copyright David Gibson, IBM Corp. 2001-2003.
+ *
+ * Portions taken from hfa384x.h, Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+ *
+ * This file distributed under the GPL, version 2.
+ */
+
+#ifndef _HERMES_H
+#define _HERMES_H
+
+/* Notes on locking:
+ *
+ * As a module of low level hardware access routines, there is no
+ * locking. Users of this module should ensure that they serialize
+ * access to the hermes_t structure, and to the hardware
+*/
+
+#include <linux/if_ether.h>
+#include <asm/io.h>
+
+/*
+ * Limits and constants
+ */
+#define                HERMES_ALLOC_LEN_MIN            (4)
+#define                HERMES_ALLOC_LEN_MAX            (2400)
+#define                HERMES_LTV_LEN_MAX              (34)
+#define                HERMES_BAP_DATALEN_MAX          (4096)
+#define                HERMES_BAP_OFFSET_MAX           (4096)
+#define                HERMES_PORTID_MAX               (7)
+#define                HERMES_NUMPORTS_MAX             (HERMES_PORTID_MAX+1)
+#define                HERMES_PDR_LEN_MAX              (260)   /* in bytes, from EK */
+#define                HERMES_PDA_RECS_MAX             (200)   /* a guess */
+#define                HERMES_PDA_LEN_MAX              (1024)  /* in bytes, from EK */
+#define                HERMES_SCANRESULT_MAX           (35)
+#define                HERMES_CHINFORESULT_MAX         (8)
+#define                HERMES_MAX_MULTICAST            (16)
+#define                HERMES_MAGIC                    (0x7d1f)
+
+/*
+ * Hermes register offsets
+ */
+#define                HERMES_CMD                      (0x00)
+#define                HERMES_PARAM0                   (0x02)
+#define                HERMES_PARAM1                   (0x04)
+#define                HERMES_PARAM2                   (0x06)
+#define                HERMES_STATUS                   (0x08)
+#define                HERMES_RESP0                    (0x0A)
+#define                HERMES_RESP1                    (0x0C)
+#define                HERMES_RESP2                    (0x0E)
+#define                HERMES_INFOFID                  (0x10)
+#define                HERMES_RXFID                    (0x20)
+#define                HERMES_ALLOCFID                 (0x22)
+#define                HERMES_TXCOMPLFID               (0x24)
+#define                HERMES_SELECT0                  (0x18)
+#define                HERMES_OFFSET0                  (0x1C)
+#define                HERMES_DATA0                    (0x36)
+#define                HERMES_SELECT1                  (0x1A)
+#define                HERMES_OFFSET1                  (0x1E)
+#define                HERMES_DATA1                    (0x38)
+#define                HERMES_EVSTAT                   (0x30)
+#define                HERMES_INTEN                    (0x32)
+#define                HERMES_EVACK                    (0x34)
+#define                HERMES_CONTROL                  (0x14)
+#define                HERMES_SWSUPPORT0               (0x28)
+#define                HERMES_SWSUPPORT1               (0x2A)
+#define                HERMES_SWSUPPORT2               (0x2C)
+#define                HERMES_AUXPAGE                  (0x3A)
+#define                HERMES_AUXOFFSET                (0x3C)
+#define                HERMES_AUXDATA                  (0x3E)
+
+/*
+ * CMD register bitmasks
+ */
+#define                HERMES_CMD_BUSY                 (0x8000)
+#define                HERMES_CMD_AINFO                (0x7f00)
+#define                HERMES_CMD_MACPORT              (0x0700)
+#define                HERMES_CMD_RECL                 (0x0100)
+#define                HERMES_CMD_WRITE                (0x0100)
+#define                HERMES_CMD_PROGMODE             (0x0300)
+#define                HERMES_CMD_CMDCODE              (0x003f)
+
+/*
+ * STATUS register bitmasks
+ */
+#define                HERMES_STATUS_RESULT            (0x7f00)
+#define                HERMES_STATUS_CMDCODE           (0x003f)
+
+/*
+ * OFFSET register bitmasks
+ */
+#define                HERMES_OFFSET_BUSY              (0x8000)
+#define                HERMES_OFFSET_ERR               (0x4000)
+#define                HERMES_OFFSET_DATAOFF           (0x0ffe)
+
+/*
+ * Event register bitmasks (INTEN, EVSTAT, EVACK)
+ */
+#define                HERMES_EV_TICK                  (0x8000)
+#define                HERMES_EV_WTERR                 (0x4000)
+#define                HERMES_EV_INFDROP               (0x2000)
+#define                HERMES_EV_INFO                  (0x0080)
+#define                HERMES_EV_DTIM                  (0x0020)
+#define                HERMES_EV_CMD                   (0x0010)
+#define                HERMES_EV_ALLOC                 (0x0008)
+#define                HERMES_EV_TXEXC                 (0x0004)
+#define                HERMES_EV_TX                    (0x0002)
+#define                HERMES_EV_RX                    (0x0001)
+
+/*
+ * Command codes
+ */
+/*--- Controller Commands ----------------------------*/
+#define                HERMES_CMD_INIT                 (0x0000)
+#define                HERMES_CMD_ENABLE               (0x0001)
+#define                HERMES_CMD_DISABLE              (0x0002)
+#define                HERMES_CMD_DIAG                 (0x0003)
+
+/*--- Buffer Mgmt Commands ---------------------------*/
+#define                HERMES_CMD_ALLOC                (0x000A)
+#define                HERMES_CMD_TX                   (0x000B)
+
+/*--- Regulate Commands ------------------------------*/
+#define                HERMES_CMD_NOTIFY               (0x0010)
+#define                HERMES_CMD_INQUIRE              (0x0011)
+
+/*--- Configure Commands -----------------------------*/
+#define                HERMES_CMD_ACCESS               (0x0021)
+#define                HERMES_CMD_DOWNLD               (0x0022)
+
+/*--- Serial I/O Commands ----------------------------*/
+#define                HERMES_CMD_READMIF              (0x0030)
+#define                HERMES_CMD_WRITEMIF             (0x0031)
+
+/*--- Debugging Commands -----------------------------*/
+#define        HERMES_CMD_TEST                 (0x0038)
+
+
+/* Test command arguments */
+#define                HERMES_TEST_SET_CHANNEL         0x0800
+#define                HERMES_TEST_MONITOR             0x0b00
+#define                HERMES_TEST_STOP                0x0f00
+
+/* Authentication algorithms */
+#define                HERMES_AUTH_OPEN                1
+#define                HERMES_AUTH_SHARED_KEY          2
+
+/* WEP settings */
+#define                HERMES_WEP_PRIVACY_INVOKED      0x0001
+#define                HERMES_WEP_EXCL_UNENCRYPTED     0x0002
+#define                HERMES_WEP_HOST_ENCRYPT         0x0010
+#define                HERMES_WEP_HOST_DECRYPT         0x0080
+
+/* Symbol hostscan options */
+#define                HERMES_HOSTSCAN_SYMBOL_5SEC     0x0001
+#define                HERMES_HOSTSCAN_SYMBOL_ONCE     0x0002
+#define                HERMES_HOSTSCAN_SYMBOL_PASSIVE  0x0040
+#define                HERMES_HOSTSCAN_SYMBOL_BCAST    0x0080
+
+/*
+ * Frame structures and constants
+ */
+
+#define HERMES_DESCRIPTOR_OFFSET       0
+#define HERMES_802_11_OFFSET           (14)
+#define HERMES_802_3_OFFSET            (14+32)
+#define HERMES_802_2_OFFSET            (14+32+14)
+#define HERMES_TXCNTL2_OFFSET          (HERMES_802_3_OFFSET - 2)
+
+#define HERMES_RXSTAT_ERR              (0x0003)
+#define        HERMES_RXSTAT_BADCRC            (0x0001)
+#define        HERMES_RXSTAT_UNDECRYPTABLE     (0x0002)
+#define        HERMES_RXSTAT_MIC               (0x0010)        /* Frame contains MIC */
+#define        HERMES_RXSTAT_MACPORT           (0x0700)
+#define HERMES_RXSTAT_PCF              (0x1000)        /* Frame was received in CF period */
+#define        HERMES_RXSTAT_MIC_KEY_ID        (0x1800)        /* MIC key used */
+#define        HERMES_RXSTAT_MSGTYPE           (0xE000)
+#define        HERMES_RXSTAT_1042              (0x2000)        /* RFC-1042 frame */
+#define        HERMES_RXSTAT_TUNNEL            (0x4000)        /* bridge-tunnel encoded frame */
+#define        HERMES_RXSTAT_WMP               (0x6000)        /* Wavelan-II Management Protocol frame */
+
+/* Shift amount for key ID in RXSTAT and TXCTRL */
+#define        HERMES_MIC_KEY_ID_SHIFT         11
+
+struct hermes_tx_descriptor {
+       __le16 status;
+       __le16 reserved1;
+       __le16 reserved2;
+       __le32 sw_support;
+       u8 retry_count;
+       u8 tx_rate;
+       __le16 tx_control;      
+} __attribute__ ((packed));
+
+#define HERMES_TXSTAT_RETRYERR         (0x0001)
+#define HERMES_TXSTAT_AGEDERR          (0x0002)
+#define HERMES_TXSTAT_DISCON           (0x0004)
+#define HERMES_TXSTAT_FORMERR          (0x0008)
+
+#define HERMES_TXCTRL_TX_OK            (0x0002)        /* ?? interrupt on Tx complete */
+#define HERMES_TXCTRL_TX_EX            (0x0004)        /* ?? interrupt on Tx exception */
+#define HERMES_TXCTRL_802_11           (0x0008)        /* We supply 802.11 header */
+#define HERMES_TXCTRL_MIC              (0x0010)        /* 802.3 + TKIP */
+#define HERMES_TXCTRL_MIC_KEY_ID       (0x1800)        /* MIC Key ID mask */
+#define HERMES_TXCTRL_ALT_RTRY         (0x0020)
+
+/* Inquiry constants and data types */
+
+#define HERMES_INQ_TALLIES             (0xF100)
+#define HERMES_INQ_SCAN                        (0xF101)
+#define HERMES_INQ_CHANNELINFO         (0xF102)
+#define HERMES_INQ_HOSTSCAN            (0xF103)
+#define HERMES_INQ_HOSTSCAN_SYMBOL     (0xF104)
+#define HERMES_INQ_LINKSTATUS          (0xF200)
+#define HERMES_INQ_SEC_STAT_AGERE      (0xF202)
+
+struct hermes_tallies_frame {
+       __le16 TxUnicastFrames;
+       __le16 TxMulticastFrames;
+       __le16 TxFragments;
+       __le16 TxUnicastOctets;
+       __le16 TxMulticastOctets;
+       __le16 TxDeferredTransmissions;
+       __le16 TxSingleRetryFrames;
+       __le16 TxMultipleRetryFrames;
+       __le16 TxRetryLimitExceeded;
+       __le16 TxDiscards;
+       __le16 RxUnicastFrames;
+       __le16 RxMulticastFrames;
+       __le16 RxFragments;
+       __le16 RxUnicastOctets;
+       __le16 RxMulticastOctets;
+       __le16 RxFCSErrors;
+       __le16 RxDiscards_NoBuffer;
+       __le16 TxDiscardsWrongSA;
+       __le16 RxWEPUndecryptable;
+       __le16 RxMsgInMsgFragments;
+       __le16 RxMsgInBadMsgFragments;
+       /* Those last are probably not available in very old firmwares */
+       __le16 RxDiscards_WEPICVError;
+       __le16 RxDiscards_WEPExcluded;
+} __attribute__ ((packed));
+
+/* Grabbed from wlan-ng - Thanks Mark... - Jean II
+ * This is the result of a scan inquiry command */
+/* Structure describing info about an Access Point */
+struct prism2_scan_apinfo {
+       __le16 channel;         /* Channel where the AP sits */
+       __le16 noise;           /* Noise level */
+       __le16 level;           /* Signal level */
+       u8 bssid[ETH_ALEN];     /* MAC address of the Access Point */
+       __le16 beacon_interv;   /* Beacon interval */
+       __le16 capabilities;    /* Capabilities */
+       __le16 essid_len;       /* ESSID length */
+       u8 essid[32];           /* ESSID of the network */
+       u8 rates[10];           /* Bit rate supported */
+       __le16 proberesp_rate;  /* Data rate of the response frame */
+       __le16 atim;            /* ATIM window time, Kus (hostscan only) */
+} __attribute__ ((packed));
+
+/* Same stuff for the Lucent/Agere card.
+ * Thanks to h1kari <h1kari AT dachb0den.com> - Jean II */
+struct agere_scan_apinfo {
+       __le16 channel;         /* Channel where the AP sits */
+       __le16 noise;           /* Noise level */
+       __le16 level;           /* Signal level */
+       u8 bssid[ETH_ALEN];     /* MAC address of the Access Point */
+       __le16 beacon_interv;   /* Beacon interval */
+       __le16 capabilities;    /* Capabilities */
+       /* bits: 0-ess, 1-ibss, 4-privacy [wep] */
+       __le16 essid_len;       /* ESSID length */
+       u8 essid[32];           /* ESSID of the network */
+} __attribute__ ((packed));
+
+/* Moustafa: Scan structure for Symbol cards */
+struct symbol_scan_apinfo {
+       u8 channel;             /* Channel where the AP sits */
+       u8 unknown1;            /* 8 in 2.9x and 3.9x f/w, 0 otherwise */
+       __le16 noise;           /* Noise level */
+       __le16 level;           /* Signal level */
+       u8 bssid[ETH_ALEN];     /* MAC address of the Access Point */
+       __le16 beacon_interv;   /* Beacon interval */
+       __le16 capabilities;    /* Capabilities */
+       /* bits: 0-ess, 1-ibss, 4-privacy [wep] */
+       __le16 essid_len;       /* ESSID length */
+       u8 essid[32];           /* ESSID of the network */
+       __le16 rates[5];        /* Bit rate supported */
+       __le16 basic_rates;     /* Basic rates bitmask */
+       u8 unknown2[6];         /* Always FF:FF:FF:FF:00:00 */
+       u8 unknown3[8];         /* Always 0, appeared in f/w 3.91-68 */
+} __attribute__ ((packed));
+
+union hermes_scan_info {
+       struct agere_scan_apinfo        a;
+       struct prism2_scan_apinfo       p;
+       struct symbol_scan_apinfo       s;
+};
+
+/* Extended scan struct for HERMES_INQ_CHANNELINFO.
+ * wl_lkm calls this an ACS scan (Automatic Channel Select).
+ * Keep out of union hermes_scan_info because it is much bigger than
+ * the older scan structures. */
+struct agere_ext_scan_info {
+       __le16  reserved0;
+
+       u8      noise;
+       u8      level;
+       u8      rx_flow;
+       u8      rate;
+       __le16  reserved1[2];
+
+       __le16  frame_control;
+       __le16  dur_id;
+       u8      addr1[ETH_ALEN];
+       u8      addr2[ETH_ALEN];
+       u8      bssid[ETH_ALEN];
+       __le16  sequence;
+       u8      addr4[ETH_ALEN];
+
+       __le16  data_length;
+
+       /* Next 3 fields do not get filled in. */
+       u8      daddr[ETH_ALEN];
+       u8      saddr[ETH_ALEN];
+       __le16  len_type;
+
+       __le64  timestamp;
+       __le16  beacon_interval;
+       __le16  capabilities;
+       u8      data[316];
+} __attribute__ ((packed));
+
+#define HERMES_LINKSTATUS_NOT_CONNECTED   (0x0000)  
+#define HERMES_LINKSTATUS_CONNECTED       (0x0001)
+#define HERMES_LINKSTATUS_DISCONNECTED    (0x0002)
+#define HERMES_LINKSTATUS_AP_CHANGE       (0x0003)
+#define HERMES_LINKSTATUS_AP_OUT_OF_RANGE (0x0004)
+#define HERMES_LINKSTATUS_AP_IN_RANGE     (0x0005)
+#define HERMES_LINKSTATUS_ASSOC_FAILED    (0x0006)
+  
+struct hermes_linkstatus {
+       __le16 linkstatus;         /* Link status */
+} __attribute__ ((packed));
+
+struct hermes_response {
+       u16 status, resp0, resp1, resp2;
+};
+
+/* "ID" structure - used for ESSID and station nickname */
+struct hermes_idstring {
+       __le16 len;
+       __le16 val[16];
+} __attribute__ ((packed));
+
+struct hermes_multicast {
+       u8 addr[HERMES_MAX_MULTICAST][ETH_ALEN];
+} __attribute__ ((packed));
+
+/* Timeouts */
+#define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */
+
+/* Basic control structure */
+typedef struct hermes {
+       void __iomem *iobase;
+       int reg_spacing;
+#define HERMES_16BIT_REGSPACING        0
+#define HERMES_32BIT_REGSPACING        1
+       u16 inten; /* Which interrupts should be enabled? */
+} hermes_t;
+
+/* Register access convenience macros */
+#define hermes_read_reg(hw, off) \
+       (ioread16((hw)->iobase + ( (off) << (hw)->reg_spacing )))
+#define hermes_write_reg(hw, off, val) \
+       (iowrite16((val), (hw)->iobase + ((off) << (hw)->reg_spacing)))
+#define hermes_read_regn(hw, name) hermes_read_reg((hw), HERMES_##name)
+#define hermes_write_regn(hw, name, val) hermes_write_reg((hw), HERMES_##name, (val))
+
+/* Function prototypes */
+void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing);
+int hermes_init(hermes_t *hw);
+int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
+                     struct hermes_response *resp);
+int hermes_doicmd_wait(hermes_t *hw, u16 cmd,
+                      u16 parm0, u16 parm1, u16 parm2,
+                      struct hermes_response *resp);
+int hermes_allocate(hermes_t *hw, u16 size, u16 *fid);
+
+int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
+                      u16 id, u16 offset);
+int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
+                       u16 id, u16 offset);
+int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen,
+                   u16 *length, void *buf);
+int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
+                     u16 length, const void *value);
+
+/* Inline functions */
+
+static inline int hermes_present(hermes_t *hw)
+{
+       return hermes_read_regn(hw, SWSUPPORT0) == HERMES_MAGIC;
+}
+
+static inline void hermes_set_irqmask(hermes_t *hw, u16 events)
+{
+       hw->inten = events;
+       hermes_write_regn(hw, INTEN, events);
+}
+
+static inline int hermes_enable_port(hermes_t *hw, int port)
+{
+       return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8),
+                                0, NULL);
+}
+
+static inline int hermes_disable_port(hermes_t *hw, int port)
+{
+       return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8), 
+                                0, NULL);
+}
+
+/* Initiate an INQUIRE command (tallies or scan).  The result will come as an
+ * information frame in __orinoco_ev_info() */
+static inline int hermes_inquire(hermes_t *hw, u16 rid)
+{
+       return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL);
+}
+
+#define HERMES_BYTES_TO_RECLEN(n) ( (((n)+1)/2) + 1 )
+#define HERMES_RECLEN_TO_BYTES(n) ( ((n)-1) * 2 )
+
+/* Note that for the next two, the count is in 16-bit words, not bytes */
+static inline void hermes_read_words(struct hermes *hw, int off, void *buf, unsigned count)
+{
+       off = off << hw->reg_spacing;
+       ioread16_rep(hw->iobase + off, buf, count);
+}
+
+static inline void hermes_write_bytes(struct hermes *hw, int off,
+                                     const char *buf, unsigned count)
+{
+       off = off << hw->reg_spacing;
+       iowrite16_rep(hw->iobase + off, buf, count >> 1);
+       if (unlikely(count & 1))
+               iowrite8(buf[count - 1], hw->iobase + off);
+}
+
+static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count)
+{
+       unsigned i;
+
+       off = off << hw->reg_spacing;
+
+       for (i = 0; i < count; i++)
+               iowrite16(0, hw->iobase + off);
+}
+
+#define HERMES_READ_RECORD(hw, bap, rid, buf) \
+       (hermes_read_ltv((hw),(bap),(rid), sizeof(*buf), NULL, (buf)))
+#define HERMES_WRITE_RECORD(hw, bap, rid, buf) \
+       (hermes_write_ltv((hw),(bap),(rid),HERMES_BYTES_TO_RECLEN(sizeof(*buf)),(buf)))
+
+static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
+{
+       __le16 rec;
+       int err;
+
+       err = HERMES_READ_RECORD(hw, bap, rid, &rec);
+       *word = le16_to_cpu(rec);
+       return err;
+}
+
+static inline int hermes_write_wordrec(hermes_t *hw, int bap, u16 rid, u16 word)
+{
+       __le16 rec = cpu_to_le16(word);
+       return HERMES_WRITE_RECORD(hw, bap, rid, &rec);
+}
+
+#endif  /* _HERMES_H */
diff --git a/drivers/net/wireless/orinoco/hermes_dld.c b/drivers/net/wireless/orinoco/hermes_dld.c
new file mode 100644 (file)
index 0000000..d8c626e
--- /dev/null
@@ -0,0 +1,730 @@
+/*
+ * Hermes download helper driver.
+ *
+ * This could be entirely merged into hermes.c.
+ *
+ * I'm keeping it separate to minimise the amount of merging between
+ * kernel upgrades. It also means the memory overhead for drivers that
+ * don't need firmware download low.
+ *
+ * This driver:
+ *  - is capable of writing to the volatile area of the hermes device
+ *  - is currently not capable of writing to non-volatile areas
+ *  - provide helpers to identify and update plugin data
+ *  - is not capable of interpreting a fw image directly. That is up to
+ *    the main card driver.
+ *  - deals with Hermes I devices. It can probably be modified to deal
+ *    with Hermes II devices
+ *
+ * Copyright (C) 2007, David Kilroy
+ *
+ * Plug data code slightly modified from spectrum_cs driver
+ *    Copyright (C) 2002-2005 Pavel Roskin <proski@gnu.org>
+ * Portions based on information in wl_lkm_718 Agere driver
+ *    COPYRIGHT (C) 2001-2004 by Agere Systems Inc. All Rights Reserved
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include "hermes.h"
+#include "hermes_dld.h"
+
+MODULE_DESCRIPTION("Download helper for Lucent Hermes chipset");
+MODULE_AUTHOR("David Kilroy <kilroyd@gmail.com>");
+MODULE_LICENSE("Dual MPL/GPL");
+
+#define PFX "hermes_dld: "
+
+/*
+ * AUX port access.  To unlock the AUX port write the access keys to the
+ * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL
+ * register.  Then read it and make sure it's HERMES_AUX_ENABLED.
+ */
+#define HERMES_AUX_ENABLE      0x8000  /* Enable auxiliary port access */
+#define HERMES_AUX_DISABLE     0x4000  /* Disable to auxiliary port access */
+#define HERMES_AUX_ENABLED     0xC000  /* Auxiliary port is open */
+#define HERMES_AUX_DISABLED    0x0000  /* Auxiliary port is closed */
+
+#define HERMES_AUX_PW0 0xFE01
+#define HERMES_AUX_PW1 0xDC23
+#define HERMES_AUX_PW2 0xBA45
+
+/* HERMES_CMD_DOWNLD */
+#define HERMES_PROGRAM_DISABLE             (0x0000 | HERMES_CMD_DOWNLD)
+#define HERMES_PROGRAM_ENABLE_VOLATILE     (0x0100 | HERMES_CMD_DOWNLD)
+#define HERMES_PROGRAM_ENABLE_NON_VOLATILE (0x0200 | HERMES_CMD_DOWNLD)
+#define HERMES_PROGRAM_NON_VOLATILE        (0x0300 | HERMES_CMD_DOWNLD)
+
+/* End markers used in dblocks */
+#define PDI_END                0x00000000      /* End of PDA */
+#define BLOCK_END      0xFFFFFFFF      /* Last image block */
+#define TEXT_END       0x1A            /* End of text header */
+
+/*
+ * PDA == Production Data Area
+ *
+ * In principle, the max. size of the PDA is is 4096 words. Currently,
+ * however, only about 500 bytes of this area are used.
+ *
+ * Some USB implementations can't handle sizes in excess of 1016. Note
+ * that PDA is not actually used in those USB environments, but may be
+ * retrieved by common code.
+ */
+#define MAX_PDA_SIZE   1000
+
+/* Limit the amout we try to download in a single shot.
+ * Size is in bytes.
+ */
+#define MAX_DL_SIZE 1024
+#define LIMIT_PROGRAM_SIZE 0
+
+/*
+ * The following structures have little-endian fields denoted by
+ * the leading underscore.  Don't access them directly - use inline
+ * functions defined below.
+ */
+
+/*
+ * The binary image to be downloaded consists of series of data blocks.
+ * Each block has the following structure.
+ */
+struct dblock {
+       __le32 addr;            /* adapter address where to write the block */
+       __le16 len;             /* length of the data only, in bytes */
+       char data[0];           /* data to be written */
+} __attribute__ ((packed));
+
+/*
+ * Plug Data References are located in in the image after the last data
+ * block.  They refer to areas in the adapter memory where the plug data
+ * items with matching ID should be written.
+ */
+struct pdr {
+       __le32 id;              /* record ID */
+       __le32 addr;            /* adapter address where to write the data */
+       __le32 len;             /* expected length of the data, in bytes */
+       char next[0];           /* next PDR starts here */
+} __attribute__ ((packed));
+
+/*
+ * Plug Data Items are located in the EEPROM read from the adapter by
+ * primary firmware.  They refer to the device-specific data that should
+ * be plugged into the secondary firmware.
+ */
+struct pdi {
+       __le16 len;             /* length of ID and data, in words */
+       __le16 id;              /* record ID */
+       char data[0];           /* plug data */
+} __attribute__ ((packed));
+
+/*** FW data block access functions ***/
+
+static inline u32
+dblock_addr(const struct dblock *blk)
+{
+       return le32_to_cpu(blk->addr);
+}
+
+static inline u32
+dblock_len(const struct dblock *blk)
+{
+       return le16_to_cpu(blk->len);
+}
+
+/*** PDR Access functions ***/
+
+static inline u32
+pdr_id(const struct pdr *pdr)
+{
+       return le32_to_cpu(pdr->id);
+}
+
+static inline u32
+pdr_addr(const struct pdr *pdr)
+{
+       return le32_to_cpu(pdr->addr);
+}
+
+static inline u32
+pdr_len(const struct pdr *pdr)
+{
+       return le32_to_cpu(pdr->len);
+}
+
+/*** PDI Access functions ***/
+
+static inline u32
+pdi_id(const struct pdi *pdi)
+{
+       return le16_to_cpu(pdi->id);
+}
+
+/* Return length of the data only, in bytes */
+static inline u32
+pdi_len(const struct pdi *pdi)
+{
+       return 2 * (le16_to_cpu(pdi->len) - 1);
+}
+
+/*** Hermes AUX control ***/
+
+static inline void
+hermes_aux_setaddr(hermes_t *hw, u32 addr)
+{
+       hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7));
+       hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F));
+}
+
+static inline int
+hermes_aux_control(hermes_t *hw, int enabled)
+{
+       int desired_state = enabled ? HERMES_AUX_ENABLED : HERMES_AUX_DISABLED;
+       int action = enabled ? HERMES_AUX_ENABLE : HERMES_AUX_DISABLE;
+       int i;
+
+       /* Already open? */
+       if (hermes_read_reg(hw, HERMES_CONTROL) == desired_state)
+               return 0;
+
+       hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0);
+       hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1);
+       hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2);
+       hermes_write_reg(hw, HERMES_CONTROL, action);
+
+       for (i = 0; i < 20; i++) {
+               udelay(10);
+               if (hermes_read_reg(hw, HERMES_CONTROL) ==
+                   desired_state)
+                       return 0;
+       }
+
+       return -EBUSY;
+}
+
+/*** Plug Data Functions ***/
+
+/*
+ * Scan PDR for the record with the specified RECORD_ID.
+ * If it's not found, return NULL.
+ */
+static struct pdr *
+hermes_find_pdr(struct pdr *first_pdr, u32 record_id)
+{
+       struct pdr *pdr = first_pdr;
+       void *end = (void *)first_pdr + MAX_PDA_SIZE;
+
+       while (((void *)pdr < end) &&
+              (pdr_id(pdr) != PDI_END)) {
+               /*
+                * PDR area is currently not terminated by PDI_END.
+                * It's followed by CRC records, which have the type
+                * field where PDR has length.  The type can be 0 or 1.
+                */
+               if (pdr_len(pdr) < 2)
+                       return NULL;
+
+               /* If the record ID matches, we are done */
+               if (pdr_id(pdr) == record_id)
+                       return pdr;
+
+               pdr = (struct pdr *) pdr->next;
+       }
+       return NULL;
+}
+
+/* Scan production data items for a particular entry */
+static struct pdi *
+hermes_find_pdi(struct pdi *first_pdi, u32 record_id)
+{
+       struct pdi *pdi = first_pdi;
+
+       while (pdi_id(pdi) != PDI_END) {
+
+               /* If the record ID matches, we are done */
+               if (pdi_id(pdi) == record_id)
+                       return pdi;
+
+               pdi = (struct pdi *) &pdi->data[pdi_len(pdi)];
+       }
+       return NULL;
+}
+
+/* Process one Plug Data Item - find corresponding PDR and plug it */
+static int
+hermes_plug_pdi(hermes_t *hw, struct pdr *first_pdr, const struct pdi *pdi)
+{
+       struct pdr *pdr;
+
+       /* Find the PDR corresponding to this PDI */
+       pdr = hermes_find_pdr(first_pdr, pdi_id(pdi));
+
+       /* No match is found, safe to ignore */
+       if (!pdr)
+               return 0;
+
+       /* Lengths of the data in PDI and PDR must match */
+       if (pdi_len(pdi) != pdr_len(pdr))
+               return -EINVAL;
+
+       /* do the actual plugging */
+       hermes_aux_setaddr(hw, pdr_addr(pdr));
+       hermes_write_bytes(hw, HERMES_AUXDATA, pdi->data, pdi_len(pdi));
+
+       return 0;
+}
+
+/* Read PDA from the adapter */
+int hermes_read_pda(hermes_t *hw,
+                   __le16 *pda,
+                   u32 pda_addr,
+                   u16 pda_len,
+                   int use_eeprom) /* can we get this into hw? */
+{
+       int ret;
+       u16 pda_size;
+       u16 data_len = pda_len;
+       __le16 *data = pda;
+
+       if (use_eeprom) {
+               /* PDA of spectrum symbol is in eeprom */
+
+               /* Issue command to read EEPROM */
+               ret = hermes_docmd_wait(hw, HERMES_CMD_READMIF, 0, NULL);
+               if (ret)
+                       return ret;
+       } else {
+               /* wl_lkm does not include PDA size in the PDA area.
+                * We will pad the information into pda, so other routines
+                * don't have to be modified */
+               pda[0] = cpu_to_le16(pda_len - 2);
+                       /* Includes CFG_PROD_DATA but not itself */
+               pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */
+               data_len = pda_len - 4;
+               data = pda + 2;
+       }
+
+       /* Open auxiliary port */
+       ret = hermes_aux_control(hw, 1);
+       printk(KERN_DEBUG PFX "AUX enable returned %d\n", ret);
+       if (ret)
+               return ret;
+
+       /* read PDA from EEPROM */
+       hermes_aux_setaddr(hw, pda_addr);
+       hermes_read_words(hw, HERMES_AUXDATA, data, data_len / 2);
+
+       /* Close aux port */
+       ret = hermes_aux_control(hw, 0);
+       printk(KERN_DEBUG PFX "AUX disable returned %d\n", ret);
+
+       /* Check PDA length */
+       pda_size = le16_to_cpu(pda[0]);
+       printk(KERN_DEBUG PFX "Actual PDA length %d, Max allowed %d\n",
+              pda_size, pda_len);
+       if (pda_size > pda_len)
+               return -EINVAL;
+
+       return 0;
+}
+EXPORT_SYMBOL(hermes_read_pda);
+
+/* Parse PDA and write the records into the adapter
+ *
+ * Attempt to write every records that is in the specified pda
+ * which also has a valid production data record for the firmware.
+ */
+int hermes_apply_pda(hermes_t *hw,
+                    const char *first_pdr,
+                    const __le16 *pda)
+{
+       int ret;
+       const struct pdi *pdi;
+       struct pdr *pdr;
+
+       pdr = (struct pdr *) first_pdr;
+
+       /* Go through every PDI and plug them into the adapter */
+       pdi = (const struct pdi *) (pda + 2);
+       while (pdi_id(pdi) != PDI_END) {
+               ret = hermes_plug_pdi(hw, pdr, pdi);
+               if (ret)
+                       return ret;
+
+               /* Increment to the next PDI */
+               pdi = (const struct pdi *) &pdi->data[pdi_len(pdi)];
+       }
+       return 0;
+}
+EXPORT_SYMBOL(hermes_apply_pda);
+
+/* Identify the total number of bytes in all blocks
+ * including the header data.
+ */
+size_t
+hermes_blocks_length(const char *first_block)
+{
+       const struct dblock *blk = (const struct dblock *) first_block;
+       int total_len = 0;
+       int len;
+
+       /* Skip all blocks to locate Plug Data References
+        * (Spectrum CS) */
+       while (dblock_addr(blk) != BLOCK_END) {
+               len = dblock_len(blk);
+               total_len += sizeof(*blk) + len;
+               blk = (struct dblock *) &blk->data[len];
+       }
+
+       return total_len;
+}
+EXPORT_SYMBOL(hermes_blocks_length);
+
+/*** Hermes programming ***/
+
+/* About to start programming data (Hermes I)
+ * offset is the entry point
+ *
+ * Spectrum_cs' Symbol fw does not require this
+ * wl_lkm Agere fw does
+ * Don't know about intersil
+ */
+int hermesi_program_init(hermes_t *hw, u32 offset)
+{
+       int err;
+
+       /* Disable interrupts?*/
+       /*hw->inten = 0x0;*/
+       /*hermes_write_regn(hw, INTEN, 0);*/
+       /*hermes_set_irqmask(hw, 0);*/
+
+       /* Acknowledge any outstanding command */
+       hermes_write_regn(hw, EVACK, 0xFFFF);
+
+       /* Using doicmd_wait rather than docmd_wait */
+       err = hermes_doicmd_wait(hw,
+                                0x0100 | HERMES_CMD_INIT,
+                                0, 0, 0, NULL);
+       if (err)
+               return err;
+
+       err = hermes_doicmd_wait(hw,
+                                0x0000 | HERMES_CMD_INIT,
+                                0, 0, 0, NULL);
+       if (err)
+               return err;
+
+       err = hermes_aux_control(hw, 1);
+       printk(KERN_DEBUG PFX "AUX enable returned %d\n", err);
+
+       if (err)
+               return err;
+
+       printk(KERN_DEBUG PFX "Enabling volatile, EP 0x%08x\n", offset);
+       err = hermes_doicmd_wait(hw,
+                                HERMES_PROGRAM_ENABLE_VOLATILE,
+                                offset & 0xFFFFu,
+                                offset >> 16,
+                                0,
+                                NULL);
+       printk(KERN_DEBUG PFX "PROGRAM_ENABLE returned %d\n",
+              err);
+
+       return err;
+}
+EXPORT_SYMBOL(hermesi_program_init);
+
+/* Done programming data (Hermes I)
+ *
+ * Spectrum_cs' Symbol fw does not require this
+ * wl_lkm Agere fw does
+ * Don't know about intersil
+ */
+int hermesi_program_end(hermes_t *hw)
+{
+       struct hermes_response resp;
+       int rc = 0;
+       int err;
+
+       rc = hermes_docmd_wait(hw, HERMES_PROGRAM_DISABLE, 0, &resp);
+
+       printk(KERN_DEBUG PFX "PROGRAM_DISABLE returned %d, "
+              "r0 0x%04x, r1 0x%04x, r2 0x%04x\n",
+              rc, resp.resp0, resp.resp1, resp.resp2);
+
+       if ((rc == 0) &&
+           ((resp.status & HERMES_STATUS_CMDCODE) != HERMES_CMD_DOWNLD))
+               rc = -EIO;
+
+       err = hermes_aux_control(hw, 0);
+       printk(KERN_DEBUG PFX "AUX disable returned %d\n", err);
+
+       /* Acknowledge any outstanding command */
+       hermes_write_regn(hw, EVACK, 0xFFFF);
+
+       /* Reinitialise, ignoring return */
+       (void) hermes_doicmd_wait(hw, 0x0000 | HERMES_CMD_INIT,
+                                 0, 0, 0, NULL);
+
+       return rc ? rc : err;
+}
+EXPORT_SYMBOL(hermesi_program_end);
+
+/* Program the data blocks */
+int hermes_program(hermes_t *hw, const char *first_block, const char *end)
+{
+       const struct dblock *blk;
+       u32 blkaddr;
+       u32 blklen;
+#if LIMIT_PROGRAM_SIZE
+       u32 addr;
+       u32 len;
+#endif
+
+       blk = (const struct dblock *) first_block;
+
+       if ((const char *) blk > (end - sizeof(*blk)))
+               return -EIO;
+
+       blkaddr = dblock_addr(blk);
+       blklen = dblock_len(blk);
+
+       while ((blkaddr != BLOCK_END) &&
+              (((const char *) blk + blklen) <= end)) {
+               printk(KERN_DEBUG PFX
+                      "Programming block of length %d to address 0x%08x\n",
+                      blklen, blkaddr);
+
+#if !LIMIT_PROGRAM_SIZE
+               /* wl_lkm driver splits this into writes of 2000 bytes */
+               hermes_aux_setaddr(hw, blkaddr);
+               hermes_write_bytes(hw, HERMES_AUXDATA, blk->data,
+                                  blklen);
+#else
+               len = (blklen < MAX_DL_SIZE) ? blklen : MAX_DL_SIZE;
+               addr = blkaddr;
+
+               while (addr < (blkaddr + blklen)) {
+                       printk(KERN_DEBUG PFX
+                              "Programming subblock of length %d "
+                              "to address 0x%08x. Data @ %p\n",
+                              len, addr, &blk->data[addr - blkaddr]);
+
+                       hermes_aux_setaddr(hw, addr);
+                       hermes_write_bytes(hw, HERMES_AUXDATA,
+                                          &blk->data[addr - blkaddr],
+                                          len);
+
+                       addr += len;
+                       len = ((blkaddr + blklen - addr) < MAX_DL_SIZE) ?
+                               (blkaddr + blklen - addr) : MAX_DL_SIZE;
+               }
+#endif
+               blk = (const struct dblock *) &blk->data[blklen];
+
+               if ((const char *) blk > (end - sizeof(*blk)))
+                       return -EIO;
+
+               blkaddr = dblock_addr(blk);
+               blklen = dblock_len(blk);
+       }
+       return 0;
+}
+EXPORT_SYMBOL(hermes_program);
+
+static int __init init_hermes_dld(void)
+{
+       return 0;
+}
+
+static void __exit exit_hermes_dld(void)
+{
+}
+
+module_init(init_hermes_dld);
+module_exit(exit_hermes_dld);
+
+/*** Default plugging data for Hermes I ***/
+/* Values from wl_lkm_718/hcf/dhf.c */
+
+#define DEFINE_DEFAULT_PDR(pid, length, data)                          \
+static const struct {                                                  \
+       __le16 len;                                                     \
+       __le16 id;                                                      \
+       u8 val[length];                                                 \
+} __attribute__ ((packed)) default_pdr_data_##pid = {                  \
+       __constant_cpu_to_le16((sizeof(default_pdr_data_##pid)/         \
+                               sizeof(__le16)) - 1),                   \
+       __constant_cpu_to_le16(pid),                                    \
+       data                                                            \
+}
+
+#define DEFAULT_PDR(pid) default_pdr_data_##pid
+
+/*  HWIF Compatiblity */
+DEFINE_DEFAULT_PDR(0x0005, 10, "\x00\x00\x06\x00\x01\x00\x01\x00\x01\x00");
+
+/* PPPPSign */
+DEFINE_DEFAULT_PDR(0x0108, 4, "\x00\x00\x00\x00");
+
+/* PPPPProf */
+DEFINE_DEFAULT_PDR(0x0109, 10, "\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00");
+
+/* Antenna diversity */
+DEFINE_DEFAULT_PDR(0x0150, 2, "\x00\x3F");
+
+/* Modem VCO band Set-up */
+DEFINE_DEFAULT_PDR(0x0160, 28,
+                  "\x00\x00\x00\x00\x00\x00\x00\x00"
+                  "\x00\x00\x00\x00\x00\x00\x00\x00"
+                  "\x00\x00\x00\x00\x00\x00\x00\x00"
+                  "\x00\x00\x00\x00");
+
+/* Modem Rx Gain Table Values */
+DEFINE_DEFAULT_PDR(0x0161, 256,
+                  "\x3F\x01\x3F\01\x3F\x01\x3F\x01"
+                  "\x3F\x01\x3F\01\x3F\x01\x3F\x01"
+                  "\x3F\x01\x3F\01\x3F\x01\x3F\x01"
+                  "\x3F\x01\x3F\01\x3F\x01\x3F\x01"
+                  "\x3F\x01\x3E\01\x3E\x01\x3D\x01"
+                  "\x3D\x01\x3C\01\x3C\x01\x3B\x01"
+                  "\x3B\x01\x3A\01\x3A\x01\x39\x01"
+                  "\x39\x01\x38\01\x38\x01\x37\x01"
+                  "\x37\x01\x36\01\x36\x01\x35\x01"
+                  "\x35\x01\x34\01\x34\x01\x33\x01"
+                  "\x33\x01\x32\x01\x32\x01\x31\x01"
+                  "\x31\x01\x30\x01\x30\x01\x7B\x01"
+                  "\x7B\x01\x7A\x01\x7A\x01\x79\x01"
+                  "\x79\x01\x78\x01\x78\x01\x77\x01"
+                  "\x77\x01\x76\x01\x76\x01\x75\x01"
+                  "\x75\x01\x74\x01\x74\x01\x73\x01"
+                  "\x73\x01\x72\x01\x72\x01\x71\x01"
+                  "\x71\x01\x70\x01\x70\x01\x68\x01"
+                  "\x68\x01\x67\x01\x67\x01\x66\x01"
+                  "\x66\x01\x65\x01\x65\x01\x57\x01"
+                  "\x57\x01\x56\x01\x56\x01\x55\x01"
+                  "\x55\x01\x54\x01\x54\x01\x53\x01"
+                  "\x53\x01\x52\x01\x52\x01\x51\x01"
+                  "\x51\x01\x50\x01\x50\x01\x48\x01"
+                  "\x48\x01\x47\x01\x47\x01\x46\x01"
+                  "\x46\x01\x45\x01\x45\x01\x44\x01"
+                  "\x44\x01\x43\x01\x43\x01\x42\x01"
+                  "\x42\x01\x41\x01\x41\x01\x40\x01"
+                  "\x40\x01\x40\x01\x40\x01\x40\x01"
+                  "\x40\x01\x40\x01\x40\x01\x40\x01"
+                  "\x40\x01\x40\x01\x40\x01\x40\x01"
+                  "\x40\x01\x40\x01\x40\x01\x40\x01");
+
+/* Write PDA according to certain rules.
+ *
+ * For every production data record, look for a previous setting in
+ * the pda, and use that.
+ *
+ * For certain records, use defaults if they are not found in pda.
+ */
+int hermes_apply_pda_with_defaults(hermes_t *hw,
+                                  const char *first_pdr,
+                                  const __le16 *pda)
+{
+       const struct pdr *pdr = (const struct pdr *) first_pdr;
+       struct pdi *first_pdi = (struct pdi *) &pda[2];
+       struct pdi *pdi;
+       struct pdi *default_pdi = NULL;
+       struct pdi *outdoor_pdi;
+       void *end = (void *)first_pdr + MAX_PDA_SIZE;
+       int record_id;
+
+       while (((void *)pdr < end) &&
+              (pdr_id(pdr) != PDI_END)) {
+               /*
+                * For spectrum_cs firmwares,
+                * PDR area is currently not terminated by PDI_END.
+                * It's followed by CRC records, which have the type
+                * field where PDR has length.  The type can be 0 or 1.
+                */
+               if (pdr_len(pdr) < 2)
+                       break;
+               record_id = pdr_id(pdr);
+
+               pdi = hermes_find_pdi(first_pdi, record_id);
+               if (pdi)
+                       printk(KERN_DEBUG PFX "Found record 0x%04x at %p\n",
+                              record_id, pdi);
+
+               switch (record_id) {
+               case 0x110: /* Modem REFDAC values */
+               case 0x120: /* Modem VGDAC values */
+                       outdoor_pdi = hermes_find_pdi(first_pdi, record_id + 1);
+                       default_pdi = NULL;
+                       if (outdoor_pdi) {
+                               pdi = outdoor_pdi;
+                               printk(KERN_DEBUG PFX
+                                      "Using outdoor record 0x%04x at %p\n",
+                                      record_id + 1, pdi);
+                       }
+                       break;
+               case 0x5: /*  HWIF Compatiblity */
+                       default_pdi = (struct pdi *) &DEFAULT_PDR(0x0005);
+                       break;
+               case 0x108: /* PPPPSign */
+                       default_pdi = (struct pdi *) &DEFAULT_PDR(0x0108);
+                       break;
+               case 0x109: /* PPPPProf */
+                       default_pdi = (struct pdi *) &DEFAULT_PDR(0x0109);
+                       break;
+               case 0x150: /* Antenna diversity */
+                       default_pdi = (struct pdi *) &DEFAULT_PDR(0x0150);
+                       break;
+               case 0x160: /* Modem VCO band Set-up */
+                       default_pdi = (struct pdi *) &DEFAULT_PDR(0x0160);
+                       break;
+               case 0x161: /* Modem Rx Gain Table Values */
+                       default_pdi = (struct pdi *) &DEFAULT_PDR(0x0161);
+                       break;
+               default:
+                       default_pdi = NULL;
+                       break;
+               }
+               if (!pdi && default_pdi) {
+                       /* Use default */
+                       pdi = default_pdi;
+                       printk(KERN_DEBUG PFX
+                              "Using default record 0x%04x at %p\n",
+                              record_id, pdi);
+               }
+
+               if (pdi) {
+                       /* Lengths of the data in PDI and PDR must match */
+                       if (pdi_len(pdi) == pdr_len(pdr)) {
+                               /* do the actual plugging */
+                               hermes_aux_setaddr(hw, pdr_addr(pdr));
+                               hermes_write_bytes(hw, HERMES_AUXDATA,
+                                                  pdi->data, pdi_len(pdi));
+                       }
+               }
+
+               pdr++;
+       }
+       return 0;
+}
+EXPORT_SYMBOL(hermes_apply_pda_with_defaults);
diff --git a/drivers/net/wireless/orinoco/hermes_dld.h b/drivers/net/wireless/orinoco/hermes_dld.h
new file mode 100644 (file)
index 0000000..6fcb262
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007, David Kilroy
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.
+ */
+#ifndef _HERMES_DLD_H
+#define _HERMES_DLD_H
+
+#include "hermes.h"
+
+int hermesi_program_init(hermes_t *hw, u32 offset);
+int hermesi_program_end(hermes_t *hw);
+int hermes_program(hermes_t *hw, const char *first_block, const char *end);
+
+int hermes_read_pda(hermes_t *hw,
+                   __le16 *pda,
+                   u32 pda_addr,
+                   u16 pda_len,
+                   int use_eeprom);
+int hermes_apply_pda(hermes_t *hw,
+                    const char *first_pdr,
+                    const __le16 *pda);
+int hermes_apply_pda_with_defaults(hermes_t *hw,
+                                  const char *first_pdr,
+                                  const __le16 *pda);
+
+size_t hermes_blocks_length(const char *first_block);
+
+#endif /* _HERMES_DLD_H */
diff --git a/drivers/net/wireless/orinoco/hermes_rid.h b/drivers/net/wireless/orinoco/hermes_rid.h
new file mode 100644 (file)
index 0000000..42eb67d
--- /dev/null
@@ -0,0 +1,165 @@
+#ifndef _HERMES_RID_H
+#define _HERMES_RID_H
+
+/*
+ * Configuration RIDs
+ */
+#define HERMES_RID_CNFPORTTYPE                 0xFC00
+#define HERMES_RID_CNFOWNMACADDR               0xFC01
+#define HERMES_RID_CNFDESIREDSSID              0xFC02
+#define HERMES_RID_CNFOWNCHANNEL               0xFC03
+#define HERMES_RID_CNFOWNSSID                  0xFC04
+#define HERMES_RID_CNFOWNATIMWINDOW            0xFC05
+#define HERMES_RID_CNFSYSTEMSCALE              0xFC06
+#define HERMES_RID_CNFMAXDATALEN               0xFC07
+#define HERMES_RID_CNFWDSADDRESS               0xFC08
+#define HERMES_RID_CNFPMENABLED                        0xFC09
+#define HERMES_RID_CNFPMEPS                    0xFC0A
+#define HERMES_RID_CNFMULTICASTRECEIVE         0xFC0B
+#define HERMES_RID_CNFMAXSLEEPDURATION         0xFC0C
+#define HERMES_RID_CNFPMHOLDOVERDURATION       0xFC0D
+#define HERMES_RID_CNFOWNNAME                  0xFC0E
+#define HERMES_RID_CNFOWNDTIMPERIOD            0xFC10
+#define HERMES_RID_CNFWDSADDRESS1              0xFC11
+#define HERMES_RID_CNFWDSADDRESS2              0xFC12
+#define HERMES_RID_CNFWDSADDRESS3              0xFC13
+#define HERMES_RID_CNFWDSADDRESS4              0xFC14
+#define HERMES_RID_CNFWDSADDRESS5              0xFC15
+#define HERMES_RID_CNFWDSADDRESS6              0xFC16
+#define HERMES_RID_CNFMULTICASTPMBUFFERING     0xFC17
+#define HERMES_RID_CNFWEPENABLED_AGERE         0xFC20
+#define HERMES_RID_CNFAUTHENTICATION_AGERE     0xFC21
+#define HERMES_RID_CNFMANDATORYBSSID_SYMBOL    0xFC21
+#define HERMES_RID_CNFDROPUNENCRYPTED          0xFC22
+#define HERMES_RID_CNFWEPDEFAULTKEYID          0xFC23
+#define HERMES_RID_CNFDEFAULTKEY0              0xFC24
+#define HERMES_RID_CNFDEFAULTKEY1              0xFC25
+#define HERMES_RID_CNFMWOROBUST_AGERE          0xFC25
+#define HERMES_RID_CNFDEFAULTKEY2              0xFC26
+#define HERMES_RID_CNFDEFAULTKEY3              0xFC27
+#define HERMES_RID_CNFWEPFLAGS_INTERSIL                0xFC28
+#define HERMES_RID_CNFWEPKEYMAPPINGTABLE       0xFC29
+#define HERMES_RID_CNFAUTHENTICATION           0xFC2A
+#define HERMES_RID_CNFMAXASSOCSTA              0xFC2B
+#define        HERMES_RID_CNFKEYLENGTH_SYMBOL          0xFC2B
+#define HERMES_RID_CNFTXCONTROL                        0xFC2C
+#define HERMES_RID_CNFROAMINGMODE              0xFC2D
+#define HERMES_RID_CNFHOSTAUTHENTICATION       0xFC2E
+#define HERMES_RID_CNFRCVCRCERROR              0xFC30
+#define HERMES_RID_CNFMMLIFE                   0xFC31
+#define HERMES_RID_CNFALTRETRYCOUNT            0xFC32
+#define HERMES_RID_CNFBEACONINT                        0xFC33
+#define HERMES_RID_CNFAPPCFINFO                        0xFC34
+#define HERMES_RID_CNFSTAPCFINFO               0xFC35
+#define HERMES_RID_CNFPRIORITYQUSAGE           0xFC37
+#define HERMES_RID_CNFTIMCTRL                  0xFC40
+#define HERMES_RID_CNFTHIRTY2TALLY             0xFC42
+#define HERMES_RID_CNFENHSECURITY              0xFC43
+#define HERMES_RID_CNFGROUPADDRESSES           0xFC80
+#define HERMES_RID_CNFCREATEIBSS               0xFC81
+#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD   0xFC82
+#define HERMES_RID_CNFRTSTHRESHOLD             0xFC83
+#define HERMES_RID_CNFTXRATECONTROL            0xFC84
+#define HERMES_RID_CNFPROMISCUOUSMODE          0xFC85
+#define HERMES_RID_CNFBASICRATES_SYMBOL                0xFC8A
+#define HERMES_RID_CNFPREAMBLE_SYMBOL          0xFC8C
+#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD0  0xFC90
+#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD1  0xFC91
+#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD2  0xFC92
+#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD3  0xFC93
+#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD4  0xFC94
+#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD5  0xFC95
+#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD6  0xFC96
+#define HERMES_RID_CNFRTSTHRESHOLD0            0xFC97
+#define HERMES_RID_CNFRTSTHRESHOLD1            0xFC98
+#define HERMES_RID_CNFRTSTHRESHOLD2            0xFC99
+#define HERMES_RID_CNFRTSTHRESHOLD3            0xFC9A
+#define HERMES_RID_CNFRTSTHRESHOLD4            0xFC9B
+#define HERMES_RID_CNFRTSTHRESHOLD5            0xFC9C
+#define HERMES_RID_CNFRTSTHRESHOLD6            0xFC9D
+#define HERMES_RID_CNFHOSTSCAN_SYMBOL          0xFCAB
+#define HERMES_RID_CNFSHORTPREAMBLE            0xFCB0
+#define HERMES_RID_CNFWEPKEYS_AGERE            0xFCB0
+#define HERMES_RID_CNFEXCLUDELONGPREAMBLE      0xFCB1
+#define HERMES_RID_CNFTXKEY_AGERE              0xFCB1
+#define HERMES_RID_CNFAUTHENTICATIONRSPTO      0xFCB2
+#define HERMES_RID_CNFSCANSSID_AGERE           0xFCB2
+#define HERMES_RID_CNFBASICRATES               0xFCB3
+#define HERMES_RID_CNFSUPPORTEDRATES           0xFCB4
+#define HERMES_RID_CNFADDDEFAULTTKIPKEY_AGERE  0xFCB4
+#define HERMES_RID_CNFSETWPAAUTHMGMTSUITE_AGERE        0xFCB5
+#define HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE  0xFCB6
+#define HERMES_RID_CNFADDMAPPEDTKIPKEY_AGERE   0xFCB7
+#define HERMES_RID_CNFREMMAPPEDTKIPKEY_AGERE   0xFCB8
+#define HERMES_RID_CNFSETWPACAPABILITIES_AGERE 0xFCB9
+#define HERMES_RID_CNFCACHEDPMKADDRESS         0xFCBA
+#define HERMES_RID_CNFREMOVEPMKADDRESS         0xFCBB
+#define HERMES_RID_CNFSCANCHANNELS2GHZ         0xFCC2
+#define HERMES_RID_CNFDISASSOCIATE             0xFCC8
+#define HERMES_RID_CNFTICKTIME                 0xFCE0
+#define HERMES_RID_CNFSCANREQUEST              0xFCE1
+#define HERMES_RID_CNFJOINREQUEST              0xFCE2
+#define HERMES_RID_CNFAUTHENTICATESTATION      0xFCE3
+#define HERMES_RID_CNFCHANNELINFOREQUEST       0xFCE4
+#define HERMES_RID_CNFHOSTSCAN                 0xFCE5
+
+/*
+ * Information RIDs
+ */
+#define HERMES_RID_MAXLOADTIME                 0xFD00
+#define HERMES_RID_DOWNLOADBUFFER              0xFD01
+#define HERMES_RID_PRIID                       0xFD02
+#define HERMES_RID_PRISUPRANGE                 0xFD03
+#define HERMES_RID_CFIACTRANGES                        0xFD04
+#define HERMES_RID_NICSERNUM                   0xFD0A
+#define HERMES_RID_NICID                       0xFD0B
+#define HERMES_RID_MFISUPRANGE                 0xFD0C
+#define HERMES_RID_CFISUPRANGE                 0xFD0D
+#define HERMES_RID_CHANNELLIST                 0xFD10
+#define HERMES_RID_REGULATORYDOMAINS           0xFD11
+#define HERMES_RID_TEMPTYPE                    0xFD12
+#define HERMES_RID_CIS                         0xFD13
+#define HERMES_RID_STAID                       0xFD20
+#define HERMES_RID_STASUPRANGE                 0xFD21
+#define HERMES_RID_MFIACTRANGES                        0xFD22
+#define HERMES_RID_CFIACTRANGES2               0xFD23
+#define HERMES_RID_SECONDARYVERSION_SYMBOL     0xFD24
+#define HERMES_RID_PORTSTATUS                  0xFD40
+#define HERMES_RID_CURRENTSSID                 0xFD41
+#define HERMES_RID_CURRENTBSSID                        0xFD42
+#define HERMES_RID_COMMSQUALITY                        0xFD43
+#define HERMES_RID_CURRENTTXRATE               0xFD44
+#define HERMES_RID_CURRENTBEACONINTERVAL       0xFD45
+#define HERMES_RID_CURRENTSCALETHRESHOLDS      0xFD46
+#define HERMES_RID_PROTOCOLRSPTIME             0xFD47
+#define HERMES_RID_SHORTRETRYLIMIT             0xFD48
+#define HERMES_RID_LONGRETRYLIMIT              0xFD49
+#define HERMES_RID_MAXTRANSMITLIFETIME         0xFD4A
+#define HERMES_RID_MAXRECEIVELIFETIME          0xFD4B
+#define HERMES_RID_CFPOLLABLE                  0xFD4C
+#define HERMES_RID_AUTHENTICATIONALGORITHMS    0xFD4D
+#define HERMES_RID_PRIVACYOPTIONIMPLEMENTED    0xFD4F
+#define HERMES_RID_DBMCOMMSQUALITY_INTERSIL    0xFD51
+#define HERMES_RID_CURRENTTXRATE1              0xFD80
+#define HERMES_RID_CURRENTTXRATE2              0xFD81
+#define HERMES_RID_CURRENTTXRATE3              0xFD82
+#define HERMES_RID_CURRENTTXRATE4              0xFD83
+#define HERMES_RID_CURRENTTXRATE5              0xFD84
+#define HERMES_RID_CURRENTTXRATE6              0xFD85
+#define HERMES_RID_OWNMACADDR                  0xFD86
+#define HERMES_RID_SCANRESULTSTABLE            0xFD88
+#define HERMES_RID_CURRENT_COUNTRY_INFO                0xFD89
+#define HERMES_RID_CURRENT_WPA_IE              0xFD8A
+#define HERMES_RID_CURRENT_TKIP_IV             0xFD8B
+#define HERMES_RID_CURRENT_ASSOC_REQ_INFO      0xFD8C
+#define HERMES_RID_CURRENT_ASSOC_RESP_INFO     0xFD8D
+#define HERMES_RID_TXQUEUEEMPTY                        0xFD91
+#define HERMES_RID_PHYTYPE                     0xFDC0
+#define HERMES_RID_CURRENTCHANNEL              0xFDC1
+#define HERMES_RID_CURRENTPOWERSTATE           0xFDC2
+#define HERMES_RID_CCAMODE                     0xFDC3
+#define HERMES_RID_SUPPORTEDDATARATES          0xFDC6
+#define HERMES_RID_BUILDSEQ                    0xFFFE
+#define HERMES_RID_FWID                                0xFFFF
+
+#endif
diff --git a/drivers/net/wireless/orinoco/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c
new file mode 100644 (file)
index 0000000..072be44
--- /dev/null
@@ -0,0 +1,6032 @@
+/* orinoco.c - (formerly known as dldwd_cs.c and orinoco_cs.c)
+ *
+ * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
+ * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
+ *
+ * Current maintainers (as of 29 September 2003) are:
+ *     Pavel Roskin <proski AT gnu.org>
+ * and David Gibson <hermes AT gibson.dropbear.id.au>
+ *
+ * (C) Copyright David Gibson, IBM Corporation 2001-2003.
+ * Copyright (C) 2000 David Gibson, Linuxcare Australia.
+ *     With some help from :
+ * Copyright (C) 2001 Jean Tourrilhes, HP Labs
+ * Copyright (C) 2001 Benjamin Herrenschmidt
+ *
+ * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
+ *
+ * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy
+ * AT fasta.fh-dortmund.de>
+ *      http://www.stud.fh-dortmund.de/~andy/wvlan/
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dahinds AT users.sourceforge.net>.  Portions created by David
+ * A. Hinds are Copyright (C) 1999 David A. Hinds.  All Rights
+ * Reserved.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.  */
+
+/*
+ * TODO
+ *     o Handle de-encapsulation within network layer, provide 802.11
+ *       headers (patch from Thomas 'Dent' Mirlacher)
+ *     o Fix possible races in SPY handling.
+ *     o Disconnect wireless extensions from fundamental configuration.
+ *     o (maybe) Software WEP support (patch from Stano Meduna).
+ *     o (maybe) Use multiple Tx buffers - driver handling queue
+ *       rather than firmware.
+ */
+
+/* Locking and synchronization:
+ *
+ * The basic principle is that everything is serialized through a
+ * single spinlock, priv->lock.  The lock is used in user, bh and irq
+ * context, so when taken outside hardirq context it should always be
+ * taken with interrupts disabled.  The lock protects both the
+ * hardware and the struct orinoco_private.
+ *
+ * Another flag, priv->hw_unavailable indicates that the hardware is
+ * unavailable for an extended period of time (e.g. suspended, or in
+ * the middle of a hard reset).  This flag is protected by the
+ * spinlock.  All code which touches the hardware should check the
+ * flag after taking the lock, and if it is set, give up on whatever
+ * they are doing and drop the lock again.  The orinoco_lock()
+ * function handles this (it unlocks and returns -EBUSY if
+ * hw_unavailable is non-zero).
+ */
+
+#define DRIVER_NAME "orinoco"
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/firmware.h>
+#include <linux/if_arp.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <net/iw_handler.h>
+
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
+
+#include "hermes_rid.h"
+#include "hermes_dld.h"
+#include "orinoco.h"
+
+/********************************************************************/
+/* Module information                                               */
+/********************************************************************/
+
+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
+MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
+MODULE_LICENSE("Dual MPL/GPL");
+
+/* Level of debugging. Used in the macros in orinoco.h */
+#ifdef ORINOCO_DEBUG
+int orinoco_debug = ORINOCO_DEBUG;
+module_param(orinoco_debug, int, 0644);
+MODULE_PARM_DESC(orinoco_debug, "Debug level");
+EXPORT_SYMBOL(orinoco_debug);
+#endif
+
+static int suppress_linkstatus; /* = 0 */
+module_param(suppress_linkstatus, bool, 0644);
+MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
+static int ignore_disconnect; /* = 0 */
+module_param(ignore_disconnect, int, 0644);
+MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer");
+
+static int force_monitor; /* = 0 */
+module_param(force_monitor, int, 0644);
+MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
+
+/********************************************************************/
+/* Compile time configuration and compatibility stuff               */
+/********************************************************************/
+
+/* We do this this way to avoid ifdefs in the actual code */
+#ifdef WIRELESS_SPY
+#define SPY_NUMBER(priv)       (priv->spy_data.spy_number)
+#else
+#define SPY_NUMBER(priv)       0
+#endif /* WIRELESS_SPY */
+
+/********************************************************************/
+/* Internal constants                                               */
+/********************************************************************/
+
+/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
+static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+#define ENCAPS_OVERHEAD                (sizeof(encaps_hdr) + 2)
+
+#define ORINOCO_MIN_MTU                256
+#define ORINOCO_MAX_MTU                (IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD)
+
+#define SYMBOL_MAX_VER_LEN     (14)
+#define USER_BAP               0
+#define IRQ_BAP                        1
+#define MAX_IRQLOOPS_PER_IRQ   10
+#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of
+                                           * how many events the
+                                           * device could
+                                           * legitimately generate */
+#define SMALL_KEY_SIZE         5
+#define LARGE_KEY_SIZE         13
+#define TX_NICBUF_SIZE_BUG     1585            /* Bug in Symbol firmware */
+
+#define DUMMY_FID              0xFFFF
+
+/*#define MAX_MULTICAST(priv)  (priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
+  HERMES_MAX_MULTICAST : 0)*/
+#define MAX_MULTICAST(priv)    (HERMES_MAX_MULTICAST)
+
+#define ORINOCO_INTEN          (HERMES_EV_RX | HERMES_EV_ALLOC \
+                                | HERMES_EV_TX | HERMES_EV_TXEXC \
+                                | HERMES_EV_WTERR | HERMES_EV_INFO \
+                                | HERMES_EV_INFDROP )
+
+#define MAX_RID_LEN 1024
+
+static const struct iw_handler_def orinoco_handler_def;
+static const struct ethtool_ops orinoco_ethtool_ops;
+
+/********************************************************************/
+/* Data tables                                                      */
+/********************************************************************/
+
+/* The frequency of each channel in MHz */
+static const long channel_frequency[] = {
+       2412, 2417, 2422, 2427, 2432, 2437, 2442,
+       2447, 2452, 2457, 2462, 2467, 2472, 2484
+};
+#define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
+
+/* This tables gives the actual meanings of the bitrate IDs returned
+ * by the firmware. */
+static struct {
+       int bitrate; /* in 100s of kilobits */
+       int automatic;
+       u16 agere_txratectrl;
+       u16 intersil_txratectrl;
+} bitrate_table[] = {
+       {110, 1,  3, 15}, /* Entry 0 is the default */
+       {10,  0,  1,  1},
+       {10,  1,  1,  1},
+       {20,  0,  2,  2},
+       {20,  1,  6,  3},
+       {55,  0,  4,  4},
+       {55,  1,  7,  7},
+       {110, 0,  5,  8},
+};
+#define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
+
+/********************************************************************/
+/* Data types                                                       */
+/********************************************************************/
+
+/* Beginning of the Tx descriptor, used in TxExc handling */
+struct hermes_txexc_data {
+       struct hermes_tx_descriptor desc;
+       __le16 frame_ctl;
+       __le16 duration_id;
+       u8 addr1[ETH_ALEN];
+} __attribute__ ((packed));
+
+/* Rx frame header except compatibility 802.3 header */
+struct hermes_rx_descriptor {
+       /* Control */
+       __le16 status;
+       __le32 time;
+       u8 silence;
+       u8 signal;
+       u8 rate;
+       u8 rxflow;
+       __le32 reserved;
+
+       /* 802.11 header */
+       __le16 frame_ctl;
+       __le16 duration_id;
+       u8 addr1[ETH_ALEN];
+       u8 addr2[ETH_ALEN];
+       u8 addr3[ETH_ALEN];
+       __le16 seq_ctl;
+       u8 addr4[ETH_ALEN];
+
+       /* Data length */
+       __le16 data_len;
+} __attribute__ ((packed));
+
+/********************************************************************/
+/* Function prototypes                                              */
+/********************************************************************/
+
+static int __orinoco_program_rids(struct net_device *dev);
+static void __orinoco_set_multicast_list(struct net_device *dev);
+
+/********************************************************************/
+/* Michael MIC crypto setup                                         */
+/********************************************************************/
+#define MICHAEL_MIC_LEN 8
+static int orinoco_mic_init(struct orinoco_private *priv)
+{
+       priv->tx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
+       if (IS_ERR(priv->tx_tfm_mic)) {
+               printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
+                      "crypto API michael_mic\n");
+               priv->tx_tfm_mic = NULL;
+               return -ENOMEM;
+       }
+
+       priv->rx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
+       if (IS_ERR(priv->rx_tfm_mic)) {
+               printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
+                      "crypto API michael_mic\n");
+               priv->rx_tfm_mic = NULL;
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static void orinoco_mic_free(struct orinoco_private *priv)
+{
+       if (priv->tx_tfm_mic)
+               crypto_free_hash(priv->tx_tfm_mic);
+       if (priv->rx_tfm_mic)
+               crypto_free_hash(priv->rx_tfm_mic);
+}
+
+static int michael_mic(struct crypto_hash *tfm_michael, u8 *key,
+                      u8 *da, u8 *sa, u8 priority,
+                      u8 *data, size_t data_len, u8 *mic)
+{
+       struct hash_desc desc;
+       struct scatterlist sg[2];
+       u8 hdr[ETH_HLEN + 2]; /* size of header + padding */
+
+       if (tfm_michael == NULL) {
+               printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
+               return -1;
+       }
+
+       /* Copy header into buffer. We need the padding on the end zeroed */
+       memcpy(&hdr[0], da, ETH_ALEN);
+       memcpy(&hdr[ETH_ALEN], sa, ETH_ALEN);
+       hdr[ETH_ALEN*2] = priority;
+       hdr[ETH_ALEN*2+1] = 0;
+       hdr[ETH_ALEN*2+2] = 0;
+       hdr[ETH_ALEN*2+3] = 0;
+
+       /* Use scatter gather to MIC header and data in one go */
+       sg_init_table(sg, 2);
+       sg_set_buf(&sg[0], hdr, sizeof(hdr));
+       sg_set_buf(&sg[1], data, data_len);
+
+       if (crypto_hash_setkey(tfm_michael, key, MIC_KEYLEN))
+               return -1;
+
+       desc.tfm = tfm_michael;
+       desc.flags = 0;
+       return crypto_hash_digest(&desc, sg, data_len + sizeof(hdr),
+                                 mic);
+}
+
+/********************************************************************/
+/* Internal helper functions                                        */
+/********************************************************************/
+
+static inline void set_port_type(struct orinoco_private *priv)
+{
+       switch (priv->iw_mode) {
+       case IW_MODE_INFRA:
+               priv->port_type = 1;
+               priv->createibss = 0;
+               break;
+       case IW_MODE_ADHOC:
+               if (priv->prefer_port3) {
+                       priv->port_type = 3;
+                       priv->createibss = 0;
+               } else {
+                       priv->port_type = priv->ibss_port;
+                       priv->createibss = 1;
+               }
+               break;
+       case IW_MODE_MONITOR:
+               priv->port_type = 3;
+               priv->createibss = 0;
+               break;
+       default:
+               printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
+                      priv->ndev->name);
+       }
+}
+
+#define ORINOCO_MAX_BSS_COUNT  64
+static int orinoco_bss_data_allocate(struct orinoco_private *priv)
+{
+       if (priv->bss_xbss_data)
+               return 0;
+
+       if (priv->has_ext_scan)
+               priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
+                                             sizeof(struct xbss_element),
+                                             GFP_KERNEL);
+       else
+               priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
+                                             sizeof(struct bss_element),
+                                             GFP_KERNEL);
+
+       if (!priv->bss_xbss_data) {
+               printk(KERN_WARNING "Out of memory allocating beacons");
+               return -ENOMEM;
+       }
+       return 0;
+}
+
+static void orinoco_bss_data_free(struct orinoco_private *priv)
+{
+       kfree(priv->bss_xbss_data);
+       priv->bss_xbss_data = NULL;
+}
+
+#define PRIV_BSS       ((struct bss_element *)priv->bss_xbss_data)
+#define PRIV_XBSS      ((struct xbss_element *)priv->bss_xbss_data)
+static void orinoco_bss_data_init(struct orinoco_private *priv)
+{
+       int i;
+
+       INIT_LIST_HEAD(&priv->bss_free_list);
+       INIT_LIST_HEAD(&priv->bss_list);
+       if (priv->has_ext_scan)
+               for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
+                       list_add_tail(&(PRIV_XBSS[i].list),
+                                     &priv->bss_free_list);
+       else
+               for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
+                       list_add_tail(&(PRIV_BSS[i].list),
+                                     &priv->bss_free_list);
+
+}
+
+static inline u8 *orinoco_get_ie(u8 *data, size_t len,
+                                enum ieee80211_eid eid)
+{
+       u8 *p = data;
+       while ((p + 2) < (data + len)) {
+               if (p[0] == eid)
+                       return p;
+               p += p[1] + 2;
+       }
+       return NULL;
+}
+
+#define WPA_OUI_TYPE   "\x00\x50\xF2\x01"
+#define WPA_SELECTOR_LEN 4
+static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len)
+{
+       u8 *p = data;
+       while ((p + 2 + WPA_SELECTOR_LEN) < (data + len)) {
+               if ((p[0] == WLAN_EID_GENERIC) &&
+                   (memcmp(&p[2], WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0))
+                       return p;
+               p += p[1] + 2;
+       }
+       return NULL;
+}
+
+
+/********************************************************************/
+/* Download functionality                                           */
+/********************************************************************/
+
+struct fw_info {
+       char *pri_fw;
+       char *sta_fw;
+       char *ap_fw;
+       u32 pda_addr;
+       u16 pda_size;
+};
+
+const static struct fw_info orinoco_fw[] = {
+       { "", "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 },
+       { "", "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 },
+       { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", "", 0x00003100, 512 }
+};
+
+/* Structure used to access fields in FW
+ * Make sure LE decoding macros are used
+ */
+struct orinoco_fw_header {
+       char hdr_vers[6];       /* ASCII string for header version */
+       __le16 headersize;      /* Total length of header */
+       __le32 entry_point;     /* NIC entry point */
+       __le32 blocks;          /* Number of blocks to program */
+       __le32 block_offset;    /* Offset of block data from eof header */
+       __le32 pdr_offset;      /* Offset to PDR data from eof header */
+       __le32 pri_offset;      /* Offset to primary plug data */
+       __le32 compat_offset;   /* Offset to compatibility data*/
+       char signature[0];      /* FW signature length headersize-20 */
+} __attribute__ ((packed));
+
+/* Download either STA or AP firmware into the card. */
+static int
+orinoco_dl_firmware(struct orinoco_private *priv,
+                   const struct fw_info *fw,
+                   int ap)
+{
+       /* Plug Data Area (PDA) */
+       __le16 *pda;
+
+       hermes_t *hw = &priv->hw;
+       const struct firmware *fw_entry;
+       const struct orinoco_fw_header *hdr;
+       const unsigned char *first_block;
+       const unsigned char *end;
+       const char *firmware;
+       struct net_device *dev = priv->ndev;
+       int err = 0;
+
+       pda = kzalloc(fw->pda_size, GFP_KERNEL);
+       if (!pda)
+               return -ENOMEM;
+
+       if (ap)
+               firmware = fw->ap_fw;
+       else
+               firmware = fw->sta_fw;
+
+       printk(KERN_DEBUG "%s: Attempting to download firmware %s\n",
+              dev->name, firmware);
+
+       /* Read current plug data */
+       err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
+       printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
+       if (err)
+               goto free;
+
+       if (priv->cached_fw)
+               fw_entry = priv->cached_fw;
+       else {
+               err = request_firmware(&fw_entry, firmware, priv->dev);
+               if (err) {
+                       printk(KERN_ERR "%s: Cannot find firmware %s\n",
+                              dev->name, firmware);
+                       err = -ENOENT;
+                       goto free;
+               }
+               priv->cached_fw = fw_entry;
+       }
+
+       hdr = (const struct orinoco_fw_header *) fw_entry->data;
+
+       /* Enable aux port to allow programming */
+       err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
+       printk(KERN_DEBUG "%s: Program init returned %d\n", dev->name, err);
+       if (err != 0)
+               goto abort;
+
+       /* Program data */
+       first_block = (fw_entry->data +
+                      le16_to_cpu(hdr->headersize) +
+                      le32_to_cpu(hdr->block_offset));
+       end = fw_entry->data + fw_entry->size;
+
+       err = hermes_program(hw, first_block, end);
+       printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
+       if (err != 0)
+               goto abort;
+
+       /* Update production data */
+       first_block = (fw_entry->data +
+                      le16_to_cpu(hdr->headersize) +
+                      le32_to_cpu(hdr->pdr_offset));
+
+       err = hermes_apply_pda_with_defaults(hw, first_block, pda);
+       printk(KERN_DEBUG "%s: Apply PDA returned %d\n", dev->name, err);
+       if (err)
+               goto abort;
+
+       /* Tell card we've finished */
+       err = hermesi_program_end(hw);
+       printk(KERN_DEBUG "%s: Program end returned %d\n", dev->name, err);
+       if (err != 0)
+               goto abort;
+
+       /* Check if we're running */
+       printk(KERN_DEBUG "%s: hermes_present returned %d\n",
+              dev->name, hermes_present(hw));
+
+abort:
+       /* In case of error, assume firmware was bogus and release it */
+       if (err) {
+               priv->cached_fw = NULL;
+               release_firmware(fw_entry);
+       }
+
+free:
+       kfree(pda);
+       return err;
+}
+
+/* End markers */
+#define TEXT_END       0x1A            /* End of text header */
+
+/*
+ * Process a firmware image - stop the card, load the firmware, reset
+ * the card and make sure it responds.  For the secondary firmware take
+ * care of the PDA - read it and then write it on top of the firmware.
+ */
+static int
+symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
+               const unsigned char *image, const unsigned char *end,
+               int secondary)
+{
+       hermes_t *hw = &priv->hw;
+       int ret = 0;
+       const unsigned char *ptr;
+       const unsigned char *first_block;
+
+       /* Plug Data Area (PDA) */
+       __le16 *pda = NULL;
+
+       /* Binary block begins after the 0x1A marker */
+       ptr = image;
+       while (*ptr++ != TEXT_END);
+       first_block = ptr;
+
+       /* Read the PDA from EEPROM */
+       if (secondary) {
+               pda = kzalloc(fw->pda_size, GFP_KERNEL);
+               if (!pda)
+                       return -ENOMEM;
+
+               ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1);
+               if (ret)
+                       goto free;
+       }
+
+       /* Stop the firmware, so that it can be safely rewritten */
+       if (priv->stop_fw) {
+               ret = priv->stop_fw(priv, 1);
+               if (ret)
+                       goto free;
+       }
+
+       /* Program the adapter with new firmware */
+       ret = hermes_program(hw, first_block, end);
+       if (ret)
+               goto free;
+
+       /* Write the PDA to the adapter */
+       if (secondary) {
+               size_t len = hermes_blocks_length(first_block);
+               ptr = first_block + len;
+               ret = hermes_apply_pda(hw, ptr, pda);
+               kfree(pda);
+               if (ret)
+                       return ret;
+       }
+
+       /* Run the firmware */
+       if (priv->stop_fw) {
+               ret = priv->stop_fw(priv, 0);
+               if (ret)
+                       return ret;
+       }
+
+       /* Reset hermes chip and make sure it responds */
+       ret = hermes_init(hw);
+
+       /* hermes_reset() should return 0 with the secondary firmware */
+       if (secondary && ret != 0)
+               return -ENODEV;
+
+       /* And this should work with any firmware */
+       if (!hermes_present(hw))
+               return -ENODEV;
+
+       return 0;
+
+free:
+       kfree(pda);
+       return ret;
+}
+
+
+/*
+ * Download the firmware into the card, this also does a PCMCIA soft
+ * reset on the card, to make sure it's in a sane state.
+ */
+static int
+symbol_dl_firmware(struct orinoco_private *priv,
+                  const struct fw_info *fw)
+{
+       struct net_device *dev = priv->ndev;
+       int ret;
+       const struct firmware *fw_entry;
+
+       if (request_firmware(&fw_entry, fw->pri_fw,
+                            priv->dev) != 0) {
+               printk(KERN_ERR "%s: Cannot find firmware: %s\n",
+                      dev->name, fw->pri_fw);
+               return -ENOENT;
+       }
+
+       /* Load primary firmware */
+       ret = symbol_dl_image(priv, fw, fw_entry->data,
+                             fw_entry->data + fw_entry->size, 0);
+       release_firmware(fw_entry);
+       if (ret) {
+               printk(KERN_ERR "%s: Primary firmware download failed\n",
+                      dev->name);
+               return ret;
+       }
+
+       if (request_firmware(&fw_entry, fw->sta_fw,
+                            priv->dev) != 0) {
+               printk(KERN_ERR "%s: Cannot find firmware: %s\n",
+                      dev->name, fw->sta_fw);
+               return -ENOENT;
+       }
+
+       /* Load secondary firmware */
+       ret = symbol_dl_image(priv, fw, fw_entry->data,
+                             fw_entry->data + fw_entry->size, 1);
+       release_firmware(fw_entry);
+       if (ret) {
+               printk(KERN_ERR "%s: Secondary firmware download failed\n",
+                      dev->name);
+       }
+
+       return ret;
+}
+
+static int orinoco_download(struct orinoco_private *priv)
+{
+       int err = 0;
+       /* Reload firmware */
+       switch (priv->firmware_type) {
+       case FIRMWARE_TYPE_AGERE:
+               /* case FIRMWARE_TYPE_INTERSIL: */
+               err = orinoco_dl_firmware(priv,
+                                         &orinoco_fw[priv->firmware_type], 0);
+               break;
+
+       case FIRMWARE_TYPE_SYMBOL:
+               err = symbol_dl_firmware(priv,
+                                        &orinoco_fw[priv->firmware_type]);
+               break;
+       case FIRMWARE_TYPE_INTERSIL:
+               break;
+       }
+       /* TODO: if we fail we probably need to reinitialise
+        * the driver */
+
+       return err;
+}
+
+/********************************************************************/
+/* Device methods                                                   */
+/********************************************************************/
+
+static int orinoco_open(struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
+       int err;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       err = __orinoco_up(dev);
+
+       if (! err)
+               priv->open = 1;
+
+       orinoco_unlock(priv, &flags);
+
+       return err;
+}
+
+static int orinoco_stop(struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int err = 0;
+
+       /* We mustn't use orinoco_lock() here, because we need to be
+          able to close the interface even if hw_unavailable is set
+          (e.g. as we're released after a PC Card removal) */
+       spin_lock_irq(&priv->lock);
+
+       priv->open = 0;
+
+       err = __orinoco_down(dev);
+
+       spin_unlock_irq(&priv->lock);
+
+       return err;
+}
+
+static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       
+       return &priv->stats;
+}
+
+static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       hermes_t *hw = &priv->hw;
+       struct iw_statistics *wstats = &priv->wstats;
+       int err;
+       unsigned long flags;
+
+       if (! netif_device_present(dev)) {
+               printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
+                      dev->name);
+               return NULL; /* FIXME: Can we do better than this? */
+       }
+
+       /* If busy, return the old stats.  Returning NULL may cause
+        * the interface to disappear from /proc/net/wireless */
+       if (orinoco_lock(priv, &flags) != 0)
+               return wstats;
+
+       /* We can't really wait for the tallies inquiry command to
+        * complete, so we just use the previous results and trigger
+        * a new tallies inquiry command for next time - Jean II */
+       /* FIXME: Really we should wait for the inquiry to come back -
+        * as it is the stats we give don't make a whole lot of sense.
+        * Unfortunately, it's not clear how to do that within the
+        * wireless extensions framework: I think we're in user
+        * context, but a lock seems to be held by the time we get in
+        * here so we're not safe to sleep here. */
+       hermes_inquire(hw, HERMES_INQ_TALLIES);
+
+       if (priv->iw_mode == IW_MODE_ADHOC) {
+               memset(&wstats->qual, 0, sizeof(wstats->qual));
+               /* If a spy address is defined, we report stats of the
+                * first spy address - Jean II */
+               if (SPY_NUMBER(priv)) {
+                       wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
+                       wstats->qual.level = priv->spy_data.spy_stat[0].level;
+                       wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
+                       wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
+               }
+       } else {
+               struct {
+                       __le16 qual, signal, noise, unused;
+               } __attribute__ ((packed)) cq;
+
+               err = HERMES_READ_RECORD(hw, USER_BAP,
+                                        HERMES_RID_COMMSQUALITY, &cq);
+
+               if (!err) {
+                       wstats->qual.qual = (int)le16_to_cpu(cq.qual);
+                       wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
+                       wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
+                       wstats->qual.updated = 7;
+               }
+       }
+
+       orinoco_unlock(priv, &flags);
+       return wstats;
+}
+
+static void orinoco_set_multicast_list(struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0) {
+               printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
+                      "called when hw_unavailable\n", dev->name);
+               return;
+       }
+
+       __orinoco_set_multicast_list(dev);
+       orinoco_unlock(priv, &flags);
+}
+
+static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+
+       if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
+               return -EINVAL;
+
+       /* MTU + encapsulation + header length */
+       if ( (new_mtu + ENCAPS_OVERHEAD + sizeof(struct ieee80211_hdr)) >
+            (priv->nicbuf_size - ETH_HLEN) )
+               return -EINVAL;
+
+       dev->mtu = new_mtu;
+
+       return 0;
+}
+
+/********************************************************************/
+/* Tx path                                                          */
+/********************************************************************/
+
+static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct net_device_stats *stats = &priv->stats;
+       hermes_t *hw = &priv->hw;
+       int err = 0;
+       u16 txfid = priv->txfid;
+       struct ethhdr *eh;
+       int tx_control;
+       unsigned long flags;
+
+       if (! netif_running(dev)) {
+               printk(KERN_ERR "%s: Tx on stopped device!\n",
+                      dev->name);
+               return NETDEV_TX_BUSY;
+       }
+       
+       if (netif_queue_stopped(dev)) {
+               printk(KERN_DEBUG "%s: Tx while transmitter busy!\n", 
+                      dev->name);
+               return NETDEV_TX_BUSY;
+       }
+       
+       if (orinoco_lock(priv, &flags) != 0) {
+               printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
+                      dev->name);
+               return NETDEV_TX_BUSY;
+       }
+
+       if (! netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
+               /* Oops, the firmware hasn't established a connection,
+                   silently drop the packet (this seems to be the
+                   safest approach). */
+               goto drop;
+       }
+
+       /* Check packet length */
+       if (skb->len < ETH_HLEN)
+               goto drop;
+
+       tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
+
+       if (priv->encode_alg == IW_ENCODE_ALG_TKIP)
+               tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
+                       HERMES_TXCTRL_MIC;
+
+       if (priv->has_alt_txcntl) {
+               /* WPA enabled firmwares have tx_cntl at the end of
+                * the 802.11 header.  So write zeroed descriptor and
+                * 802.11 header at the same time
+                */
+               char desc[HERMES_802_3_OFFSET];
+               __le16 *txcntl = (__le16 *) &desc[HERMES_TXCNTL2_OFFSET];
+
+               memset(&desc, 0, sizeof(desc));
+
+               *txcntl = cpu_to_le16(tx_control);
+               err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
+                                       txfid, 0);
+               if (err) {
+                       if (net_ratelimit())
+                               printk(KERN_ERR "%s: Error %d writing Tx "
+                                      "descriptor to BAP\n", dev->name, err);
+                       goto busy;
+               }
+       } else {
+               struct hermes_tx_descriptor desc;
+
+               memset(&desc, 0, sizeof(desc));
+
+               desc.tx_control = cpu_to_le16(tx_control);
+               err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
+                                       txfid, 0);
+               if (err) {
+                       if (net_ratelimit())
+                               printk(KERN_ERR "%s: Error %d writing Tx "
+                                      "descriptor to BAP\n", dev->name, err);
+                       goto busy;
+               }
+
+               /* Clear the 802.11 header and data length fields - some
+                * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
+                * if this isn't done. */
+               hermes_clear_words(hw, HERMES_DATA0,
+                                  HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
+       }
+
+       eh = (struct ethhdr *)skb->data;
+
+       /* Encapsulate Ethernet-II frames */
+       if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
+               struct header_struct {
+                       struct ethhdr eth;      /* 802.3 header */
+                       u8 encap[6];            /* 802.2 header */
+               } __attribute__ ((packed)) hdr;
+
+               /* Strip destination and source from the data */
+               skb_pull(skb, 2 * ETH_ALEN);
+
+               /* And move them to a separate header */
+               memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
+               hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
+               memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
+
+               /* Insert the SNAP header */
+               if (skb_headroom(skb) < sizeof(hdr)) {
+                       printk(KERN_ERR
+                              "%s: Not enough headroom for 802.2 headers %d\n",
+                              dev->name, skb_headroom(skb));
+                       goto drop;
+               }
+               eh = (struct ethhdr *) skb_push(skb, sizeof(hdr));
+               memcpy(eh, &hdr, sizeof(hdr));
+       }
+
+       err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len,
+                               txfid, HERMES_802_3_OFFSET);
+       if (err) {
+               printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
+                      dev->name, err);
+               goto busy;
+       }
+
+       /* Calculate Michael MIC */
+       if (priv->encode_alg == IW_ENCODE_ALG_TKIP) {
+               u8 mic_buf[MICHAEL_MIC_LEN + 1];
+               u8 *mic;
+               size_t offset;
+               size_t len;
+
+               if (skb->len % 2) {
+                       /* MIC start is on an odd boundary */
+                       mic_buf[0] = skb->data[skb->len - 1];
+                       mic = &mic_buf[1];
+                       offset = skb->len - 1;
+                       len = MICHAEL_MIC_LEN + 1;
+               } else {
+                       mic = &mic_buf[0];
+                       offset = skb->len;
+                       len = MICHAEL_MIC_LEN;
+               }
+
+               michael_mic(priv->tx_tfm_mic,
+                           priv->tkip_key[priv->tx_key].tx_mic,
+                           eh->h_dest, eh->h_source, 0 /* priority */,
+                           skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic);
+
+               /* Write the MIC */
+               err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
+                                       txfid, HERMES_802_3_OFFSET + offset);
+               if (err) {
+                       printk(KERN_ERR "%s: Error %d writing MIC to BAP\n",
+                              dev->name, err);
+                       goto busy;
+               }
+       }
+
+       /* Finally, we actually initiate the send */
+       netif_stop_queue(dev);
+
+       err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
+                               txfid, NULL);
+       if (err) {
+               netif_start_queue(dev);
+               if (net_ratelimit())
+                       printk(KERN_ERR "%s: Error %d transmitting packet\n",
+                               dev->name, err);
+               goto busy;
+       }
+
+       dev->trans_start = jiffies;
+       stats->tx_bytes += HERMES_802_3_OFFSET + skb->len;
+       goto ok;
+
+ drop:
+       stats->tx_errors++;
+       stats->tx_dropped++;
+
+ ok:
+       orinoco_unlock(priv, &flags);
+       dev_kfree_skb(skb);
+       return NETDEV_TX_OK;
+
+ busy:
+       if (err == -EIO)
+               schedule_work(&priv->reset_work);
+       orinoco_unlock(priv, &flags);
+       return NETDEV_TX_BUSY;
+}
+
+static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       u16 fid = hermes_read_regn(hw, ALLOCFID);
+
+       if (fid != priv->txfid) {
+               if (fid != DUMMY_FID)
+                       printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
+                              dev->name, fid);
+               return;
+       }
+
+       hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
+}
+
+static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct net_device_stats *stats = &priv->stats;
+
+       stats->tx_packets++;
+
+       netif_wake_queue(dev);
+
+       hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
+}
+
+static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct net_device_stats *stats = &priv->stats;
+       u16 fid = hermes_read_regn(hw, TXCOMPLFID);
+       u16 status;
+       struct hermes_txexc_data hdr;
+       int err = 0;
+
+       if (fid == DUMMY_FID)
+               return; /* Nothing's really happened */
+
+       /* Read part of the frame header - we need status and addr1 */
+       err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
+                              sizeof(struct hermes_txexc_data),
+                              fid, 0);
+
+       hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
+       stats->tx_errors++;
+
+       if (err) {
+               printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
+                      "(FID=%04X error %d)\n",
+                      dev->name, fid, err);
+               return;
+       }
+       
+       DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name,
+             err, fid);
+    
+       /* We produce a TXDROP event only for retry or lifetime
+        * exceeded, because that's the only status that really mean
+        * that this particular node went away.
+        * Other errors means that *we* screwed up. - Jean II */
+       status = le16_to_cpu(hdr.desc.status);
+       if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
+               union iwreq_data        wrqu;
+
+               /* Copy 802.11 dest address.
+                * We use the 802.11 header because the frame may
+                * not be 802.3 or may be mangled...
+                * In Ad-Hoc mode, it will be the node address.
+                * In managed mode, it will be most likely the AP addr
+                * User space will figure out how to convert it to
+                * whatever it needs (IP address or else).
+                * - Jean II */
+               memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN);
+               wrqu.addr.sa_family = ARPHRD_ETHER;
+
+               /* Send event to user space */
+               wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
+       }
+
+       netif_wake_queue(dev);
+}
+
+static void orinoco_tx_timeout(struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct net_device_stats *stats = &priv->stats;
+       struct hermes *hw = &priv->hw;
+
+       printk(KERN_WARNING "%s: Tx timeout! "
+              "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
+              dev->name, hermes_read_regn(hw, ALLOCFID),
+              hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
+
+       stats->tx_errors++;
+
+       schedule_work(&priv->reset_work);
+}
+
+/********************************************************************/
+/* Rx path (data frames)                                            */
+/********************************************************************/
+
+/* Does the frame have a SNAP header indicating it should be
+ * de-encapsulated to Ethernet-II? */
+static inline int is_ethersnap(void *_hdr)
+{
+       u8 *hdr = _hdr;
+
+       /* We de-encapsulate all packets which, a) have SNAP headers
+        * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
+        * and where b) the OUI of the SNAP header is 00:00:00 or
+        * 00:00:f8 - we need both because different APs appear to use
+        * different OUIs for some reason */
+       return (memcmp(hdr, &encaps_hdr, 5) == 0)
+               && ( (hdr[5] == 0x00) || (hdr[5] == 0xf8) );
+}
+
+static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
+                                     int level, int noise)
+{
+       struct iw_quality wstats;
+       wstats.level = level - 0x95;
+       wstats.noise = noise - 0x95;
+       wstats.qual = (level > noise) ? (level - noise) : 0;
+       wstats.updated = 7;
+       /* Update spy records */
+       wireless_spy_update(dev, mac, &wstats);
+}
+
+static void orinoco_stat_gather(struct net_device *dev,
+                               struct sk_buff *skb,
+                               struct hermes_rx_descriptor *desc)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+
+       /* Using spy support with lots of Rx packets, like in an
+        * infrastructure (AP), will really slow down everything, because
+        * the MAC address must be compared to each entry of the spy list.
+        * If the user really asks for it (set some address in the
+        * spy list), we do it, but he will pay the price.
+        * Note that to get here, you need both WIRELESS_SPY
+        * compiled in AND some addresses in the list !!!
+        */
+       /* Note : gcc will optimise the whole section away if
+        * WIRELESS_SPY is not defined... - Jean II */
+       if (SPY_NUMBER(priv)) {
+               orinoco_spy_gather(dev, skb_mac_header(skb) + ETH_ALEN,
+                                  desc->signal, desc->silence);
+       }
+}
+
+/*
+ * orinoco_rx_monitor - handle received monitor frames.
+ *
+ * Arguments:
+ *     dev             network device
+ *     rxfid           received FID
+ *     desc            rx descriptor of the frame
+ *
+ * Call context: interrupt
+ */
+static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
+                              struct hermes_rx_descriptor *desc)
+{
+       u32 hdrlen = 30;        /* return full header by default */
+       u32 datalen = 0;
+       u16 fc;
+       int err;
+       int len;
+       struct sk_buff *skb;
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct net_device_stats *stats = &priv->stats;
+       hermes_t *hw = &priv->hw;
+
+       len = le16_to_cpu(desc->data_len);
+
+       /* Determine the size of the header and the data */
+       fc = le16_to_cpu(desc->frame_ctl);
+       switch (fc & IEEE80211_FCTL_FTYPE) {
+       case IEEE80211_FTYPE_DATA:
+               if ((fc & IEEE80211_FCTL_TODS)
+                   && (fc & IEEE80211_FCTL_FROMDS))
+                       hdrlen = 30;
+               else
+                       hdrlen = 24;
+               datalen = len;
+               break;
+       case IEEE80211_FTYPE_MGMT:
+               hdrlen = 24;
+               datalen = len;
+               break;
+       case IEEE80211_FTYPE_CTL:
+               switch (fc & IEEE80211_FCTL_STYPE) {
+               case IEEE80211_STYPE_PSPOLL:
+               case IEEE80211_STYPE_RTS:
+               case IEEE80211_STYPE_CFEND:
+               case IEEE80211_STYPE_CFENDACK:
+                       hdrlen = 16;
+                       break;
+               case IEEE80211_STYPE_CTS:
+               case IEEE80211_STYPE_ACK:
+                       hdrlen = 10;
+                       break;
+               }
+               break;
+       default:
+               /* Unknown frame type */
+               break;
+       }
+
+       /* sanity check the length */
+       if (datalen > IEEE80211_MAX_DATA_LEN + 12) {
+               printk(KERN_DEBUG "%s: oversized monitor frame, "
+                      "data length = %d\n", dev->name, datalen);
+               stats->rx_length_errors++;
+               goto update_stats;
+       }
+
+       skb = dev_alloc_skb(hdrlen + datalen);
+       if (!skb) {
+               printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
+                      dev->name);
+               goto update_stats;
+       }
+
+       /* Copy the 802.11 header to the skb */
+       memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
+       skb_reset_mac_header(skb);
+
+       /* If any, copy the data from the card to the skb */
+       if (datalen > 0) {
+               err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
+                                      ALIGN(datalen, 2), rxfid,
+                                      HERMES_802_2_OFFSET);
+               if (err) {
+                       printk(KERN_ERR "%s: error %d reading monitor frame\n",
+                              dev->name, err);
+                       goto drop;
+               }
+       }
+
+       skb->dev = dev;
+       skb->ip_summed = CHECKSUM_NONE;
+       skb->pkt_type = PACKET_OTHERHOST;
+       skb->protocol = __constant_htons(ETH_P_802_2);
+       
+       stats->rx_packets++;
+       stats->rx_bytes += skb->len;
+
+       netif_rx(skb);
+       return;
+
+ drop:
+       dev_kfree_skb_irq(skb);
+ update_stats:
+       stats->rx_errors++;
+       stats->rx_dropped++;
+}
+
+/* Get tsc from the firmware */
+static int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key,
+                                 u8 *tsc)
+{
+       hermes_t *hw = &priv->hw;
+       int err = 0;
+       u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE];
+
+       if ((key < 0) || (key > 4))
+               return -EINVAL;
+
+       err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV,
+                             sizeof(tsc_arr), NULL, &tsc_arr);
+       if (!err)
+               memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0]));
+
+       return err;
+}
+
+static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct net_device_stats *stats = &priv->stats;
+       struct iw_statistics *wstats = &priv->wstats;
+       struct sk_buff *skb = NULL;
+       u16 rxfid, status;
+       int length;
+       struct hermes_rx_descriptor *desc;
+       struct orinoco_rx_data *rx_data;
+       int err;
+
+       desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
+       if (!desc) {
+               printk(KERN_WARNING
+                      "%s: Can't allocate space for RX descriptor\n",
+                      dev->name);
+               goto update_stats;
+       }
+
+       rxfid = hermes_read_regn(hw, RXFID);
+
+       err = hermes_bap_pread(hw, IRQ_BAP, desc, sizeof(*desc),
+                              rxfid, 0);
+       if (err) {
+               printk(KERN_ERR "%s: error %d reading Rx descriptor. "
+                      "Frame dropped.\n", dev->name, err);
+               goto update_stats;
+       }
+
+       status = le16_to_cpu(desc->status);
+
+       if (status & HERMES_RXSTAT_BADCRC) {
+               DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n",
+                     dev->name);
+               stats->rx_crc_errors++;
+               goto update_stats;
+       }
+
+       /* Handle frames in monitor mode */
+       if (priv->iw_mode == IW_MODE_MONITOR) {
+               orinoco_rx_monitor(dev, rxfid, desc);
+               goto out;
+       }
+
+       if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
+               DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
+                     dev->name);
+               wstats->discard.code++;
+               goto update_stats;
+       }
+
+       length = le16_to_cpu(desc->data_len);
+
+       /* Sanity checks */
+       if (length < 3) { /* No for even an 802.2 LLC header */
+               /* At least on Symbol firmware with PCF we get quite a
+                   lot of these legitimately - Poll frames with no
+                   data. */
+               goto out;
+       }
+       if (length > IEEE80211_MAX_DATA_LEN) {
+               printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
+                      dev->name, length);
+               stats->rx_length_errors++;
+               goto update_stats;
+       }
+
+       /* Payload size does not include Michael MIC. Increase payload
+        * size to read it together with the data. */
+       if (status & HERMES_RXSTAT_MIC)
+               length += MICHAEL_MIC_LEN;
+
+       /* We need space for the packet data itself, plus an ethernet
+          header, plus 2 bytes so we can align the IP header on a
+          32bit boundary, plus 1 byte so we can read in odd length
+          packets from the card, which has an IO granularity of 16
+          bits */  
+       skb = dev_alloc_skb(length+ETH_HLEN+2+1);
+       if (!skb) {
+               printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
+                      dev->name);
+               goto update_stats;
+       }
+
+       /* We'll prepend the header, so reserve space for it.  The worst
+          case is no decapsulation, when 802.3 header is prepended and
+          nothing is removed.  2 is for aligning the IP header.  */
+       skb_reserve(skb, ETH_HLEN + 2);
+
+       err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length),
+                              ALIGN(length, 2), rxfid,
+                              HERMES_802_2_OFFSET);
+       if (err) {
+               printk(KERN_ERR "%s: error %d reading frame. "
+                      "Frame dropped.\n", dev->name, err);
+               goto drop;
+       }
+
+       /* Add desc and skb to rx queue */
+       rx_data = kzalloc(sizeof(*rx_data), GFP_ATOMIC);
+       if (!rx_data) {
+               printk(KERN_WARNING "%s: Can't allocate RX packet\n",
+                       dev->name);
+               goto drop;
+       }
+       rx_data->desc = desc;
+       rx_data->skb = skb;
+       list_add_tail(&rx_data->list, &priv->rx_list);
+       tasklet_schedule(&priv->rx_tasklet);
+
+       return;
+
+drop:
+       dev_kfree_skb_irq(skb);
+update_stats:
+       stats->rx_errors++;
+       stats->rx_dropped++;
+out:
+       kfree(desc);
+}
+
+static void orinoco_rx(struct net_device *dev,
+                      struct hermes_rx_descriptor *desc,
+                      struct sk_buff *skb)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct net_device_stats *stats = &priv->stats;
+       u16 status, fc;
+       int length;
+       struct ethhdr *hdr;
+
+       status = le16_to_cpu(desc->status);
+       length = le16_to_cpu(desc->data_len);
+       fc = le16_to_cpu(desc->frame_ctl);
+
+       /* Calculate and check MIC */
+       if (status & HERMES_RXSTAT_MIC) {
+               int key_id = ((status & HERMES_RXSTAT_MIC_KEY_ID) >>
+                             HERMES_MIC_KEY_ID_SHIFT);
+               u8 mic[MICHAEL_MIC_LEN];
+               u8 *rxmic;
+               u8 *src = (fc & IEEE80211_FCTL_FROMDS) ?
+                       desc->addr3 : desc->addr2;
+
+               /* Extract Michael MIC from payload */
+               rxmic = skb->data + skb->len - MICHAEL_MIC_LEN;
+
+               skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
+               length -= MICHAEL_MIC_LEN;
+
+               michael_mic(priv->rx_tfm_mic,
+                           priv->tkip_key[key_id].rx_mic,
+                           desc->addr1,
+                           src,
+                           0, /* priority or QoS? */
+                           skb->data,
+                           skb->len,
+                           &mic[0]);
+
+               if (memcmp(mic, rxmic,
+                          MICHAEL_MIC_LEN)) {
+                       union iwreq_data wrqu;
+                       struct iw_michaelmicfailure wxmic;
+
+                       printk(KERN_WARNING "%s: "
+                              "Invalid Michael MIC in data frame from %pM, "
+                              "using key %i\n",
+                              dev->name, src, key_id);
+
+                       /* TODO: update stats */
+
+                       /* Notify userspace */
+                       memset(&wxmic, 0, sizeof(wxmic));
+                       wxmic.flags = key_id & IW_MICFAILURE_KEY_ID;
+                       wxmic.flags |= (desc->addr1[0] & 1) ?
+                               IW_MICFAILURE_GROUP : IW_MICFAILURE_PAIRWISE;
+                       wxmic.src_addr.sa_family = ARPHRD_ETHER;
+                       memcpy(wxmic.src_addr.sa_data, src, ETH_ALEN);
+
+                       (void) orinoco_hw_get_tkip_iv(priv, key_id,
+                                                     &wxmic.tsc[0]);
+
+                       memset(&wrqu, 0, sizeof(wrqu));
+                       wrqu.data.length = sizeof(wxmic);
+                       wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu,
+                                           (char *) &wxmic);
+
+                       goto drop;
+               }
+       }
+
+       /* Handle decapsulation
+        * In most cases, the firmware tell us about SNAP frames.
+        * For some reason, the SNAP frames sent by LinkSys APs
+        * are not properly recognised by most firmwares.
+        * So, check ourselves */
+       if (length >= ENCAPS_OVERHEAD &&
+           (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
+            ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
+            is_ethersnap(skb->data))) {
+               /* These indicate a SNAP within 802.2 LLC within
+                  802.11 frame which we'll need to de-encapsulate to
+                  the original EthernetII frame. */
+               hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN - ENCAPS_OVERHEAD);
+       } else {
+               /* 802.3 frame - prepend 802.3 header as is */
+               hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN);
+               hdr->h_proto = htons(length);
+       }
+       memcpy(hdr->h_dest, desc->addr1, ETH_ALEN);
+       if (fc & IEEE80211_FCTL_FROMDS)
+               memcpy(hdr->h_source, desc->addr3, ETH_ALEN);
+       else
+               memcpy(hdr->h_source, desc->addr2, ETH_ALEN);
+
+       skb->protocol = eth_type_trans(skb, dev);
+       skb->ip_summed = CHECKSUM_NONE;
+       if (fc & IEEE80211_FCTL_TODS)
+               skb->pkt_type = PACKET_OTHERHOST;
+       
+       /* Process the wireless stats if needed */
+       orinoco_stat_gather(dev, skb, desc);
+
+       /* Pass the packet to the networking stack */
+       netif_rx(skb);
+       stats->rx_packets++;
+       stats->rx_bytes += length;
+
+       return;
+
+ drop:
+       dev_kfree_skb(skb);
+       stats->rx_errors++;
+       stats->rx_dropped++;
+}
+
+static void orinoco_rx_isr_tasklet(unsigned long data)
+{
+       struct net_device *dev = (struct net_device *) data;
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct orinoco_rx_data *rx_data, *temp;
+       struct hermes_rx_descriptor *desc;
+       struct sk_buff *skb;
+
+       /* extract desc and skb from queue */
+       list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
+               desc = rx_data->desc;
+               skb = rx_data->skb;
+               list_del(&rx_data->list);
+               kfree(rx_data);
+
+               orinoco_rx(dev, desc, skb);
+
+               kfree(desc);
+       }
+}
+
+/********************************************************************/
+/* Rx path (info frames)                                            */
+/********************************************************************/
+
+static void print_linkstatus(struct net_device *dev, u16 status)
+{
+       char * s;
+
+       if (suppress_linkstatus)
+               return;
+
+       switch (status) {
+       case HERMES_LINKSTATUS_NOT_CONNECTED:
+               s = "Not Connected";
+               break;
+       case HERMES_LINKSTATUS_CONNECTED:
+               s = "Connected";
+               break;
+       case HERMES_LINKSTATUS_DISCONNECTED:
+               s = "Disconnected";
+               break;
+       case HERMES_LINKSTATUS_AP_CHANGE:
+               s = "AP Changed";
+               break;
+       case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
+               s = "AP Out of Range";
+               break;
+       case HERMES_LINKSTATUS_AP_IN_RANGE:
+               s = "AP In Range";
+               break;
+       case HERMES_LINKSTATUS_ASSOC_FAILED:
+               s = "Association Failed";
+               break;
+       default:
+               s = "UNKNOWN";
+       }
+       
+       printk(KERN_INFO "%s: New link status: %s (%04x)\n",
+              dev->name, s, status);
+}
+
+/* Search scan results for requested BSSID, join it if found */
+static void orinoco_join_ap(struct work_struct *work)
+{
+       struct orinoco_private *priv =
+               container_of(work, struct orinoco_private, join_work);
+       struct net_device *dev = priv->ndev;
+       struct hermes *hw = &priv->hw;
+       int err;
+       unsigned long flags;
+       struct join_req {
+               u8 bssid[ETH_ALEN];
+               __le16 channel;
+       } __attribute__ ((packed)) req;
+       const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
+       struct prism2_scan_apinfo *atom = NULL;
+       int offset = 4;
+       int found = 0;
+       u8 *buf;
+       u16 len;
+
+       /* Allocate buffer for scan results */
+       buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL);
+       if (! buf)
+               return;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               goto fail_lock;
+
+       /* Sanity checks in case user changed something in the meantime */
+       if (! priv->bssid_fixed)
+               goto out;
+
+       if (strlen(priv->desired_essid) == 0)
+               goto out;
+
+       /* Read scan results from the firmware */
+       err = hermes_read_ltv(hw, USER_BAP,
+                             HERMES_RID_SCANRESULTSTABLE,
+                             MAX_SCAN_LEN, &len, buf);
+       if (err) {
+               printk(KERN_ERR "%s: Cannot read scan results\n",
+                      dev->name);
+               goto out;
+       }
+
+       len = HERMES_RECLEN_TO_BYTES(len);
+
+       /* Go through the scan results looking for the channel of the AP
+        * we were requested to join */
+       for (; offset + atom_len <= len; offset += atom_len) {
+               atom = (struct prism2_scan_apinfo *) (buf + offset);
+               if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) {
+                       found = 1;
+                       break;
+               }
+       }
+
+       if (! found) {
+               DEBUG(1, "%s: Requested AP not found in scan results\n",
+                     dev->name);
+               goto out;
+       }
+
+       memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
+       req.channel = atom->channel;    /* both are little-endian */
+       err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
+                                 &req);
+       if (err)
+               printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
+
+ out:
+       orinoco_unlock(priv, &flags);
+
+ fail_lock:
+       kfree(buf);
+}
+
+/* Send new BSSID to userspace */
+static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
+{
+       struct net_device *dev = priv->ndev;
+       struct hermes *hw = &priv->hw;
+       union iwreq_data wrqu;
+       int err;
+
+       err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
+                             ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
+       if (err != 0)
+               return;
+
+       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+
+       /* Send event to user space */
+       wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+}
+
+static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv)
+{
+       struct net_device *dev = priv->ndev;
+       struct hermes *hw = &priv->hw;
+       union iwreq_data wrqu;
+       int err;
+       u8 buf[88];
+       u8 *ie;
+
+       if (!priv->has_wpa)
+               return;
+
+       err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
+                             sizeof(buf), NULL, &buf);
+       if (err != 0)
+               return;
+
+       ie = orinoco_get_wpa_ie(buf, sizeof(buf));
+       if (ie) {
+               int rem = sizeof(buf) - (ie - &buf[0]);
+               wrqu.data.length = ie[1] + 2;
+               if (wrqu.data.length > rem)
+                       wrqu.data.length = rem;
+
+               if (wrqu.data.length)
+                       /* Send event to user space */
+                       wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, ie);
+       }
+}
+
+static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv)
+{
+       struct net_device *dev = priv->ndev;
+       struct hermes *hw = &priv->hw;
+       union iwreq_data wrqu;
+       int err;
+       u8 buf[88]; /* TODO: verify max size or IW_GENERIC_IE_MAX */
+       u8 *ie;
+
+       if (!priv->has_wpa)
+               return;
+
+       err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO,
+                             sizeof(buf), NULL, &buf);
+       if (err != 0)
+               return;
+
+       ie = orinoco_get_wpa_ie(buf, sizeof(buf));
+       if (ie) {
+               int rem = sizeof(buf) - (ie - &buf[0]);
+               wrqu.data.length = ie[1] + 2;
+               if (wrqu.data.length > rem)
+                       wrqu.data.length = rem;
+
+               if (wrqu.data.length)
+                       /* Send event to user space */
+                       wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, ie);
+       }
+}
+
+static void orinoco_send_wevents(struct work_struct *work)
+{
+       struct orinoco_private *priv =
+               container_of(work, struct orinoco_private, wevent_work);
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return;
+
+       orinoco_send_assocreqie_wevent(priv);
+       orinoco_send_assocrespie_wevent(priv);
+       orinoco_send_bssid_wevent(priv);
+
+       orinoco_unlock(priv, &flags);
+}
+
+static inline void orinoco_clear_scan_results(struct orinoco_private *priv,
+                                             unsigned long scan_age)
+{
+       if (priv->has_ext_scan) {
+               struct xbss_element *bss;
+               struct xbss_element *tmp_bss;
+
+               /* Blow away current list of scan results */
+               list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
+                       if (!scan_age ||
+                           time_after(jiffies, bss->last_scanned + scan_age)) {
+                               list_move_tail(&bss->list,
+                                              &priv->bss_free_list);
+                               /* Don't blow away ->list, just BSS data */
+                               memset(&bss->bss, 0, sizeof(bss->bss));
+                               bss->last_scanned = 0;
+                       }
+               }
+       } else {
+               struct bss_element *bss;
+               struct bss_element *tmp_bss;
+
+               /* Blow away current list of scan results */
+               list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
+                       if (!scan_age ||
+                           time_after(jiffies, bss->last_scanned + scan_age)) {
+                               list_move_tail(&bss->list,
+                                              &priv->bss_free_list);
+                               /* Don't blow away ->list, just BSS data */
+                               memset(&bss->bss, 0, sizeof(bss->bss));
+                               bss->last_scanned = 0;
+                       }
+               }
+       }
+}
+
+static void orinoco_add_ext_scan_result(struct orinoco_private *priv,
+                                       struct agere_ext_scan_info *atom)
+{
+       struct xbss_element *bss = NULL;
+       int found = 0;
+
+       /* Try to update an existing bss first */
+       list_for_each_entry(bss, &priv->bss_list, list) {
+               if (compare_ether_addr(bss->bss.bssid, atom->bssid))
+                       continue;
+               /* ESSID lengths */
+               if (bss->bss.data[1] != atom->data[1])
+                       continue;
+               if (memcmp(&bss->bss.data[2], &atom->data[2],
+                          atom->data[1]))
+                       continue;
+               found = 1;
+               break;
+       }
+
+       /* Grab a bss off the free list */
+       if (!found && !list_empty(&priv->bss_free_list)) {
+               bss = list_entry(priv->bss_free_list.next,
+                                struct xbss_element, list);
+               list_del(priv->bss_free_list.next);
+
+               list_add_tail(&bss->list, &priv->bss_list);
+       }
+
+       if (bss) {
+               /* Always update the BSS to get latest beacon info */
+               memcpy(&bss->bss, atom, sizeof(bss->bss));
+               bss->last_scanned = jiffies;
+       }
+}
+
+static int orinoco_process_scan_results(struct net_device *dev,
+                                       unsigned char *buf,
+                                       int len)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int                     offset;         /* In the scan data */
+       union hermes_scan_info *atom;
+       int                     atom_len;
+
+       switch (priv->firmware_type) {
+       case FIRMWARE_TYPE_AGERE:
+               atom_len = sizeof(struct agere_scan_apinfo);
+               offset = 0;
+               break;
+       case FIRMWARE_TYPE_SYMBOL:
+               /* Lack of documentation necessitates this hack.
+                * Different firmwares have 68 or 76 byte long atoms.
+                * We try modulo first.  If the length divides by both,
+                * we check what would be the channel in the second
+                * frame for a 68-byte atom.  76-byte atoms have 0 there.
+                * Valid channel cannot be 0.  */
+               if (len % 76)
+                       atom_len = 68;
+               else if (len % 68)
+                       atom_len = 76;
+               else if (len >= 1292 && buf[68] == 0)
+                       atom_len = 76;
+               else
+                       atom_len = 68;
+               offset = 0;
+               break;
+       case FIRMWARE_TYPE_INTERSIL:
+               offset = 4;
+               if (priv->has_hostscan) {
+                       atom_len = le16_to_cpup((__le16 *)buf);
+                       /* Sanity check for atom_len */
+                       if (atom_len < sizeof(struct prism2_scan_apinfo)) {
+                               printk(KERN_ERR "%s: Invalid atom_len in scan "
+                                      "data: %d\n", dev->name, atom_len);
+                               return -EIO;
+                       }
+               } else
+                       atom_len = offsetof(struct prism2_scan_apinfo, atim);
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       /* Check that we got an whole number of atoms */
+       if ((len - offset) % atom_len) {
+               printk(KERN_ERR "%s: Unexpected scan data length %d, "
+                      "atom_len %d, offset %d\n", dev->name, len,
+                      atom_len, offset);
+               return -EIO;
+       }
+
+       orinoco_clear_scan_results(priv, msecs_to_jiffies(15000));
+
+       /* Read the entries one by one */
+       for (; offset + atom_len <= len; offset += atom_len) {
+               int found = 0;
+               struct bss_element *bss = NULL;
+
+               /* Get next atom */
+               atom = (union hermes_scan_info *) (buf + offset);
+
+               /* Try to update an existing bss first */
+               list_for_each_entry(bss, &priv->bss_list, list) {
+                       if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid))
+                               continue;
+                       if (le16_to_cpu(bss->bss.a.essid_len) !=
+                             le16_to_cpu(atom->a.essid_len))
+                               continue;
+                       if (memcmp(bss->bss.a.essid, atom->a.essid,
+                             le16_to_cpu(atom->a.essid_len)))
+                               continue;
+                       found = 1;
+                       break;
+               }
+
+               /* Grab a bss off the free list */
+               if (!found && !list_empty(&priv->bss_free_list)) {
+                       bss = list_entry(priv->bss_free_list.next,
+                                        struct bss_element, list);
+                       list_del(priv->bss_free_list.next);
+
+                       list_add_tail(&bss->list, &priv->bss_list);
+               }
+
+               if (bss) {
+                       /* Always update the BSS to get latest beacon info */
+                       memcpy(&bss->bss, atom, sizeof(bss->bss));
+                       bss->last_scanned = jiffies;
+               }
+       }
+
+       return 0;
+}
+
+static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       u16 infofid;
+       struct {
+               __le16 len;
+               __le16 type;
+       } __attribute__ ((packed)) info;
+       int len, type;
+       int err;
+
+       /* This is an answer to an INQUIRE command that we did earlier,
+        * or an information "event" generated by the card
+        * The controller return to us a pseudo frame containing
+        * the information in question - Jean II */
+       infofid = hermes_read_regn(hw, INFOFID);
+
+       /* Read the info frame header - don't try too hard */
+       err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
+                              infofid, 0);
+       if (err) {
+               printk(KERN_ERR "%s: error %d reading info frame. "
+                      "Frame dropped.\n", dev->name, err);
+               return;
+       }
+       
+       len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
+       type = le16_to_cpu(info.type);
+
+       switch (type) {
+       case HERMES_INQ_TALLIES: {
+               struct hermes_tallies_frame tallies;
+               struct iw_statistics *wstats = &priv->wstats;
+               
+               if (len > sizeof(tallies)) {
+                       printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
+                              dev->name, len);
+                       len = sizeof(tallies);
+               }
+               
+               err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
+                                      infofid, sizeof(info));
+               if (err)
+                       break;
+               
+               /* Increment our various counters */
+               /* wstats->discard.nwid - no wrong BSSID stuff */
+               wstats->discard.code +=
+                       le16_to_cpu(tallies.RxWEPUndecryptable);
+               if (len == sizeof(tallies))  
+                       wstats->discard.code +=
+                               le16_to_cpu(tallies.RxDiscards_WEPICVError) +
+                               le16_to_cpu(tallies.RxDiscards_WEPExcluded);
+               wstats->discard.misc +=
+                       le16_to_cpu(tallies.TxDiscardsWrongSA);
+               wstats->discard.fragment +=
+                       le16_to_cpu(tallies.RxMsgInBadMsgFragments);
+               wstats->discard.retries +=
+                       le16_to_cpu(tallies.TxRetryLimitExceeded);
+               /* wstats->miss.beacon - no match */
+       }
+       break;
+       case HERMES_INQ_LINKSTATUS: {
+               struct hermes_linkstatus linkstatus;
+               u16 newstatus;
+               int connected;
+
+               if (priv->iw_mode == IW_MODE_MONITOR)
+                       break;
+
+               if (len != sizeof(linkstatus)) {
+                       printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
+                              dev->name, len);
+                       break;
+               }
+
+               err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
+                                      infofid, sizeof(info));
+               if (err)
+                       break;
+               newstatus = le16_to_cpu(linkstatus.linkstatus);
+
+               /* Symbol firmware uses "out of range" to signal that
+                * the hostscan frame can be requested.  */
+               if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
+                   priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
+                   priv->has_hostscan && priv->scan_inprogress) {
+                       hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
+                       break;
+               }
+
+               connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
+                       || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
+                       || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
+
+               if (connected)
+                       netif_carrier_on(dev);
+               else if (!ignore_disconnect)
+                       netif_carrier_off(dev);
+
+               if (newstatus != priv->last_linkstatus) {
+                       priv->last_linkstatus = newstatus;
+                       print_linkstatus(dev, newstatus);
+                       /* The info frame contains only one word which is the
+                        * status (see hermes.h). The status is pretty boring
+                        * in itself, that's why we export the new BSSID...
+                        * Jean II */
+                       schedule_work(&priv->wevent_work);
+               }
+       }
+       break;
+       case HERMES_INQ_SCAN:
+               if (!priv->scan_inprogress && priv->bssid_fixed &&
+                   priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
+                       schedule_work(&priv->join_work);
+                       break;
+               }
+               /* fall through */
+       case HERMES_INQ_HOSTSCAN:
+       case HERMES_INQ_HOSTSCAN_SYMBOL: {
+               /* Result of a scanning. Contains information about
+                * cells in the vicinity - Jean II */
+               union iwreq_data        wrqu;
+               unsigned char *buf;
+
+               /* Scan is no longer in progress */
+               priv->scan_inprogress = 0;
+
+               /* Sanity check */
+               if (len > 4096) {
+                       printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
+                              dev->name, len);
+                       break;
+               }
+
+               /* Allocate buffer for results */
+               buf = kmalloc(len, GFP_ATOMIC);
+               if (buf == NULL)
+                       /* No memory, so can't printk()... */
+                       break;
+
+               /* Read scan data */
+               err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
+                                      infofid, sizeof(info));
+               if (err) {
+                       kfree(buf);
+                       break;
+               }
+
+#ifdef ORINOCO_DEBUG
+               {
+                       int     i;
+                       printk(KERN_DEBUG "Scan result [%02X", buf[0]);
+                       for(i = 1; i < (len * 2); i++)
+                               printk(":%02X", buf[i]);
+                       printk("]\n");
+               }
+#endif /* ORINOCO_DEBUG */
+
+               if (orinoco_process_scan_results(dev, buf, len) == 0) {
+                       /* Send an empty event to user space.
+                        * We don't send the received data on the event because
+                        * it would require us to do complex transcoding, and
+                        * we want to minimise the work done in the irq handler
+                        * Use a request to extract the data - Jean II */
+                       wrqu.data.length = 0;
+                       wrqu.data.flags = 0;
+                       wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
+               }
+               kfree(buf);
+       }
+       break;
+       case HERMES_INQ_CHANNELINFO:
+       {
+               struct agere_ext_scan_info *bss;
+
+               if (!priv->scan_inprogress) {
+                       printk(KERN_DEBUG "%s: Got chaninfo without scan, "
+                              "len=%d\n", dev->name, len);
+                       break;
+               }
+
+               /* An empty result indicates that the scan is complete */
+               if (len == 0) {
+                       union iwreq_data        wrqu;
+
+                       /* Scan is no longer in progress */
+                       priv->scan_inprogress = 0;
+
+                       wrqu.data.length = 0;
+                       wrqu.data.flags = 0;
+                       wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
+                       break;
+               }
+
+               /* Sanity check */
+               else if (len > sizeof(*bss)) {
+                       printk(KERN_WARNING
+                              "%s: Ext scan results too large (%d bytes). "
+                              "Truncating results to %zd bytes.\n",
+                              dev->name, len, sizeof(*bss));
+                       len = sizeof(*bss);
+               } else if (len < (offsetof(struct agere_ext_scan_info,
+                                          data) + 2)) {
+                       /* Drop this result now so we don't have to
+                        * keep checking later */
+                       printk(KERN_WARNING
+                              "%s: Ext scan results too short (%d bytes)\n",
+                              dev->name, len);
+                       break;
+               }
+
+               bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
+               if (bss == NULL)
+                       break;
+
+               /* Read scan data */
+               err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len,
+                                      infofid, sizeof(info));
+               if (err) {
+                       kfree(bss);
+                       break;
+               }
+
+               orinoco_add_ext_scan_result(priv, bss);
+
+               kfree(bss);
+               break;
+       }
+       case HERMES_INQ_SEC_STAT_AGERE:
+               /* Security status (Agere specific) */
+               /* Ignore this frame for now */
+               if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
+                       break;
+               /* fall through */
+       default:
+               printk(KERN_DEBUG "%s: Unknown information frame received: "
+                      "type 0x%04x, length %d\n", dev->name, type, len);
+               /* We don't actually do anything about it */
+               break;
+       }
+}
+
+static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
+{
+       if (net_ratelimit())
+               printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
+}
+
+/********************************************************************/
+/* Internal hardware control routines                               */
+/********************************************************************/
+
+int __orinoco_up(struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct hermes *hw = &priv->hw;
+       int err;
+
+       netif_carrier_off(dev); /* just to make sure */
+
+       err = __orinoco_program_rids(dev);
+       if (err) {
+               printk(KERN_ERR "%s: Error %d configuring card\n",
+                      dev->name, err);
+               return err;
+       }
+
+       /* Fire things up again */
+       hermes_set_irqmask(hw, ORINOCO_INTEN);
+       err = hermes_enable_port(hw, 0);
+       if (err) {
+               printk(KERN_ERR "%s: Error %d enabling MAC port\n",
+                      dev->name, err);
+               return err;
+       }
+
+       netif_start_queue(dev);
+
+       return 0;
+}
+
+int __orinoco_down(struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct hermes *hw = &priv->hw;
+       int err;
+
+       netif_stop_queue(dev);
+
+       if (! priv->hw_unavailable) {
+               if (! priv->broken_disableport) {
+                       err = hermes_disable_port(hw, 0);
+                       if (err) {
+                               /* Some firmwares (e.g. Intersil 1.3.x) seem
+                                * to have problems disabling the port, oh
+                                * well, too bad. */
+                               printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
+                                      dev->name, err);
+                               priv->broken_disableport = 1;
+                       }
+               }
+               hermes_set_irqmask(hw, 0);
+               hermes_write_regn(hw, EVACK, 0xffff);
+       }
+       
+       /* firmware will have to reassociate */
+       netif_carrier_off(dev);
+       priv->last_linkstatus = 0xffff;
+
+       return 0;
+}
+
+static int orinoco_allocate_fid(struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct hermes *hw = &priv->hw;
+       int err;
+
+       err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+       if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
+               /* Try workaround for old Symbol firmware bug */
+               printk(KERN_WARNING "%s: firmware ALLOC bug detected "
+                      "(old Symbol firmware?). Trying to work around... ",
+                      dev->name);
+               
+               priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
+               err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+               if (err)
+                       printk("failed!\n");
+               else
+                       printk("ok.\n");
+       }
+
+       return err;
+}
+
+int orinoco_reinit_firmware(struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct hermes *hw = &priv->hw;
+       int err;
+
+       err = hermes_init(hw);
+       if (priv->do_fw_download && !err) {
+               err = orinoco_download(priv);
+               if (err)
+                       priv->do_fw_download = 0;
+       }
+       if (!err)
+               err = orinoco_allocate_fid(dev);
+
+       return err;
+}
+
+static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
+{
+       hermes_t *hw = &priv->hw;
+       int err = 0;
+
+       if (priv->bitratemode >= BITRATE_TABLE_SIZE) {
+               printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
+                      priv->ndev->name, priv->bitratemode);
+               return -EINVAL;
+       }
+
+       switch (priv->firmware_type) {
+       case FIRMWARE_TYPE_AGERE:
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFTXRATECONTROL,
+                                          bitrate_table[priv->bitratemode].agere_txratectrl);
+               break;
+       case FIRMWARE_TYPE_INTERSIL:
+       case FIRMWARE_TYPE_SYMBOL:
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFTXRATECONTROL,
+                                          bitrate_table[priv->bitratemode].intersil_txratectrl);
+               break;
+       default:
+               BUG();
+       }
+
+       return err;
+}
+
+/* Set fixed AP address */
+static int __orinoco_hw_set_wap(struct orinoco_private *priv)
+{
+       int roaming_flag;
+       int err = 0;
+       hermes_t *hw = &priv->hw;
+
+       switch (priv->firmware_type) {
+       case FIRMWARE_TYPE_AGERE:
+               /* not supported */
+               break;
+       case FIRMWARE_TYPE_INTERSIL:
+               if (priv->bssid_fixed)
+                       roaming_flag = 2;
+               else
+                       roaming_flag = 1;
+
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFROAMINGMODE,
+                                          roaming_flag);
+               break;
+       case FIRMWARE_TYPE_SYMBOL:
+               err = HERMES_WRITE_RECORD(hw, USER_BAP,
+                                         HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
+                                         &priv->desired_bssid);
+               break;
+       }
+       return err;
+}
+
+/* Change the WEP keys and/or the current keys.  Can be called
+ * either from __orinoco_hw_setup_enc() or directly from
+ * orinoco_ioctl_setiwencode().  In the later case the association
+ * with the AP is not broken (if the firmware can handle it),
+ * which is needed for 802.1x implementations. */
+static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
+{
+       hermes_t *hw = &priv->hw;
+       int err = 0;
+
+       switch (priv->firmware_type) {
+       case FIRMWARE_TYPE_AGERE:
+               err = HERMES_WRITE_RECORD(hw, USER_BAP,
+                                         HERMES_RID_CNFWEPKEYS_AGERE,
+                                         &priv->keys);
+               if (err)
+                       return err;
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFTXKEY_AGERE,
+                                          priv->tx_key);
+               if (err)
+                       return err;
+               break;
+       case FIRMWARE_TYPE_INTERSIL:
+       case FIRMWARE_TYPE_SYMBOL:
+               {
+                       int keylen;
+                       int i;
+
+                       /* Force uniform key length to work around firmware bugs */
+                       keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
+                       
+                       if (keylen > LARGE_KEY_SIZE) {
+                               printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
+                                      priv->ndev->name, priv->tx_key, keylen);
+                               return -E2BIG;
+                       }
+
+                       /* Write all 4 keys */
+                       for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
+                               err = hermes_write_ltv(hw, USER_BAP,
+                                                      HERMES_RID_CNFDEFAULTKEY0 + i,
+                                                      HERMES_BYTES_TO_RECLEN(keylen),
+                                                      priv->keys[i].data);
+                               if (err)
+                                       return err;
+                       }
+
+                       /* Write the index of the key used in transmission */
+                       err = hermes_write_wordrec(hw, USER_BAP,
+                                                  HERMES_RID_CNFWEPDEFAULTKEYID,
+                                                  priv->tx_key);
+                       if (err)
+                               return err;
+               }
+               break;
+       }
+
+       return 0;
+}
+
+static int __orinoco_hw_setup_enc(struct orinoco_private *priv)
+{
+       hermes_t *hw = &priv->hw;
+       int err = 0;
+       int master_wep_flag;
+       int auth_flag;
+       int enc_flag;
+
+       /* Setup WEP keys for WEP and WPA */
+       if (priv->encode_alg)
+               __orinoco_hw_setup_wepkeys(priv);
+
+       if (priv->wep_restrict)
+               auth_flag = HERMES_AUTH_SHARED_KEY;
+       else
+               auth_flag = HERMES_AUTH_OPEN;
+
+       if (priv->wpa_enabled)
+               enc_flag = 2;
+       else if (priv->encode_alg == IW_ENCODE_ALG_WEP)
+               enc_flag = 1;
+       else
+               enc_flag = 0;
+
+       switch (priv->firmware_type) {
+       case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
+               if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
+                       /* Enable the shared-key authentication. */
+                       err = hermes_write_wordrec(hw, USER_BAP,
+                                                  HERMES_RID_CNFAUTHENTICATION_AGERE,
+                                                  auth_flag);
+               }
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFWEPENABLED_AGERE,
+                                          enc_flag);
+               if (err)
+                       return err;
+
+               if (priv->has_wpa) {
+                       /* Set WPA key management */
+                       err = hermes_write_wordrec(hw, USER_BAP,
+                                 HERMES_RID_CNFSETWPAAUTHMGMTSUITE_AGERE,
+                                 priv->key_mgmt);
+                       if (err)
+                               return err;
+               }
+
+               break;
+
+       case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
+       case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
+               if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
+                       if (priv->wep_restrict ||
+                           (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
+                               master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
+                                                 HERMES_WEP_EXCL_UNENCRYPTED;
+                       else
+                               master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
+
+                       err = hermes_write_wordrec(hw, USER_BAP,
+                                                  HERMES_RID_CNFAUTHENTICATION,
+                                                  auth_flag);
+                       if (err)
+                               return err;
+               } else
+                       master_wep_flag = 0;
+
+               if (priv->iw_mode == IW_MODE_MONITOR)
+                       master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
+
+               /* Master WEP setting : on/off */
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFWEPFLAGS_INTERSIL,
+                                          master_wep_flag);
+               if (err)
+                       return err;     
+
+               break;
+       }
+
+       return 0;
+}
+
+/* key must be 32 bytes, including the tx and rx MIC keys.
+ * rsc must be 8 bytes
+ * tsc must be 8 bytes or NULL
+ */
+static int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
+                                    u8 *key, u8 *rsc, u8 *tsc)
+{
+       struct {
+               __le16 idx;
+               u8 rsc[IW_ENCODE_SEQ_MAX_SIZE];
+               u8 key[TKIP_KEYLEN];
+               u8 tx_mic[MIC_KEYLEN];
+               u8 rx_mic[MIC_KEYLEN];
+               u8 tsc[IW_ENCODE_SEQ_MAX_SIZE];
+       } __attribute__ ((packed)) buf;
+       int ret;
+       int err;
+       int k;
+       u16 xmitting;
+
+       key_idx &= 0x3;
+
+       if (set_tx)
+               key_idx |= 0x8000;
+
+       buf.idx = cpu_to_le16(key_idx);
+       memcpy(buf.key, key,
+              sizeof(buf.key) + sizeof(buf.tx_mic) + sizeof(buf.rx_mic));
+
+       if (rsc == NULL)
+               memset(buf.rsc, 0, sizeof(buf.rsc));
+       else
+               memcpy(buf.rsc, rsc, sizeof(buf.rsc));
+
+       if (tsc == NULL) {
+               memset(buf.tsc, 0, sizeof(buf.tsc));
+               buf.tsc[4] = 0x10;
+       } else {
+               memcpy(buf.tsc, tsc, sizeof(buf.tsc));
+       }
+
+       /* Wait upto 100ms for tx queue to empty */
+       k = 100;
+       do {
+               k--;
+               udelay(1000);
+               ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY,
+                                         &xmitting);
+               if (ret)
+                       break;
+       } while ((k > 0) && xmitting);
+
+       if (k == 0)
+               ret = -ETIMEDOUT;
+
+       err = HERMES_WRITE_RECORD(hw, USER_BAP,
+                                 HERMES_RID_CNFADDDEFAULTTKIPKEY_AGERE,
+                                 &buf);
+
+       return ret ? ret : err;
+}
+
+static int orinoco_clear_tkip_key(struct orinoco_private *priv,
+                                 int key_idx)
+{
+       hermes_t *hw = &priv->hw;
+       int err;
+
+       memset(&priv->tkip_key[key_idx], 0, sizeof(priv->tkip_key[key_idx]));
+       err = hermes_write_wordrec(hw, USER_BAP,
+                                  HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE,
+                                  key_idx);
+       if (err)
+               printk(KERN_WARNING "%s: Error %d clearing TKIP key %d\n",
+                      priv->ndev->name, err, key_idx);
+       return err;
+}
+
+static int __orinoco_program_rids(struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       hermes_t *hw = &priv->hw;
+       int err;
+       struct hermes_idstring idbuf;
+
+       /* Set the MAC address */
+       err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
+                              HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
+       if (err) {
+               printk(KERN_ERR "%s: Error %d setting MAC address\n",
+                      dev->name, err);
+               return err;
+       }
+
+       /* Set up the link mode */
+       err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
+                                  priv->port_type);
+       if (err) {
+               printk(KERN_ERR "%s: Error %d setting port type\n",
+                      dev->name, err);
+               return err;
+       }
+       /* Set the channel/frequency */
+       if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFOWNCHANNEL,
+                                          priv->channel);
+               if (err) {
+                       printk(KERN_ERR "%s: Error %d setting channel %d\n",
+                              dev->name, err, priv->channel);
+                       return err;
+               }
+       }
+
+       if (priv->has_ibss) {
+               u16 createibss;
+
+               if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
+                       printk(KERN_WARNING "%s: This firmware requires an "
+                              "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
+                       /* With wvlan_cs, in this case, we would crash.
+                        * hopefully, this driver will behave better...
+                        * Jean II */
+                       createibss = 0;
+               } else {
+                       createibss = priv->createibss;
+               }
+               
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFCREATEIBSS,
+                                          createibss);
+               if (err) {
+                       printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
+                              dev->name, err);
+                       return err;
+               }
+       }
+
+       /* Set the desired BSSID */
+       err = __orinoco_hw_set_wap(priv);
+       if (err) {
+               printk(KERN_ERR "%s: Error %d setting AP address\n",
+                      dev->name, err);
+               return err;
+       }
+       /* Set the desired ESSID */
+       idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
+       memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
+       /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
+       err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
+                              HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+                              &idbuf);
+       if (err) {
+               printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
+                      dev->name, err);
+               return err;
+       }
+       err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
+                              HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+                              &idbuf);
+       if (err) {
+               printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
+                      dev->name, err);
+               return err;
+       }
+
+       /* Set the station name */
+       idbuf.len = cpu_to_le16(strlen(priv->nick));
+       memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
+       err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
+                              HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
+                              &idbuf);
+       if (err) {
+               printk(KERN_ERR "%s: Error %d setting nickname\n",
+                      dev->name, err);
+               return err;
+       }
+
+       /* Set AP density */
+       if (priv->has_sensitivity) {
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFSYSTEMSCALE,
+                                          priv->ap_density);
+               if (err) {
+                       printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE.  "
+                              "Disabling sensitivity control\n",
+                              dev->name, err);
+
+                       priv->has_sensitivity = 0;
+               }
+       }
+
+       /* Set RTS threshold */
+       err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
+                                  priv->rts_thresh);
+       if (err) {
+               printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
+                      dev->name, err);
+               return err;
+       }
+
+       /* Set fragmentation threshold or MWO robustness */
+       if (priv->has_mwo)
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFMWOROBUST_AGERE,
+                                          priv->mwo_robust);
+       else
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+                                          priv->frag_thresh);
+       if (err) {
+               printk(KERN_ERR "%s: Error %d setting fragmentation\n",
+                      dev->name, err);
+               return err;
+       }
+
+       /* Set bitrate */
+       err = __orinoco_hw_set_bitrate(priv);
+       if (err) {
+               printk(KERN_ERR "%s: Error %d setting bitrate\n",
+                      dev->name, err);
+               return err;
+       }
+
+       /* Set power management */
+       if (priv->has_pm) {
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFPMENABLED,
+                                          priv->pm_on);
+               if (err) {
+                       printk(KERN_ERR "%s: Error %d setting up PM\n",
+                              dev->name, err);
+                       return err;
+               }
+
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFMULTICASTRECEIVE,
+                                          priv->pm_mcast);
+               if (err) {
+                       printk(KERN_ERR "%s: Error %d setting up PM\n",
+                              dev->name, err);
+                       return err;
+               }
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFMAXSLEEPDURATION,
+                                          priv->pm_period);
+               if (err) {
+                       printk(KERN_ERR "%s: Error %d setting up PM\n",
+                              dev->name, err);
+                       return err;
+               }
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFPMHOLDOVERDURATION,
+                                          priv->pm_timeout);
+               if (err) {
+                       printk(KERN_ERR "%s: Error %d setting up PM\n",
+                              dev->name, err);
+                       return err;
+               }
+       }
+
+       /* Set preamble - only for Symbol so far... */
+       if (priv->has_preamble) {
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFPREAMBLE_SYMBOL,
+                                          priv->preamble);
+               if (err) {
+                       printk(KERN_ERR "%s: Error %d setting preamble\n",
+                              dev->name, err);
+                       return err;
+               }
+       }
+
+       /* Set up encryption */
+       if (priv->has_wep || priv->has_wpa) {
+               err = __orinoco_hw_setup_enc(priv);
+               if (err) {
+                       printk(KERN_ERR "%s: Error %d activating encryption\n",
+                              dev->name, err);
+                       return err;
+               }
+       }
+
+       if (priv->iw_mode == IW_MODE_MONITOR) {
+               /* Enable monitor mode */
+               dev->type = ARPHRD_IEEE80211;
+               err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 
+                                           HERMES_TEST_MONITOR, 0, NULL);
+       } else {
+               /* Disable monitor mode */
+               dev->type = ARPHRD_ETHER;
+               err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+                                           HERMES_TEST_STOP, 0, NULL);
+       }
+       if (err)
+               return err;
+
+       /* Set promiscuity / multicast*/
+       priv->promiscuous = 0;
+       priv->mc_count = 0;
+
+       /* FIXME: what about netif_tx_lock */
+       __orinoco_set_multicast_list(dev);
+
+       return 0;
+}
+
+/* FIXME: return int? */
+static void
+__orinoco_set_multicast_list(struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       hermes_t *hw = &priv->hw;
+       int err = 0;
+       int promisc, mc_count;
+
+       /* The Hermes doesn't seem to have an allmulti mode, so we go
+        * into promiscuous mode and let the upper levels deal. */
+       if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
+            (dev->mc_count > MAX_MULTICAST(priv)) ) {
+               promisc = 1;
+               mc_count = 0;
+       } else {
+               promisc = 0;
+               mc_count = dev->mc_count;
+       }
+
+       if (promisc != priv->promiscuous) {
+               err = hermes_write_wordrec(hw, USER_BAP,
+                                          HERMES_RID_CNFPROMISCUOUSMODE,
+                                          promisc);
+               if (err) {
+                       printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
+                              dev->name, err);
+               } else 
+                       priv->promiscuous = promisc;
+       }
+
+       /* If we're not in promiscuous mode, then we need to set the
+        * group address if either we want to multicast, or if we were
+        * multicasting and want to stop */
+       if (! promisc && (mc_count || priv->mc_count) ) {
+               struct dev_mc_list *p = dev->mc_list;
+               struct hermes_multicast mclist;
+               int i;
+
+               for (i = 0; i < mc_count; i++) {
+                       /* paranoia: is list shorter than mc_count? */
+                       BUG_ON(! p);
+                       /* paranoia: bad address size in list? */
+                       BUG_ON(p->dmi_addrlen != ETH_ALEN);
+                       
+                       memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
+                       p = p->next;
+               }
+               
+               if (p)
+                       printk(KERN_WARNING "%s: Multicast list is "
+                              "longer than mc_count\n", dev->name);
+
+               err = hermes_write_ltv(hw, USER_BAP,
+                                  HERMES_RID_CNFGROUPADDRESSES,
+                                  HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN),
+                                  &mclist);
+               if (err)
+                       printk(KERN_ERR "%s: Error %d setting multicast list.\n",
+                              dev->name, err);
+               else
+                       priv->mc_count = mc_count;
+       }
+}
+
+/* This must be called from user context, without locks held - use
+ * schedule_work() */
+static void orinoco_reset(struct work_struct *work)
+{
+       struct orinoco_private *priv =
+               container_of(work, struct orinoco_private, reset_work);
+       struct net_device *dev = priv->ndev;
+       struct hermes *hw = &priv->hw;
+       int err;
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               /* When the hardware becomes available again, whatever
+                * detects that is responsible for re-initializing
+                * it. So no need for anything further */
+               return;
+
+       netif_stop_queue(dev);
+
+       /* Shut off interrupts.  Depending on what state the hardware
+        * is in, this might not work, but we'll try anyway */
+       hermes_set_irqmask(hw, 0);
+       hermes_write_regn(hw, EVACK, 0xffff);
+
+       priv->hw_unavailable++;
+       priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
+       netif_carrier_off(dev);
+
+       orinoco_unlock(priv, &flags);
+
+       /* Scanning support: Cleanup of driver struct */
+       orinoco_clear_scan_results(priv, 0);
+       priv->scan_inprogress = 0;
+
+       if (priv->hard_reset) {
+               err = (*priv->hard_reset)(priv);
+               if (err) {
+                       printk(KERN_ERR "%s: orinoco_reset: Error %d "
+                              "performing hard reset\n", dev->name, err);
+                       goto disable;
+               }
+       }
+
+       err = orinoco_reinit_firmware(dev);
+       if (err) {
+               printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
+                      dev->name, err);
+               goto disable;
+       }
+
+       spin_lock_irq(&priv->lock); /* This has to be called from user context */
+
+       priv->hw_unavailable--;
+
+       /* priv->open or priv->hw_unavailable might have changed while
+        * we dropped the lock */
+       if (priv->open && (! priv->hw_unavailable)) {
+               err = __orinoco_up(dev);
+               if (err) {
+                       printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
+                              dev->name, err);
+               } else
+                       dev->trans_start = jiffies;
+       }
+
+       spin_unlock_irq(&priv->lock);
+
+       return;
+ disable:
+       hermes_set_irqmask(hw, 0);
+       netif_device_detach(dev);
+       printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
+}
+
+/********************************************************************/
+/* Interrupt handler                                                */
+/********************************************************************/
+
+static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
+{
+       printk(KERN_DEBUG "%s: TICK\n", dev->name);
+}
+
+static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
+{
+       /* This seems to happen a fair bit under load, but ignoring it
+          seems to work fine...*/
+       printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
+              dev->name);
+}
+
+irqreturn_t orinoco_interrupt(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct orinoco_private *priv = netdev_priv(dev);
+       hermes_t *hw = &priv->hw;
+       int count = MAX_IRQLOOPS_PER_IRQ;
+       u16 evstat, events;
+       /* These are used to detect a runaway interrupt situation */
+       /* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
+        * we panic and shut down the hardware */
+       static int last_irq_jiffy = 0; /* jiffies value the last time
+                                       * we were called */
+       static int loops_this_jiffy = 0;
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0) {
+               /* If hw is unavailable - we don't know if the irq was
+                * for us or not */
+               return IRQ_HANDLED;
+       }
+
+       evstat = hermes_read_regn(hw, EVSTAT);
+       events = evstat & hw->inten;
+       if (! events) {
+               orinoco_unlock(priv, &flags);
+               return IRQ_NONE;
+       }
+       
+       if (jiffies != last_irq_jiffy)
+               loops_this_jiffy = 0;
+       last_irq_jiffy = jiffies;
+
+       while (events && count--) {
+               if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
+                       printk(KERN_WARNING "%s: IRQ handler is looping too "
+                              "much! Resetting.\n", dev->name);
+                       /* Disable interrupts for now */
+                       hermes_set_irqmask(hw, 0);
+                       schedule_work(&priv->reset_work);
+                       break;
+               }
+
+               /* Check the card hasn't been removed */
+               if (! hermes_present(hw)) {
+                       DEBUG(0, "orinoco_interrupt(): card removed\n");
+                       break;
+               }
+
+               if (events & HERMES_EV_TICK)
+                       __orinoco_ev_tick(dev, hw);
+               if (events & HERMES_EV_WTERR)
+                       __orinoco_ev_wterr(dev, hw);
+               if (events & HERMES_EV_INFDROP)
+                       __orinoco_ev_infdrop(dev, hw);
+               if (events & HERMES_EV_INFO)
+                       __orinoco_ev_info(dev, hw);
+               if (events & HERMES_EV_RX)
+                       __orinoco_ev_rx(dev, hw);
+               if (events & HERMES_EV_TXEXC)
+                       __orinoco_ev_txexc(dev, hw);
+               if (events & HERMES_EV_TX)
+                       __orinoco_ev_tx(dev, hw);
+               if (events & HERMES_EV_ALLOC)
+                       __orinoco_ev_alloc(dev, hw);
+               
+               hermes_write_regn(hw, EVACK, evstat);
+
+               evstat = hermes_read_regn(hw, EVSTAT);
+               events = evstat & hw->inten;
+       };
+
+       orinoco_unlock(priv, &flags);
+       return IRQ_HANDLED;
+}
+
+/********************************************************************/
+/* Initialization                                                   */
+/********************************************************************/
+
+struct comp_id {
+       u16 id, variant, major, minor;
+} __attribute__ ((packed));
+
+static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
+{
+       if (nic_id->id < 0x8000)
+               return FIRMWARE_TYPE_AGERE;
+       else if (nic_id->id == 0x8000 && nic_id->major == 0)
+               return FIRMWARE_TYPE_SYMBOL;
+       else
+               return FIRMWARE_TYPE_INTERSIL;
+}
+
+/* Set priv->firmware type, determine firmware properties */
+static int determine_firmware(struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       hermes_t *hw = &priv->hw;
+       int err;
+       struct comp_id nic_id, sta_id;
+       unsigned int firmver;
+       char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
+
+       /* Get the hardware version */
+       err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
+       if (err) {
+               printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
+                      dev->name, err);
+               return err;
+       }
+
+       le16_to_cpus(&nic_id.id);
+       le16_to_cpus(&nic_id.variant);
+       le16_to_cpus(&nic_id.major);
+       le16_to_cpus(&nic_id.minor);
+       printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
+              dev->name, nic_id.id, nic_id.variant,
+              nic_id.major, nic_id.minor);
+
+       priv->firmware_type = determine_firmware_type(&nic_id);
+
+       /* Get the firmware version */
+       err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
+       if (err) {
+               printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
+                      dev->name, err);
+               return err;
+       }
+
+       le16_to_cpus(&sta_id.id);
+       le16_to_cpus(&sta_id.variant);
+       le16_to_cpus(&sta_id.major);
+       le16_to_cpus(&sta_id.minor);
+       printk(KERN_DEBUG "%s: Station identity  %04x:%04x:%04x:%04x\n",
+              dev->name, sta_id.id, sta_id.variant,
+              sta_id.major, sta_id.minor);
+
+       switch (sta_id.id) {
+       case 0x15:
+               printk(KERN_ERR "%s: Primary firmware is active\n",
+                      dev->name);
+               return -ENODEV;
+       case 0x14b:
+               printk(KERN_ERR "%s: Tertiary firmware is active\n",
+                      dev->name);
+               return -ENODEV;
+       case 0x1f:      /* Intersil, Agere, Symbol Spectrum24 */
+       case 0x21:      /* Symbol Spectrum24 Trilogy */
+               break;
+       default:
+               printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
+                      dev->name);
+               break;
+       }
+
+       /* Default capabilities */
+       priv->has_sensitivity = 1;
+       priv->has_mwo = 0;
+       priv->has_preamble = 0;
+       priv->has_port3 = 1;
+       priv->has_ibss = 1;
+       priv->has_wep = 0;
+       priv->has_big_wep = 0;
+       priv->has_alt_txcntl = 0;
+       priv->has_ext_scan = 0;
+       priv->has_wpa = 0;
+       priv->do_fw_download = 0;
+
+       /* Determine capabilities from the firmware version */
+       switch (priv->firmware_type) {
+       case FIRMWARE_TYPE_AGERE:
+               /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
+                  ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
+               snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+                        "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
+
+               firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
+
+               priv->has_ibss = (firmver >= 0x60006);
+               priv->has_wep = (firmver >= 0x40020);
+               priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
+                                         Gold cards from the others? */
+               priv->has_mwo = (firmver >= 0x60000);
+               priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
+               priv->ibss_port = 1;
+               priv->has_hostscan = (firmver >= 0x8000a);
+               priv->do_fw_download = 1;
+               priv->broken_monitor = (firmver >= 0x80000);
+               priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
+               priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
+               priv->has_wpa = (firmver >= 0x9002a);
+               /* Tested with Agere firmware :
+                *      1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
+                * Tested CableTron firmware : 4.32 => Anton */
+               break;
+       case FIRMWARE_TYPE_SYMBOL:
+               /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
+               /* Intel MAC : 00:02:B3:* */
+               /* 3Com MAC : 00:50:DA:* */
+               memset(tmp, 0, sizeof(tmp));
+               /* Get the Symbol firmware version */
+               err = hermes_read_ltv(hw, USER_BAP,
+                                     HERMES_RID_SECONDARYVERSION_SYMBOL,
+                                     SYMBOL_MAX_VER_LEN, NULL, &tmp);
+               if (err) {
+                       printk(KERN_WARNING
+                              "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n",
+                              dev->name, err);
+                       firmver = 0;
+                       tmp[0] = '\0';
+               } else {
+                       /* The firmware revision is a string, the format is
+                        * something like : "V2.20-01".
+                        * Quick and dirty parsing... - Jean II
+                        */
+                       firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12)
+                               | ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4)
+                               | (tmp[7] - '0');
+
+                       tmp[SYMBOL_MAX_VER_LEN] = '\0';
+               }
+
+               snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+                        "Symbol %s", tmp);
+
+               priv->has_ibss = (firmver >= 0x20000);
+               priv->has_wep = (firmver >= 0x15012);
+               priv->has_big_wep = (firmver >= 0x20000);
+               priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) || 
+                              (firmver >= 0x29000 && firmver < 0x30000) ||
+                              firmver >= 0x31000;
+               priv->has_preamble = (firmver >= 0x20000);
+               priv->ibss_port = 4;
+
+               /* Symbol firmware is found on various cards, but
+                * there has been no attempt to check firmware
+                * download on non-spectrum_cs based cards.
+                *
+                * Given that the Agere firmware download works
+                * differently, we should avoid doing a firmware
+                * download with the Symbol algorithm on non-spectrum
+                * cards.
+                *
+                * For now we can identify a spectrum_cs based card
+                * because it has a firmware reset function.
+                */
+               priv->do_fw_download = (priv->stop_fw != NULL);
+
+               priv->broken_disableport = (firmver == 0x25013) ||
+                                          (firmver >= 0x30000 && firmver <= 0x31000);
+               priv->has_hostscan = (firmver >= 0x31001) ||
+                                    (firmver >= 0x29057 && firmver < 0x30000);
+               /* Tested with Intel firmware : 0x20015 => Jean II */
+               /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
+               break;
+       case FIRMWARE_TYPE_INTERSIL:
+               /* D-Link, Linksys, Adtron, ZoomAir, and many others...
+                * Samsung, Compaq 100/200 and Proxim are slightly
+                * different and less well tested */
+               /* D-Link MAC : 00:40:05:* */
+               /* Addtron MAC : 00:90:D1:* */
+               snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+                        "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
+                        sta_id.variant);
+
+               firmver = ((unsigned long)sta_id.major << 16) |
+                       ((unsigned long)sta_id.minor << 8) | sta_id.variant;
+
+               priv->has_ibss = (firmver >= 0x000700); /* FIXME */
+               priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
+               priv->has_pm = (firmver >= 0x000700);
+               priv->has_hostscan = (firmver >= 0x010301);
+
+               if (firmver >= 0x000800)
+                       priv->ibss_port = 0;
+               else {
+                       printk(KERN_NOTICE "%s: Intersil firmware earlier "
+                              "than v0.8.x - several features not supported\n",
+                              dev->name);
+                       priv->ibss_port = 1;
+               }
+               break;
+       }
+       printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
+              priv->fw_name);
+
+       return 0;
+}
+
+static int orinoco_init(struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       hermes_t *hw = &priv->hw;
+       int err = 0;
+       struct hermes_idstring nickbuf;
+       u16 reclen;
+       int len;
+
+       /* No need to lock, the hw_unavailable flag is already set in
+        * alloc_orinocodev() */
+       priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN;
+
+       /* Initialize the firmware */
+       err = hermes_init(hw);
+       if (err != 0) {
+               printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
+                      dev->name, err);
+               goto out;
+       }
+
+       err = determine_firmware(dev);
+       if (err != 0) {
+               printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
+                      dev->name);
+               goto out;
+       }
+
+       if (priv->do_fw_download) {
+               err = orinoco_download(priv);
+               if (err)
+                       priv->do_fw_download = 0;
+
+               /* Check firmware version again */
+               err = determine_firmware(dev);
+               if (err != 0) {
+                       printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
+                              dev->name);
+                       goto out;
+               }
+       }
+
+       if (priv->has_port3)
+               printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);
+       if (priv->has_ibss)
+               printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
+                      dev->name);
+       if (priv->has_wep) {
+               printk(KERN_DEBUG "%s: WEP supported, ", dev->name);
+               if (priv->has_big_wep)
+                       printk("104-bit key\n");
+               else
+                       printk("40-bit key\n");
+       }
+       if (priv->has_wpa) {
+               printk(KERN_DEBUG "%s: WPA-PSK supported\n", dev->name);
+               if (orinoco_mic_init(priv)) {
+                       printk(KERN_ERR "%s: Failed to setup MIC crypto "
+                              "algorithm. Disabling WPA support\n", dev->name);
+                       priv->has_wpa = 0;
+               }
+       }
+
+       /* Now we have the firmware capabilities, allocate appropiate
+        * sized scan buffers */
+       if (orinoco_bss_data_allocate(priv))
+               goto out;
+       orinoco_bss_data_init(priv);
+
+       /* Get the MAC address */
+       err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
+                             ETH_ALEN, NULL, dev->dev_addr);
+       if (err) {
+               printk(KERN_WARNING "%s: failed to read MAC address!\n",
+                      dev->name);
+               goto out;
+       }
+
+       printk(KERN_DEBUG "%s: MAC address %pM\n",
+              dev->name, dev->dev_addr);
+
+       /* Get the station name */
+       err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
+                             sizeof(nickbuf), &reclen, &nickbuf);
+       if (err) {
+               printk(KERN_ERR "%s: failed to read station name\n",
+                      dev->name);
+               goto out;
+       }
+       if (nickbuf.len)
+               len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
+       else
+               len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
+       memcpy(priv->nick, &nickbuf.val, len);
+       priv->nick[len] = '\0';
+
+       printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
+
+       err = orinoco_allocate_fid(dev);
+       if (err) {
+               printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
+                      dev->name);
+               goto out;
+       }
+
+       /* Get allowed channels */
+       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
+                                 &priv->channel_mask);
+       if (err) {
+               printk(KERN_ERR "%s: failed to read channel list!\n",
+                      dev->name);
+               goto out;
+       }
+
+       /* Get initial AP density */
+       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
+                                 &priv->ap_density);
+       if (err || priv->ap_density < 1 || priv->ap_density > 3) {
+               priv->has_sensitivity = 0;
+       }
+
+       /* Get initial RTS threshold */
+       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
+                                 &priv->rts_thresh);
+       if (err) {
+               printk(KERN_ERR "%s: failed to read RTS threshold!\n",
+                      dev->name);
+               goto out;
+       }
+
+       /* Get initial fragmentation settings */
+       if (priv->has_mwo)
+               err = hermes_read_wordrec(hw, USER_BAP,
+                                         HERMES_RID_CNFMWOROBUST_AGERE,
+                                         &priv->mwo_robust);
+       else
+               err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+                                         &priv->frag_thresh);
+       if (err) {
+               printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
+                      dev->name);
+               goto out;
+       }
+
+       /* Power management setup */
+       if (priv->has_pm) {
+               priv->pm_on = 0;
+               priv->pm_mcast = 1;
+               err = hermes_read_wordrec(hw, USER_BAP,
+                                         HERMES_RID_CNFMAXSLEEPDURATION,
+                                         &priv->pm_period);
+               if (err) {
+                       printk(KERN_ERR "%s: failed to read power management period!\n",
+                              dev->name);
+                       goto out;
+               }
+               err = hermes_read_wordrec(hw, USER_BAP,
+                                         HERMES_RID_CNFPMHOLDOVERDURATION,
+                                         &priv->pm_timeout);
+               if (err) {
+                       printk(KERN_ERR "%s: failed to read power management timeout!\n",
+                              dev->name);
+                       goto out;
+               }
+       }
+
+       /* Preamble setup */
+       if (priv->has_preamble) {
+               err = hermes_read_wordrec(hw, USER_BAP,
+                                         HERMES_RID_CNFPREAMBLE_SYMBOL,
+                                         &priv->preamble);
+               if (err)
+                       goto out;
+       }
+               
+       /* Set up the default configuration */
+       priv->iw_mode = IW_MODE_INFRA;
+       /* By default use IEEE/IBSS ad-hoc mode if we have it */
+       priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
+       set_port_type(priv);
+       priv->channel = 0; /* use firmware default */
+
+       priv->promiscuous = 0;
+       priv->encode_alg = IW_ENCODE_ALG_NONE;
+       priv->tx_key = 0;
+       priv->wpa_enabled = 0;
+       priv->tkip_cm_active = 0;
+       priv->key_mgmt = 0;
+       priv->wpa_ie_len = 0;
+       priv->wpa_ie = NULL;
+
+       /* Make the hardware available, as long as it hasn't been
+        * removed elsewhere (e.g. by PCMCIA hot unplug) */
+       spin_lock_irq(&priv->lock);
+       priv->hw_unavailable--;
+       spin_unlock_irq(&priv->lock);
+
+       printk(KERN_DEBUG "%s: ready\n", dev->name);
+
+ out:
+       return err;
+}
+
+struct net_device
+*alloc_orinocodev(int sizeof_card,
+                 struct device *device,
+                 int (*hard_reset)(struct orinoco_private *),
+                 int (*stop_fw)(struct orinoco_private *, int))
+{
+       struct net_device *dev;
+       struct orinoco_private *priv;
+
+       dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
+       if (! dev)
+               return NULL;
+       priv = netdev_priv(dev);
+       priv->ndev = dev;
+       if (sizeof_card)
+               priv->card = (void *)((unsigned long)priv
+                                     + sizeof(struct orinoco_private));
+       else
+               priv->card = NULL;
+       priv->dev = device;
+
+       /* Setup / override net_device fields */
+       dev->init = orinoco_init;
+       dev->hard_start_xmit = orinoco_xmit;
+       dev->tx_timeout = orinoco_tx_timeout;
+       dev->watchdog_timeo = HZ; /* 1 second timeout */
+       dev->get_stats = orinoco_get_stats;
+       dev->ethtool_ops = &orinoco_ethtool_ops;
+       dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
+#ifdef WIRELESS_SPY
+       priv->wireless_data.spy_data = &priv->spy_data;
+       dev->wireless_data = &priv->wireless_data;
+#endif
+       dev->change_mtu = orinoco_change_mtu;
+       dev->set_multicast_list = orinoco_set_multicast_list;
+       /* we use the default eth_mac_addr for setting the MAC addr */
+
+       /* Reserve space in skb for the SNAP header */
+       dev->hard_header_len += ENCAPS_OVERHEAD;
+
+       /* Set up default callbacks */
+       dev->open = orinoco_open;
+       dev->stop = orinoco_stop;
+       priv->hard_reset = hard_reset;
+       priv->stop_fw = stop_fw;
+
+       spin_lock_init(&priv->lock);
+       priv->open = 0;
+       priv->hw_unavailable = 1; /* orinoco_init() must clear this
+                                  * before anything else touches the
+                                  * hardware */
+       INIT_WORK(&priv->reset_work, orinoco_reset);
+       INIT_WORK(&priv->join_work, orinoco_join_ap);
+       INIT_WORK(&priv->wevent_work, orinoco_send_wevents);
+
+       INIT_LIST_HEAD(&priv->rx_list);
+       tasklet_init(&priv->rx_tasklet, orinoco_rx_isr_tasklet,
+                    (unsigned long) dev);
+
+       netif_carrier_off(dev);
+       priv->last_linkstatus = 0xffff;
+
+       priv->cached_fw = NULL;
+
+       return dev;
+}
+
+void free_orinocodev(struct net_device *dev)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+
+       /* No need to empty priv->rx_list: if the tasklet is scheduled
+        * when we call tasklet_kill it will run one final time,
+        * emptying the list */
+       tasklet_kill(&priv->rx_tasklet);
+       if (priv->cached_fw)
+               release_firmware(priv->cached_fw);
+       priv->cached_fw = NULL;
+       priv->wpa_ie_len = 0;
+       kfree(priv->wpa_ie);
+       orinoco_mic_free(priv);
+       orinoco_bss_data_free(priv);
+       free_netdev(dev);
+}
+
+/********************************************************************/
+/* Wireless extensions                                              */
+/********************************************************************/
+
+/* Return : < 0 -> error code ; >= 0 -> length */
+static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
+                               char buf[IW_ESSID_MAX_SIZE+1])
+{
+       hermes_t *hw = &priv->hw;
+       int err = 0;
+       struct hermes_idstring essidbuf;
+       char *p = (char *)(&essidbuf.val);
+       int len;
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       if (strlen(priv->desired_essid) > 0) {
+               /* We read the desired SSID from the hardware rather
+                  than from priv->desired_essid, just in case the
+                  firmware is allowed to change it on us. I'm not
+                  sure about this */
+               /* My guess is that the OWNSSID should always be whatever
+                * we set to the card, whereas CURRENT_SSID is the one that
+                * may change... - Jean II */
+               u16 rid;
+
+               *active = 1;
+
+               rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
+                       HERMES_RID_CNFDESIREDSSID;
+               
+               err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
+                                     NULL, &essidbuf);
+               if (err)
+                       goto fail_unlock;
+       } else {
+               *active = 0;
+
+               err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
+                                     sizeof(essidbuf), NULL, &essidbuf);
+               if (err)
+                       goto fail_unlock;
+       }
+
+       len = le16_to_cpu(essidbuf.len);
+       BUG_ON(len > IW_ESSID_MAX_SIZE);
+
+       memset(buf, 0, IW_ESSID_MAX_SIZE);
+       memcpy(buf, p, len);
+       err = len;
+
+ fail_unlock:
+       orinoco_unlock(priv, &flags);
+
+       return err;       
+}
+
+static long orinoco_hw_get_freq(struct orinoco_private *priv)
+{
+       
+       hermes_t *hw = &priv->hw;
+       int err = 0;
+       u16 channel;
+       long freq = 0;
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+       
+       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
+       if (err)
+               goto out;
+
+       /* Intersil firmware 1.3.5 returns 0 when the interface is down */
+       if (channel == 0) {
+               err = -EBUSY;
+               goto out;
+       }
+
+       if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
+               printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
+                      priv->ndev->name, channel);
+               err = -EBUSY;
+               goto out;
+
+       }
+       freq = channel_frequency[channel-1] * 100000;
+
+ out:
+       orinoco_unlock(priv, &flags);
+
+       if (err > 0)
+               err = -EBUSY;
+       return err ? err : freq;
+}
+
+static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
+                                     int *numrates, s32 *rates, int max)
+{
+       hermes_t *hw = &priv->hw;
+       struct hermes_idstring list;
+       unsigned char *p = (unsigned char *)&list.val;
+       int err = 0;
+       int num;
+       int i;
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
+                             sizeof(list), NULL, &list);
+       orinoco_unlock(priv, &flags);
+
+       if (err)
+               return err;
+       
+       num = le16_to_cpu(list.len);
+       *numrates = num;
+       num = min(num, max);
+
+       for (i = 0; i < num; i++) {
+               rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
+       }
+
+       return 0;
+}
+
+static int orinoco_ioctl_getname(struct net_device *dev,
+                                struct iw_request_info *info,
+                                char *name,
+                                char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int numrates;
+       int err;
+
+       err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
+
+       if (!err && (numrates > 2))
+               strcpy(name, "IEEE 802.11b");
+       else
+               strcpy(name, "IEEE 802.11-DS");
+
+       return 0;
+}
+
+static int orinoco_ioctl_setwap(struct net_device *dev,
+                               struct iw_request_info *info,
+                               struct sockaddr *ap_addr,
+                               char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int err = -EINPROGRESS;         /* Call commit handler */
+       unsigned long flags;
+       static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+       static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       /* Enable automatic roaming - no sanity checks are needed */
+       if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
+           memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
+               priv->bssid_fixed = 0;
+               memset(priv->desired_bssid, 0, ETH_ALEN);
+
+               /* "off" means keep existing connection */
+               if (ap_addr->sa_data[0] == 0) {
+                       __orinoco_hw_set_wap(priv);
+                       err = 0;
+               }
+               goto out;
+       }
+
+       if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
+               printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
+                      "support manual roaming\n",
+                      dev->name);
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       if (priv->iw_mode != IW_MODE_INFRA) {
+               printk(KERN_WARNING "%s: Manual roaming supported only in "
+                      "managed mode\n", dev->name);
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       /* Intersil firmware hangs without Desired ESSID */
+       if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
+           strlen(priv->desired_essid) == 0) {
+               printk(KERN_WARNING "%s: Desired ESSID must be set for "
+                      "manual roaming\n", dev->name);
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       /* Finally, enable manual roaming */
+       priv->bssid_fixed = 1;
+       memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
+
+ out:
+       orinoco_unlock(priv, &flags);
+       return err;
+}
+
+static int orinoco_ioctl_getwap(struct net_device *dev,
+                               struct iw_request_info *info,
+                               struct sockaddr *ap_addr,
+                               char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+
+       hermes_t *hw = &priv->hw;
+       int err = 0;
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       ap_addr->sa_family = ARPHRD_ETHER;
+       err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
+                             ETH_ALEN, NULL, ap_addr->sa_data);
+
+       orinoco_unlock(priv, &flags);
+
+       return err;
+}
+
+static int orinoco_ioctl_setmode(struct net_device *dev,
+                                struct iw_request_info *info,
+                                u32 *mode,
+                                char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int err = -EINPROGRESS;         /* Call commit handler */
+       unsigned long flags;
+
+       if (priv->iw_mode == *mode)
+               return 0;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       switch (*mode) {
+       case IW_MODE_ADHOC:
+               if (!priv->has_ibss && !priv->has_port3)
+                       err = -EOPNOTSUPP;
+               break;
+
+       case IW_MODE_INFRA:
+               break;
+
+       case IW_MODE_MONITOR:
+               if (priv->broken_monitor && !force_monitor) {
+                       printk(KERN_WARNING "%s: Monitor mode support is "
+                              "buggy in this firmware, not enabling\n",
+                              dev->name);
+                       err = -EOPNOTSUPP;
+               }
+               break;
+
+       default:
+               err = -EOPNOTSUPP;
+               break;
+       }
+
+       if (err == -EINPROGRESS) {
+               priv->iw_mode = *mode;
+               set_port_type(priv);
+       }
+
+       orinoco_unlock(priv, &flags);
+
+       return err;
+}
+
+static int orinoco_ioctl_getmode(struct net_device *dev,
+                                struct iw_request_info *info,
+                                u32 *mode,
+                                char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+
+       *mode = priv->iw_mode;
+       return 0;
+}
+
+static int orinoco_ioctl_getiwrange(struct net_device *dev,
+                                   struct iw_request_info *info,
+                                   struct iw_point *rrq,
+                                   char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int err = 0;
+       struct iw_range *range = (struct iw_range *) extra;
+       int numrates;
+       int i, k;
+
+       rrq->length = sizeof(struct iw_range);
+       memset(range, 0, sizeof(struct iw_range));
+
+       range->we_version_compiled = WIRELESS_EXT;
+       range->we_version_source = 22;
+
+       /* Set available channels/frequencies */
+       range->num_channels = NUM_CHANNELS;
+       k = 0;
+       for (i = 0; i < NUM_CHANNELS; i++) {
+               if (priv->channel_mask & (1 << i)) {
+                       range->freq[k].i = i + 1;
+                       range->freq[k].m = channel_frequency[i] * 100000;
+                       range->freq[k].e = 1;
+                       k++;
+               }
+               
+               if (k >= IW_MAX_FREQUENCIES)
+                       break;
+       }
+       range->num_frequency = k;
+       range->sensitivity = 3;
+
+       if (priv->has_wep) {
+               range->max_encoding_tokens = ORINOCO_MAX_KEYS;
+               range->encoding_size[0] = SMALL_KEY_SIZE;
+               range->num_encoding_sizes = 1;
+
+               if (priv->has_big_wep) {
+                       range->encoding_size[1] = LARGE_KEY_SIZE;
+                       range->num_encoding_sizes = 2;
+               }
+       }
+
+       if (priv->has_wpa)
+               range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
+
+       if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
+               /* Quality stats meaningless in ad-hoc mode */
+       } else {
+               range->max_qual.qual = 0x8b - 0x2f;
+               range->max_qual.level = 0x2f - 0x95 - 1;
+               range->max_qual.noise = 0x2f - 0x95 - 1;
+               /* Need to get better values */
+               range->avg_qual.qual = 0x24;
+               range->avg_qual.level = 0xC2;
+               range->avg_qual.noise = 0x9E;
+       }
+
+       err = orinoco_hw_get_bitratelist(priv, &numrates,
+                                        range->bitrate, IW_MAX_BITRATES);
+       if (err)
+               return err;
+       range->num_bitrates = numrates;
+
+       /* Set an indication of the max TCP throughput in bit/s that we can
+        * expect using this interface. May be use for QoS stuff...
+        * Jean II */
+       if (numrates > 2)
+               range->throughput = 5 * 1000 * 1000;    /* ~5 Mb/s */
+       else
+               range->throughput = 1.5 * 1000 * 1000;  /* ~1.5 Mb/s */
+
+       range->min_rts = 0;
+       range->max_rts = 2347;
+       range->min_frag = 256;
+       range->max_frag = 2346;
+
+       range->min_pmp = 0;
+       range->max_pmp = 65535000;
+       range->min_pmt = 0;
+       range->max_pmt = 65535 * 1000;  /* ??? */
+       range->pmp_flags = IW_POWER_PERIOD;
+       range->pmt_flags = IW_POWER_TIMEOUT;
+       range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
+
+       range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
+       range->retry_flags = IW_RETRY_LIMIT;
+       range->r_time_flags = IW_RETRY_LIFETIME;
+       range->min_retry = 0;
+       range->max_retry = 65535;       /* ??? */
+       range->min_r_time = 0;
+       range->max_r_time = 65535 * 1000;       /* ??? */
+
+       if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
+               range->scan_capa = IW_SCAN_CAPA_ESSID;
+       else
+               range->scan_capa = IW_SCAN_CAPA_NONE;
+
+       /* Event capability (kernel) */
+       IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
+       /* Event capability (driver) */
+       IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
+       IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
+       IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
+       IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
+
+       return 0;
+}
+
+static int orinoco_ioctl_setiwencode(struct net_device *dev,
+                                    struct iw_request_info *info,
+                                    struct iw_point *erq,
+                                    char *keybuf)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int index = (erq->flags & IW_ENCODE_INDEX) - 1;
+       int setindex = priv->tx_key;
+       int encode_alg = priv->encode_alg;
+       int restricted = priv->wep_restrict;
+       u16 xlen = 0;
+       int err = -EINPROGRESS;         /* Call commit handler */
+       unsigned long flags;
+
+       if (! priv->has_wep)
+               return -EOPNOTSUPP;
+
+       if (erq->pointer) {
+               /* We actually have a key to set - check its length */
+               if (erq->length > LARGE_KEY_SIZE)
+                       return -E2BIG;
+
+               if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep )
+                       return -E2BIG;
+       }
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       /* Clear any TKIP key we have */
+       if ((priv->has_wpa) && (priv->encode_alg == IW_ENCODE_ALG_TKIP))
+               (void) orinoco_clear_tkip_key(priv, setindex);
+
+       if (erq->length > 0) {
+               if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
+                       index = priv->tx_key;
+
+               /* Adjust key length to a supported value */
+               if (erq->length > SMALL_KEY_SIZE) {
+                       xlen = LARGE_KEY_SIZE;
+               } else if (erq->length > 0) {
+                       xlen = SMALL_KEY_SIZE;
+               } else
+                       xlen = 0;
+
+               /* Switch on WEP if off */
+               if ((encode_alg != IW_ENCODE_ALG_WEP) && (xlen > 0)) {
+                       setindex = index;
+                       encode_alg = IW_ENCODE_ALG_WEP;
+               }
+       } else {
+               /* Important note : if the user do "iwconfig eth0 enc off",
+                * we will arrive there with an index of -1. This is valid
+                * but need to be taken care off... Jean II */
+               if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
+                       if((index != -1) || (erq->flags == 0)) {
+                               err = -EINVAL;
+                               goto out;
+                       }
+               } else {
+                       /* Set the index : Check that the key is valid */
+                       if(priv->keys[index].len == 0) {
+                               err = -EINVAL;
+                               goto out;
+                       }
+                       setindex = index;
+               }
+       }
+
+       if (erq->flags & IW_ENCODE_DISABLED)
+               encode_alg = IW_ENCODE_ALG_NONE;
+       if (erq->flags & IW_ENCODE_OPEN)
+               restricted = 0;
+       if (erq->flags & IW_ENCODE_RESTRICTED)
+               restricted = 1;
+
+       if (erq->pointer && erq->length > 0) {
+               priv->keys[index].len = cpu_to_le16(xlen);
+               memset(priv->keys[index].data, 0,
+                      sizeof(priv->keys[index].data));
+               memcpy(priv->keys[index].data, keybuf, erq->length);
+       }
+       priv->tx_key = setindex;
+
+       /* Try fast key change if connected and only keys are changed */
+       if ((priv->encode_alg == encode_alg) &&
+           (priv->wep_restrict == restricted) &&
+           netif_carrier_ok(dev)) {
+               err = __orinoco_hw_setup_wepkeys(priv);
+               /* No need to commit if successful */
+               goto out;
+       }
+
+       priv->encode_alg = encode_alg;
+       priv->wep_restrict = restricted;
+
+ out:
+       orinoco_unlock(priv, &flags);
+
+       return err;
+}
+
+static int orinoco_ioctl_getiwencode(struct net_device *dev,
+                                    struct iw_request_info *info,
+                                    struct iw_point *erq,
+                                    char *keybuf)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int index = (erq->flags & IW_ENCODE_INDEX) - 1;
+       u16 xlen = 0;
+       unsigned long flags;
+
+       if (! priv->has_wep)
+               return -EOPNOTSUPP;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
+               index = priv->tx_key;
+
+       erq->flags = 0;
+       if (!priv->encode_alg)
+               erq->flags |= IW_ENCODE_DISABLED;
+       erq->flags |= index + 1;
+
+       if (priv->wep_restrict)
+               erq->flags |= IW_ENCODE_RESTRICTED;
+       else
+               erq->flags |= IW_ENCODE_OPEN;
+
+       xlen = le16_to_cpu(priv->keys[index].len);
+
+       erq->length = xlen;
+
+       memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
+
+       orinoco_unlock(priv, &flags);
+       return 0;
+}
+
+static int orinoco_ioctl_setessid(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 struct iw_point *erq,
+                                 char *essidbuf)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
+
+       /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
+        * anyway... - Jean II */
+
+       /* Hum... Should not use Wireless Extension constant (may change),
+        * should use our own... - Jean II */
+       if (erq->length > IW_ESSID_MAX_SIZE)
+               return -E2BIG;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       /* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
+       memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
+
+       /* If not ANY, get the new ESSID */
+       if (erq->flags) {
+               memcpy(priv->desired_essid, essidbuf, erq->length);
+       }
+
+       orinoco_unlock(priv, &flags);
+
+       return -EINPROGRESS;            /* Call commit handler */
+}
+
+static int orinoco_ioctl_getessid(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 struct iw_point *erq,
+                                 char *essidbuf)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int active;
+       int err = 0;
+       unsigned long flags;
+
+       if (netif_running(dev)) {
+               err = orinoco_hw_get_essid(priv, &active, essidbuf);
+               if (err < 0)
+                       return err;
+               erq->length = err;
+       } else {
+               if (orinoco_lock(priv, &flags) != 0)
+                       return -EBUSY;
+               memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
+               erq->length = strlen(priv->desired_essid);
+               orinoco_unlock(priv, &flags);
+       }
+
+       erq->flags = 1;
+
+       return 0;
+}
+
+static int orinoco_ioctl_setnick(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_point *nrq,
+                                char *nickbuf)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
+
+       if (nrq->length > IW_ESSID_MAX_SIZE)
+               return -E2BIG;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       memset(priv->nick, 0, sizeof(priv->nick));
+       memcpy(priv->nick, nickbuf, nrq->length);
+
+       orinoco_unlock(priv, &flags);
+
+       return -EINPROGRESS;            /* Call commit handler */
+}
+
+static int orinoco_ioctl_getnick(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_point *nrq,
+                                char *nickbuf)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
+       orinoco_unlock(priv, &flags);
+
+       nrq->length = strlen(priv->nick);
+
+       return 0;
+}
+
+static int orinoco_ioctl_setfreq(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_freq *frq,
+                                char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int chan = -1;
+       unsigned long flags;
+       int err = -EINPROGRESS;         /* Call commit handler */
+
+       /* In infrastructure mode the AP sets the channel */
+       if (priv->iw_mode == IW_MODE_INFRA)
+               return -EBUSY;
+
+       if ( (frq->e == 0) && (frq->m <= 1000) ) {
+               /* Setting by channel number */
+               chan = frq->m;
+       } else {
+               /* Setting by frequency - search the table */
+               int mult = 1;
+               int i;
+
+               for (i = 0; i < (6 - frq->e); i++)
+                       mult *= 10;
+
+               for (i = 0; i < NUM_CHANNELS; i++)
+                       if (frq->m == (channel_frequency[i] * mult))
+                               chan = i+1;
+       }
+
+       if ( (chan < 1) || (chan > NUM_CHANNELS) ||
+            ! (priv->channel_mask & (1 << (chan-1)) ) )
+               return -EINVAL;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       priv->channel = chan;
+       if (priv->iw_mode == IW_MODE_MONITOR) {
+               /* Fast channel change - no commit if successful */
+               hermes_t *hw = &priv->hw;
+               err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+                                           HERMES_TEST_SET_CHANNEL,
+                                       chan, NULL);
+       }
+       orinoco_unlock(priv, &flags);
+
+       return err;
+}
+
+static int orinoco_ioctl_getfreq(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_freq *frq,
+                                char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int tmp;
+
+       /* Locking done in there */
+       tmp = orinoco_hw_get_freq(priv);
+       if (tmp < 0) {
+               return tmp;
+       }
+
+       frq->m = tmp;
+       frq->e = 1;
+
+       return 0;
+}
+
+static int orinoco_ioctl_getsens(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_param *srq,
+                                char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       hermes_t *hw = &priv->hw;
+       u16 val;
+       int err;
+       unsigned long flags;
+
+       if (!priv->has_sensitivity)
+               return -EOPNOTSUPP;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+       err = hermes_read_wordrec(hw, USER_BAP,
+                                 HERMES_RID_CNFSYSTEMSCALE, &val);
+       orinoco_unlock(priv, &flags);
+
+       if (err)
+               return err;
+
+       srq->value = val;
+       srq->fixed = 0; /* auto */
+
+       return 0;
+}
+
+static int orinoco_ioctl_setsens(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_param *srq,
+                                char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int val = srq->value;
+       unsigned long flags;
+
+       if (!priv->has_sensitivity)
+               return -EOPNOTSUPP;
+
+       if ((val < 1) || (val > 3))
+               return -EINVAL;
+       
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+       priv->ap_density = val;
+       orinoco_unlock(priv, &flags);
+
+       return -EINPROGRESS;            /* Call commit handler */
+}
+
+static int orinoco_ioctl_setrts(struct net_device *dev,
+                               struct iw_request_info *info,
+                               struct iw_param *rrq,
+                               char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int val = rrq->value;
+       unsigned long flags;
+
+       if (rrq->disabled)
+               val = 2347;
+
+       if ( (val < 0) || (val > 2347) )
+               return -EINVAL;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       priv->rts_thresh = val;
+       orinoco_unlock(priv, &flags);
+
+       return -EINPROGRESS;            /* Call commit handler */
+}
+
+static int orinoco_ioctl_getrts(struct net_device *dev,
+                               struct iw_request_info *info,
+                               struct iw_param *rrq,
+                               char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+
+       rrq->value = priv->rts_thresh;
+       rrq->disabled = (rrq->value == 2347);
+       rrq->fixed = 1;
+
+       return 0;
+}
+
+static int orinoco_ioctl_setfrag(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_param *frq,
+                                char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int err = -EINPROGRESS;         /* Call commit handler */
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       if (priv->has_mwo) {
+               if (frq->disabled)
+                       priv->mwo_robust = 0;
+               else {
+                       if (frq->fixed)
+                               printk(KERN_WARNING "%s: Fixed fragmentation is "
+                                      "not supported on this firmware. "
+                                      "Using MWO robust instead.\n", dev->name);
+                       priv->mwo_robust = 1;
+               }
+       } else {
+               if (frq->disabled)
+                       priv->frag_thresh = 2346;
+               else {
+                       if ( (frq->value < 256) || (frq->value > 2346) )
+                               err = -EINVAL;
+                       else
+                               priv->frag_thresh = frq->value & ~0x1; /* must be even */
+               }
+       }
+
+       orinoco_unlock(priv, &flags);
+
+       return err;
+}
+
+static int orinoco_ioctl_getfrag(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_param *frq,
+                                char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       hermes_t *hw = &priv->hw;
+       int err;
+       u16 val;
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+       
+       if (priv->has_mwo) {
+               err = hermes_read_wordrec(hw, USER_BAP,
+                                         HERMES_RID_CNFMWOROBUST_AGERE,
+                                         &val);
+               if (err)
+                       val = 0;
+
+               frq->value = val ? 2347 : 0;
+               frq->disabled = ! val;
+               frq->fixed = 0;
+       } else {
+               err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+                                         &val);
+               if (err)
+                       val = 0;
+
+               frq->value = val;
+               frq->disabled = (val >= 2346);
+               frq->fixed = 1;
+       }
+
+       orinoco_unlock(priv, &flags);
+       
+       return err;
+}
+
+static int orinoco_ioctl_setrate(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_param *rrq,
+                                char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int ratemode = -1;
+       int bitrate; /* 100s of kilobits */
+       int i;
+       unsigned long flags;
+       
+       /* As the user space doesn't know our highest rate, it uses -1
+        * to ask us to set the highest rate.  Test it using "iwconfig
+        * ethX rate auto" - Jean II */
+       if (rrq->value == -1)
+               bitrate = 110;
+       else {
+               if (rrq->value % 100000)
+                       return -EINVAL;
+               bitrate = rrq->value / 100000;
+       }
+
+       if ( (bitrate != 10) && (bitrate != 20) &&
+            (bitrate != 55) && (bitrate != 110) )
+               return -EINVAL;
+
+       for (i = 0; i < BITRATE_TABLE_SIZE; i++)
+               if ( (bitrate_table[i].bitrate == bitrate) &&
+                    (bitrate_table[i].automatic == ! rrq->fixed) ) {
+                       ratemode = i;
+                       break;
+               }
+       
+       if (ratemode == -1)
+               return -EINVAL;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+       priv->bitratemode = ratemode;
+       orinoco_unlock(priv, &flags);
+
+       return -EINPROGRESS;
+}
+
+static int orinoco_ioctl_getrate(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_param *rrq,
+                                char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       hermes_t *hw = &priv->hw;
+       int err = 0;
+       int ratemode;
+       int i;
+       u16 val;
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       ratemode = priv->bitratemode;
+
+       BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
+
+       rrq->value = bitrate_table[ratemode].bitrate * 100000;
+       rrq->fixed = ! bitrate_table[ratemode].automatic;
+       rrq->disabled = 0;
+
+       /* If the interface is running we try to find more about the
+          current mode */
+       if (netif_running(dev)) {
+               err = hermes_read_wordrec(hw, USER_BAP,
+                                         HERMES_RID_CURRENTTXRATE, &val);
+               if (err)
+                       goto out;
+               
+               switch (priv->firmware_type) {
+               case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
+                       /* Note : in Lucent firmware, the return value of
+                        * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
+                        * and therefore is totally different from the
+                        * encoding of HERMES_RID_CNFTXRATECONTROL.
+                        * Don't forget that 6Mb/s is really 5.5Mb/s */
+                       if (val == 6)
+                               rrq->value = 5500000;
+                       else
+                               rrq->value = val * 1000000;
+                       break;
+               case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
+               case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
+                       for (i = 0; i < BITRATE_TABLE_SIZE; i++)
+                               if (bitrate_table[i].intersil_txratectrl == val) {
+                                       ratemode = i;
+                                       break;
+                               }
+                       if (i >= BITRATE_TABLE_SIZE)
+                               printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
+                                      dev->name, val);
+
+                       rrq->value = bitrate_table[ratemode].bitrate * 100000;
+                       break;
+               default:
+                       BUG();
+               }
+       }
+
+ out:
+       orinoco_unlock(priv, &flags);
+
+       return err;
+}
+
+static int orinoco_ioctl_setpower(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 struct iw_param *prq,
+                                 char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int err = -EINPROGRESS;         /* Call commit handler */
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       if (prq->disabled) {
+               priv->pm_on = 0;
+       } else {
+               switch (prq->flags & IW_POWER_MODE) {
+               case IW_POWER_UNICAST_R:
+                       priv->pm_mcast = 0;
+                       priv->pm_on = 1;
+                       break;
+               case IW_POWER_ALL_R:
+                       priv->pm_mcast = 1;
+                       priv->pm_on = 1;
+                       break;
+               case IW_POWER_ON:
+                       /* No flags : but we may have a value - Jean II */
+                       break;
+               default:
+                       err = -EINVAL;
+                       goto out;
+               }
+               
+               if (prq->flags & IW_POWER_TIMEOUT) {
+                       priv->pm_on = 1;
+                       priv->pm_timeout = prq->value / 1000;
+               }
+               if (prq->flags & IW_POWER_PERIOD) {
+                       priv->pm_on = 1;
+                       priv->pm_period = prq->value / 1000;
+               }
+               /* It's valid to not have a value if we are just toggling
+                * the flags... Jean II */
+               if(!priv->pm_on) {
+                       err = -EINVAL;
+                       goto out;
+               }                       
+       }
+
+ out:
+       orinoco_unlock(priv, &flags);
+
+       return err;
+}
+
+static int orinoco_ioctl_getpower(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 struct iw_param *prq,
+                                 char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       hermes_t *hw = &priv->hw;
+       int err = 0;
+       u16 enable, period, timeout, mcast;
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+       
+       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
+       if (err)
+               goto out;
+
+       err = hermes_read_wordrec(hw, USER_BAP,
+                                 HERMES_RID_CNFMAXSLEEPDURATION, &period);
+       if (err)
+               goto out;
+
+       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
+       if (err)
+               goto out;
+
+       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
+       if (err)
+               goto out;
+
+       prq->disabled = !enable;
+       /* Note : by default, display the period */
+       if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
+               prq->flags = IW_POWER_TIMEOUT;
+               prq->value = timeout * 1000;
+       } else {
+               prq->flags = IW_POWER_PERIOD;
+               prq->value = period * 1000;
+       }
+       if (mcast)
+               prq->flags |= IW_POWER_ALL_R;
+       else
+               prq->flags |= IW_POWER_UNICAST_R;
+
+ out:
+       orinoco_unlock(priv, &flags);
+
+       return err;
+}
+
+static int orinoco_ioctl_set_encodeext(struct net_device *dev,
+                                      struct iw_request_info *info,
+                                      union iwreq_data *wrqu,
+                                      char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct iw_point *encoding = &wrqu->encoding;
+       struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+       int idx, alg = ext->alg, set_key = 1;
+       unsigned long flags;
+       int err = -EINVAL;
+       u16 key_len;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       /* Determine and validate the key index */
+       idx = encoding->flags & IW_ENCODE_INDEX;
+       if (idx) {
+               if ((idx < 1) || (idx > 4))
+                       goto out;
+               idx--;
+       } else
+               idx = priv->tx_key;
+
+       if (encoding->flags & IW_ENCODE_DISABLED)
+           alg = IW_ENCODE_ALG_NONE;
+
+       if (priv->has_wpa && (alg != IW_ENCODE_ALG_TKIP)) {
+               /* Clear any TKIP TX key we had */
+               (void) orinoco_clear_tkip_key(priv, priv->tx_key);
+       }
+
+       if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+               priv->tx_key = idx;
+               set_key = ((alg == IW_ENCODE_ALG_TKIP) ||
+                          (ext->key_len > 0)) ? 1 : 0;
+       }
+
+       if (set_key) {
+               /* Set the requested key first */
+               switch (alg) {
+               case IW_ENCODE_ALG_NONE:
+                       priv->encode_alg = alg;
+                       priv->keys[idx].len = 0;
+                       break;
+
+               case IW_ENCODE_ALG_WEP:
+                       if (ext->key_len > SMALL_KEY_SIZE)
+                               key_len = LARGE_KEY_SIZE;
+                       else if (ext->key_len > 0)
+                               key_len = SMALL_KEY_SIZE;
+                       else
+                               goto out;
+
+                       priv->encode_alg = alg;
+                       priv->keys[idx].len = cpu_to_le16(key_len);
+
+                       key_len = min(ext->key_len, key_len);
+
+                       memset(priv->keys[idx].data, 0, ORINOCO_MAX_KEY_SIZE);
+                       memcpy(priv->keys[idx].data, ext->key, key_len);
+                       break;
+
+               case IW_ENCODE_ALG_TKIP:
+               {
+                       hermes_t *hw = &priv->hw;
+                       u8 *tkip_iv = NULL;
+
+                       if (!priv->has_wpa ||
+                           (ext->key_len > sizeof(priv->tkip_key[0])))
+                               goto out;
+
+                       priv->encode_alg = alg;
+                       memset(&priv->tkip_key[idx], 0,
+                              sizeof(priv->tkip_key[idx]));
+                       memcpy(&priv->tkip_key[idx], ext->key, ext->key_len);
+
+                       if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
+                               tkip_iv = &ext->rx_seq[0];
+
+                       err = __orinoco_hw_set_tkip_key(hw, idx,
+                                ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
+                                (u8 *) &priv->tkip_key[idx],
+                                tkip_iv, NULL);
+                       if (err)
+                               printk(KERN_ERR "%s: Error %d setting TKIP key"
+                                      "\n", dev->name, err);
+
+                       goto out;
+               }
+               default:
+                       goto out;
+               }
+       }
+       err = -EINPROGRESS;
+ out:
+       orinoco_unlock(priv, &flags);
+
+       return err;
+}
+
+static int orinoco_ioctl_get_encodeext(struct net_device *dev,
+                                      struct iw_request_info *info,
+                                      union iwreq_data *wrqu,
+                                      char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct iw_point *encoding = &wrqu->encoding;
+       struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+       int idx, max_key_len;
+       unsigned long flags;
+       int err;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       err = -EINVAL;
+       max_key_len = encoding->length - sizeof(*ext);
+       if (max_key_len < 0)
+               goto out;
+
+       idx = encoding->flags & IW_ENCODE_INDEX;
+       if (idx) {
+               if ((idx < 1) || (idx > 4))
+                       goto out;
+               idx--;
+       } else
+               idx = priv->tx_key;
+
+       encoding->flags = idx + 1;
+       memset(ext, 0, sizeof(*ext));
+
+       ext->alg = priv->encode_alg;
+       switch (priv->encode_alg) {
+       case IW_ENCODE_ALG_NONE:
+               ext->key_len = 0;
+               encoding->flags |= IW_ENCODE_DISABLED;
+               break;
+       case IW_ENCODE_ALG_WEP:
+               ext->key_len = min_t(u16, le16_to_cpu(priv->keys[idx].len),
+                                    max_key_len);
+               memcpy(ext->key, priv->keys[idx].data, ext->key_len);
+               encoding->flags |= IW_ENCODE_ENABLED;
+               break;
+       case IW_ENCODE_ALG_TKIP:
+               ext->key_len = min_t(u16, sizeof(struct orinoco_tkip_key),
+                                    max_key_len);
+               memcpy(ext->key, &priv->tkip_key[idx], ext->key_len);
+               encoding->flags |= IW_ENCODE_ENABLED;
+               break;
+       }
+
+       err = 0;
+ out:
+       orinoco_unlock(priv, &flags);
+
+       return err;
+}
+
+static int orinoco_ioctl_set_auth(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 union iwreq_data *wrqu, char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       hermes_t *hw = &priv->hw;
+       struct iw_param *param = &wrqu->param;
+       unsigned long flags;
+       int ret = -EINPROGRESS;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       switch (param->flags & IW_AUTH_INDEX) {
+       case IW_AUTH_WPA_VERSION:
+       case IW_AUTH_CIPHER_PAIRWISE:
+       case IW_AUTH_CIPHER_GROUP:
+       case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+       case IW_AUTH_PRIVACY_INVOKED:
+       case IW_AUTH_DROP_UNENCRYPTED:
+               /*
+                * orinoco does not use these parameters
+                */
+               break;
+
+       case IW_AUTH_KEY_MGMT:
+               /* wl_lkm implies value 2 == PSK for Hermes I
+                * which ties in with WEXT
+                * no other hints tho :(
+                */
+               priv->key_mgmt = param->value;
+               break;
+
+       case IW_AUTH_TKIP_COUNTERMEASURES:
+               /* When countermeasures are enabled, shut down the
+                * card; when disabled, re-enable the card. This must
+                * take effect immediately.
+                *
+                * TODO: Make sure that the EAPOL message is getting
+                *       out before card disabled
+                */
+               if (param->value) {
+                       priv->tkip_cm_active = 1;
+                       ret = hermes_enable_port(hw, 0);
+               } else {
+                       priv->tkip_cm_active = 0;
+                       ret = hermes_disable_port(hw, 0);
+               }
+               break;
+
+       case IW_AUTH_80211_AUTH_ALG:
+               if (param->value & IW_AUTH_ALG_SHARED_KEY)
+                       priv->wep_restrict = 1;
+               else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
+                       priv->wep_restrict = 0;
+               else
+                       ret = -EINVAL;
+               break;
+
+       case IW_AUTH_WPA_ENABLED:
+               if (priv->has_wpa) {
+                       priv->wpa_enabled = param->value ? 1 : 0;
+               } else {
+                       if (param->value)
+                               ret = -EOPNOTSUPP;
+                       /* else silently accept disable of WPA */
+                       priv->wpa_enabled = 0;
+               }
+               break;
+
+       default:
+               ret = -EOPNOTSUPP;
+       }
+
+       orinoco_unlock(priv, &flags);
+       return ret;
+}
+
+static int orinoco_ioctl_get_auth(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 union iwreq_data *wrqu, char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct iw_param *param = &wrqu->param;
+       unsigned long flags;
+       int ret = 0;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       switch (param->flags & IW_AUTH_INDEX) {
+       case IW_AUTH_KEY_MGMT:
+               param->value = priv->key_mgmt;
+               break;
+
+       case IW_AUTH_TKIP_COUNTERMEASURES:
+               param->value = priv->tkip_cm_active;
+               break;
+
+       case IW_AUTH_80211_AUTH_ALG:
+               if (priv->wep_restrict)
+                       param->value = IW_AUTH_ALG_SHARED_KEY;
+               else
+                       param->value = IW_AUTH_ALG_OPEN_SYSTEM;
+               break;
+
+       case IW_AUTH_WPA_ENABLED:
+               param->value = priv->wpa_enabled;
+               break;
+
+       default:
+               ret = -EOPNOTSUPP;
+       }
+
+       orinoco_unlock(priv, &flags);
+       return ret;
+}
+
+static int orinoco_ioctl_set_genie(struct net_device *dev,
+                                  struct iw_request_info *info,
+                                  union iwreq_data *wrqu, char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       u8 *buf;
+       unsigned long flags;
+       int err = 0;
+
+       /* cut off at IEEE80211_MAX_DATA_LEN */
+       if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) ||
+           (wrqu->data.length && (extra == NULL)))
+               return -EINVAL;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       if (wrqu->data.length) {
+               buf = kmalloc(wrqu->data.length, GFP_KERNEL);
+               if (buf == NULL) {
+                       err = -ENOMEM;
+                       goto out;
+               }
+
+               memcpy(buf, extra, wrqu->data.length);
+               kfree(priv->wpa_ie);
+               priv->wpa_ie = buf;
+               priv->wpa_ie_len = wrqu->data.length;
+       } else {
+               kfree(priv->wpa_ie);
+               priv->wpa_ie = NULL;
+               priv->wpa_ie_len = 0;
+       }
+
+       if (priv->wpa_ie) {
+               /* Looks like wl_lkm wants to check the auth alg, and
+                * somehow pass it to the firmware.
+                * Instead it just calls the key mgmt rid
+                *   - we do this in set auth.
+                */
+       }
+
+out:
+       orinoco_unlock(priv, &flags);
+       return err;
+}
+
+static int orinoco_ioctl_get_genie(struct net_device *dev,
+                                  struct iw_request_info *info,
+                                  union iwreq_data *wrqu, char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
+       int err = 0;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       if ((priv->wpa_ie_len == 0) || (priv->wpa_ie == NULL)) {
+               wrqu->data.length = 0;
+               goto out;
+       }
+
+       if (wrqu->data.length < priv->wpa_ie_len) {
+               err = -E2BIG;
+               goto out;
+       }
+
+       wrqu->data.length = priv->wpa_ie_len;
+       memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
+
+out:
+       orinoco_unlock(priv, &flags);
+       return err;
+}
+
+static int orinoco_ioctl_set_mlme(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 union iwreq_data *wrqu, char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       hermes_t *hw = &priv->hw;
+       struct iw_mlme *mlme = (struct iw_mlme *)extra;
+       unsigned long flags;
+       int ret = 0;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       switch (mlme->cmd) {
+       case IW_MLME_DEAUTH:
+               /* silently ignore */
+               break;
+
+       case IW_MLME_DISASSOC:
+       {
+               struct {
+                       u8 addr[ETH_ALEN];
+                       __le16 reason_code;
+               } __attribute__ ((packed)) buf;
+
+               memcpy(buf.addr, mlme->addr.sa_data, ETH_ALEN);
+               buf.reason_code = cpu_to_le16(mlme->reason_code);
+               ret = HERMES_WRITE_RECORD(hw, USER_BAP,
+                                         HERMES_RID_CNFDISASSOCIATE,
+                                         &buf);
+               break;
+       }
+       default:
+               ret = -EOPNOTSUPP;
+       }
+
+       orinoco_unlock(priv, &flags);
+       return ret;
+}
+
+static int orinoco_ioctl_getretry(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 struct iw_param *rrq,
+                                 char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       hermes_t *hw = &priv->hw;
+       int err = 0;
+       u16 short_limit, long_limit, lifetime;
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+       
+       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
+                                 &short_limit);
+       if (err)
+               goto out;
+
+       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
+                                 &long_limit);
+       if (err)
+               goto out;
+
+       err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
+                                 &lifetime);
+       if (err)
+               goto out;
+
+       rrq->disabled = 0;              /* Can't be disabled */
+
+       /* Note : by default, display the retry number */
+       if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
+               rrq->flags = IW_RETRY_LIFETIME;
+               rrq->value = lifetime * 1000;   /* ??? */
+       } else {
+               /* By default, display the min number */
+               if ((rrq->flags & IW_RETRY_LONG)) {
+                       rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
+                       rrq->value = long_limit;
+               } else {
+                       rrq->flags = IW_RETRY_LIMIT;
+                       rrq->value = short_limit;
+                       if(short_limit != long_limit)
+                               rrq->flags |= IW_RETRY_SHORT;
+               }
+       }
+
+ out:
+       orinoco_unlock(priv, &flags);
+
+       return err;
+}
+
+static int orinoco_ioctl_reset(struct net_device *dev,
+                              struct iw_request_info *info,
+                              void *wrqu,
+                              char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+
+       if (! capable(CAP_NET_ADMIN))
+               return -EPERM;
+
+       if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
+               printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
+
+               /* Firmware reset */
+               orinoco_reset(&priv->reset_work);
+       } else {
+               printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
+
+               schedule_work(&priv->reset_work);
+       }
+
+       return 0;
+}
+
+static int orinoco_ioctl_setibssport(struct net_device *dev,
+                                    struct iw_request_info *info,
+                                    void *wrqu,
+                                    char *extra)
+
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int val = *( (int *) extra );
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       priv->ibss_port = val ;
+
+       /* Actually update the mode we are using */
+       set_port_type(priv);
+
+       orinoco_unlock(priv, &flags);
+       return -EINPROGRESS;            /* Call commit handler */
+}
+
+static int orinoco_ioctl_getibssport(struct net_device *dev,
+                                    struct iw_request_info *info,
+                                    void *wrqu,
+                                    char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int *val = (int *) extra;
+
+       *val = priv->ibss_port;
+       return 0;
+}
+
+static int orinoco_ioctl_setport3(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 void *wrqu,
+                                 char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int val = *( (int *) extra );
+       int err = 0;
+       unsigned long flags;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       switch (val) {
+       case 0: /* Try to do IEEE ad-hoc mode */
+               if (! priv->has_ibss) {
+                       err = -EINVAL;
+                       break;
+               }
+               priv->prefer_port3 = 0;
+                       
+               break;
+
+       case 1: /* Try to do Lucent proprietary ad-hoc mode */
+               if (! priv->has_port3) {
+                       err = -EINVAL;
+                       break;
+               }
+               priv->prefer_port3 = 1;
+               break;
+
+       default:
+               err = -EINVAL;
+       }
+
+       if (! err) {
+               /* Actually update the mode we are using */
+               set_port_type(priv);
+               err = -EINPROGRESS;
+       }
+
+       orinoco_unlock(priv, &flags);
+
+       return err;
+}
+
+static int orinoco_ioctl_getport3(struct net_device *dev,
+                                 struct iw_request_info *info,
+                                 void *wrqu,
+                                 char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int *val = (int *) extra;
+
+       *val = priv->prefer_port3;
+       return 0;
+}
+
+static int orinoco_ioctl_setpreamble(struct net_device *dev,
+                                    struct iw_request_info *info,
+                                    void *wrqu,
+                                    char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
+       int val;
+
+       if (! priv->has_preamble)
+               return -EOPNOTSUPP;
+
+       /* 802.11b has recently defined some short preamble.
+        * Basically, the Phy header has been reduced in size.
+        * This increase performance, especially at high rates
+        * (the preamble is transmitted at 1Mb/s), unfortunately
+        * this give compatibility troubles... - Jean II */
+       val = *( (int *) extra );
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       if (val)
+               priv->preamble = 1;
+       else
+               priv->preamble = 0;
+
+       orinoco_unlock(priv, &flags);
+
+       return -EINPROGRESS;            /* Call commit handler */
+}
+
+static int orinoco_ioctl_getpreamble(struct net_device *dev,
+                                    struct iw_request_info *info,
+                                    void *wrqu,
+                                    char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int *val = (int *) extra;
+
+       if (! priv->has_preamble)
+               return -EOPNOTSUPP;
+
+       *val = priv->preamble;
+       return 0;
+}
+
+/* ioctl interface to hermes_read_ltv()
+ * To use with iwpriv, pass the RID as the token argument, e.g.
+ * iwpriv get_rid [0xfc00]
+ * At least Wireless Tools 25 is required to use iwpriv.
+ * For Wireless Tools 25 and 26 append "dummy" are the end. */
+static int orinoco_ioctl_getrid(struct net_device *dev,
+                               struct iw_request_info *info,
+                               struct iw_point *data,
+                               char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       hermes_t *hw = &priv->hw;
+       int rid = data->flags;
+       u16 length;
+       int err;
+       unsigned long flags;
+
+       /* It's a "get" function, but we don't want users to access the
+        * WEP key and other raw firmware data */
+       if (! capable(CAP_NET_ADMIN))
+               return -EPERM;
+
+       if (rid < 0xfc00 || rid > 0xffff)
+               return -EINVAL;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
+                             extra);
+       if (err)
+               goto out;
+
+       data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
+                            MAX_RID_LEN);
+
+ out:
+       orinoco_unlock(priv, &flags);
+       return err;
+}
+
+/* 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_point *srq,
+                                char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       hermes_t *hw = &priv->hw;
+       struct iw_scan_req *si = (struct iw_scan_req *) extra;
+       int err = 0;
+       unsigned long flags;
+
+       /* Note : you may have realised that, as this is a SET operation,
+        * this is privileged and therefore a normal user can't
+        * perform scanning.
+        * This is not an error, while the device perform scanning,
+        * traffic doesn't flow, so it's a perfect DoS...
+        * Jean II */
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       /* Scanning with port 0 disabled would fail */
+       if (!netif_running(dev)) {
+               err = -ENETDOWN;
+               goto out;
+       }
+
+       /* In monitor mode, the scan results are always empty.
+        * Probe responses are passed to the driver as received
+        * frames and could be processed in software. */
+       if (priv->iw_mode == IW_MODE_MONITOR) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       /* Note : because we don't lock out the irq handler, the way
+        * we access scan variables in priv is critical.
+        *      o scan_inprogress : not touched by irq handler
+        *      o scan_mode : not touched by irq handler
+        * Before modifying anything on those variables, please think hard !
+        * Jean II */
+
+       /* Save flags */
+       priv->scan_mode = srq->flags;
+
+       /* Always trigger scanning, even if it's in progress.
+        * This way, if the info frame get lost, we will recover somewhat
+        * gracefully  - Jean II */
+
+       if (priv->has_hostscan) {
+               switch (priv->firmware_type) {
+               case FIRMWARE_TYPE_SYMBOL:
+                       err = hermes_write_wordrec(hw, USER_BAP,
+                                                  HERMES_RID_CNFHOSTSCAN_SYMBOL,
+                                                  HERMES_HOSTSCAN_SYMBOL_ONCE |
+                                                  HERMES_HOSTSCAN_SYMBOL_BCAST);
+                       break;
+               case FIRMWARE_TYPE_INTERSIL: {
+                       __le16 req[3];
+
+                       req[0] = cpu_to_le16(0x3fff);   /* All channels */
+                       req[1] = cpu_to_le16(0x0001);   /* rate 1 Mbps */
+                       req[2] = 0;                     /* Any ESSID */
+                       err = HERMES_WRITE_RECORD(hw, USER_BAP,
+                                                 HERMES_RID_CNFHOSTSCAN, &req);
+               }
+               break;
+               case FIRMWARE_TYPE_AGERE:
+                       if (priv->scan_mode & IW_SCAN_THIS_ESSID) {
+                               struct hermes_idstring idbuf;
+                               size_t len = min(sizeof(idbuf.val),
+                                                (size_t) si->essid_len);
+                               idbuf.len = cpu_to_le16(len);
+                               memcpy(idbuf.val, si->essid, len);
+
+                               err = hermes_write_ltv(hw, USER_BAP,
+                                              HERMES_RID_CNFSCANSSID_AGERE,
+                                              HERMES_BYTES_TO_RECLEN(len + 2),
+                                              &idbuf);
+                       } else
+                               err = hermes_write_wordrec(hw, USER_BAP,
+                                                  HERMES_RID_CNFSCANSSID_AGERE,
+                                                  0);  /* Any ESSID */
+                       if (err)
+                               break;
+
+                       if (priv->has_ext_scan) {
+                               /* Clear scan results at the start of
+                                * an extended scan */
+                               orinoco_clear_scan_results(priv,
+                                               msecs_to_jiffies(15000));
+
+                               /* TODO: Is this available on older firmware?
+                                *   Can we use it to scan specific channels
+                                *   for IW_SCAN_THIS_FREQ? */
+                               err = hermes_write_wordrec(hw, USER_BAP,
+                                               HERMES_RID_CNFSCANCHANNELS2GHZ,
+                                               0x7FFF);
+                               if (err)
+                                       goto out;
+
+                               err = hermes_inquire(hw,
+                                                    HERMES_INQ_CHANNELINFO);
+                       } else
+                               err = hermes_inquire(hw, HERMES_INQ_SCAN);
+                       break;
+               }
+       } else
+               err = hermes_inquire(hw, HERMES_INQ_SCAN);
+
+       /* One more client */
+       if (! err)
+               priv->scan_inprogress = 1;
+
+ out:
+       orinoco_unlock(priv, &flags);
+       return err;
+}
+
+#define MAX_CUSTOM_LEN 64
+
+/* Translate scan data returned from the card to a card independant
+ * format that the Wireless Tools will understand - Jean II */
+static inline char *orinoco_translate_scan(struct net_device *dev,
+                                          struct iw_request_info *info,
+                                          char *current_ev,
+                                          char *end_buf,
+                                          union hermes_scan_info *bss,
+                                          unsigned int last_scanned)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       u16                     capabilities;
+       u16                     channel;
+       struct iw_event         iwe;            /* Temporary buffer */
+       char custom[MAX_CUSTOM_LEN];
+
+       memset(&iwe, 0, sizeof(iwe));
+
+       /* First entry *MUST* be the AP MAC address */
+       iwe.cmd = SIOCGIWAP;
+       iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+       memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
+       current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+                                         &iwe, IW_EV_ADDR_LEN);
+
+       /* Other entries will be displayed in the order we give them */
+
+       /* Add the ESSID */
+       iwe.u.data.length = le16_to_cpu(bss->a.essid_len);
+       if (iwe.u.data.length > 32)
+               iwe.u.data.length = 32;
+       iwe.cmd = SIOCGIWESSID;
+       iwe.u.data.flags = 1;
+       current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+                                         &iwe, bss->a.essid);
+
+       /* Add mode */
+       iwe.cmd = SIOCGIWMODE;
+       capabilities = le16_to_cpu(bss->a.capabilities);
+       if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
+               if (capabilities & WLAN_CAPABILITY_ESS)
+                       iwe.u.mode = IW_MODE_MASTER;
+               else
+                       iwe.u.mode = IW_MODE_ADHOC;
+               current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+                                                 &iwe, IW_EV_UINT_LEN);
+       }
+
+       channel = bss->s.channel;
+       if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
+               /* Add channel and frequency */
+               iwe.cmd = SIOCGIWFREQ;
+               iwe.u.freq.m = channel;
+               iwe.u.freq.e = 0;
+               current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+                                                 &iwe, IW_EV_FREQ_LEN);
+
+               iwe.u.freq.m = channel_frequency[channel-1] * 100000;
+               iwe.u.freq.e = 1;
+               current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+                                                 &iwe, IW_EV_FREQ_LEN);
+       }
+
+       /* Add quality statistics. level and noise in dB. No link quality */
+       iwe.cmd = IWEVQUAL;
+       iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
+       iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95;
+       iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95;
+       /* Wireless tools prior to 27.pre22 will show link quality
+        * anyway, so we provide a reasonable value. */
+       if (iwe.u.qual.level > iwe.u.qual.noise)
+               iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
+       else
+               iwe.u.qual.qual = 0;
+       current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+                                         &iwe, IW_EV_QUAL_LEN);
+
+       /* Add encryption capability */
+       iwe.cmd = SIOCGIWENCODE;
+       if (capabilities & WLAN_CAPABILITY_PRIVACY)
+               iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+       else
+               iwe.u.data.flags = IW_ENCODE_DISABLED;
+       iwe.u.data.length = 0;
+       current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+                                         &iwe, NULL);
+
+       /* Bit rate is not available in Lucent/Agere firmwares */
+       if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
+               char *current_val = current_ev + iwe_stream_lcp_len(info);
+               int i;
+               int step;
+
+               if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
+                       step = 2;
+               else
+                       step = 1;
+
+               iwe.cmd = SIOCGIWRATE;
+               /* Those two flags are ignored... */
+               iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+               /* Max 10 values */
+               for (i = 0; i < 10; i += step) {
+                       /* NULL terminated */
+                       if (bss->p.rates[i] == 0x0)
+                               break;
+                       /* Bit rate given in 500 kb/s units (+ 0x80) */
+                       iwe.u.bitrate.value =
+                               ((bss->p.rates[i] & 0x7f) * 500000);
+                       current_val = iwe_stream_add_value(info, current_ev,
+                                                          current_val,
+                                                          end_buf, &iwe,
+                                                          IW_EV_PARAM_LEN);
+               }
+               /* Check if we added any event */
+               if ((current_val - current_ev) > iwe_stream_lcp_len(info))
+                       current_ev = current_val;
+       }
+
+       /* Beacon interval */
+       iwe.cmd = IWEVCUSTOM;
+       iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+                                    "bcn_int=%d",
+                                    le16_to_cpu(bss->a.beacon_interv));
+       if (iwe.u.data.length)
+               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+                                                 &iwe, custom);
+
+       /* Capabilites */
+       iwe.cmd = IWEVCUSTOM;
+       iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+                                    "capab=0x%04x",
+                                    capabilities);
+       if (iwe.u.data.length)
+               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+                                                 &iwe, custom);
+
+       /* Add EXTRA: Age to display seconds since last beacon/probe response
+        * for given network. */
+       iwe.cmd = IWEVCUSTOM;
+       iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+                                    " Last beacon: %dms ago",
+                                    jiffies_to_msecs(jiffies - last_scanned));
+       if (iwe.u.data.length)
+               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+                                                 &iwe, custom);
+
+       return current_ev;
+}
+
+static inline char *orinoco_translate_ext_scan(struct net_device *dev,
+                                              struct iw_request_info *info,
+                                              char *current_ev,
+                                              char *end_buf,
+                                              struct agere_ext_scan_info *bss,
+                                              unsigned int last_scanned)
+{
+       u16                     capabilities;
+       u16                     channel;
+       struct iw_event         iwe;            /* Temporary buffer */
+       char custom[MAX_CUSTOM_LEN];
+       u8 *ie;
+
+       memset(&iwe, 0, sizeof(iwe));
+
+       /* First entry *MUST* be the AP MAC address */
+       iwe.cmd = SIOCGIWAP;
+       iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+       memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
+       current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+                                         &iwe, IW_EV_ADDR_LEN);
+
+       /* Other entries will be displayed in the order we give them */
+
+       /* Add the ESSID */
+       ie = bss->data;
+       iwe.u.data.length = ie[1];
+       if (iwe.u.data.length) {
+               if (iwe.u.data.length > 32)
+                       iwe.u.data.length = 32;
+               iwe.cmd = SIOCGIWESSID;
+               iwe.u.data.flags = 1;
+               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+                                                 &iwe, &ie[2]);
+       }
+
+       /* Add mode */
+       capabilities = le16_to_cpu(bss->capabilities);
+       if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
+               iwe.cmd = SIOCGIWMODE;
+               if (capabilities & WLAN_CAPABILITY_ESS)
+                       iwe.u.mode = IW_MODE_MASTER;
+               else
+                       iwe.u.mode = IW_MODE_ADHOC;
+               current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+                                                 &iwe, IW_EV_UINT_LEN);
+       }
+
+       ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_DS_PARAMS);
+       channel = ie ? ie[2] : 0;
+       if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
+               /* Add channel and frequency */
+               iwe.cmd = SIOCGIWFREQ;
+               iwe.u.freq.m = channel;
+               iwe.u.freq.e = 0;
+               current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+                                                 &iwe, IW_EV_FREQ_LEN);
+
+               iwe.u.freq.m = channel_frequency[channel-1] * 100000;
+               iwe.u.freq.e = 1;
+               current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+                                                 &iwe, IW_EV_FREQ_LEN);
+       }
+
+       /* Add quality statistics. level and noise in dB. No link quality */
+       iwe.cmd = IWEVQUAL;
+       iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
+       iwe.u.qual.level = bss->level - 0x95;
+       iwe.u.qual.noise = bss->noise - 0x95;
+       /* Wireless tools prior to 27.pre22 will show link quality
+        * anyway, so we provide a reasonable value. */
+       if (iwe.u.qual.level > iwe.u.qual.noise)
+               iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
+       else
+               iwe.u.qual.qual = 0;
+       current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+                                         &iwe, IW_EV_QUAL_LEN);
+
+       /* Add encryption capability */
+       iwe.cmd = SIOCGIWENCODE;
+       if (capabilities & WLAN_CAPABILITY_PRIVACY)
+               iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+       else
+               iwe.u.data.flags = IW_ENCODE_DISABLED;
+       iwe.u.data.length = 0;
+       current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+                                         &iwe, NULL);
+
+       /* WPA IE */
+       ie = orinoco_get_wpa_ie(bss->data, sizeof(bss->data));
+       if (ie) {
+               iwe.cmd = IWEVGENIE;
+               iwe.u.data.length = ie[1] + 2;
+               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+                                                 &iwe, ie);
+       }
+
+       /* RSN IE */
+       ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_RSN);
+       if (ie) {
+               iwe.cmd = IWEVGENIE;
+               iwe.u.data.length = ie[1] + 2;
+               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+                                                 &iwe, ie);
+       }
+
+       ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_SUPP_RATES);
+       if (ie) {
+               char *p = current_ev + iwe_stream_lcp_len(info);
+               int i;
+
+               iwe.cmd = SIOCGIWRATE;
+               /* Those two flags are ignored... */
+               iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+
+               for (i = 2; i < (ie[1] + 2); i++) {
+                       iwe.u.bitrate.value = ((ie[i] & 0x7F) * 500000);
+                       p = iwe_stream_add_value(info, current_ev, p, end_buf,
+                                                &iwe, IW_EV_PARAM_LEN);
+               }
+               /* Check if we added any event */
+               if (p > (current_ev + iwe_stream_lcp_len(info)))
+                       current_ev = p;
+       }
+
+       /* Timestamp */
+       iwe.cmd = IWEVCUSTOM;
+       iwe.u.data.length =
+               snprintf(custom, MAX_CUSTOM_LEN, "tsf=%016llx",
+                        (unsigned long long) le64_to_cpu(bss->timestamp));
+       if (iwe.u.data.length)
+               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+                                                 &iwe, custom);
+
+       /* Beacon interval */
+       iwe.cmd = IWEVCUSTOM;
+       iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+                                    "bcn_int=%d",
+                                    le16_to_cpu(bss->beacon_interval));
+       if (iwe.u.data.length)
+               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+                                                 &iwe, custom);
+
+       /* Capabilites */
+       iwe.cmd = IWEVCUSTOM;
+       iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+                                    "capab=0x%04x",
+                                    capabilities);
+       if (iwe.u.data.length)
+               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+                                                 &iwe, custom);
+
+       /* Add EXTRA: Age to display seconds since last beacon/probe response
+        * for given network. */
+       iwe.cmd = IWEVCUSTOM;
+       iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+                                    " Last beacon: %dms ago",
+                                    jiffies_to_msecs(jiffies - last_scanned));
+       if (iwe.u.data.length)
+               current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+                                                 &iwe, custom);
+
+       return current_ev;
+}
+
+/* Return results of a scan */
+static int orinoco_ioctl_getscan(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_point *srq,
+                                char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int err = 0;
+       unsigned long flags;
+       char *current_ev = extra;
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return -EBUSY;
+
+       if (priv->scan_inprogress) {
+               /* Important note : we don't want to block the caller
+                * until results are ready for various reasons.
+                * First, managing wait queues is complex and racy.
+                * Second, we grab some rtnetlink lock before comming
+                * here (in dev_ioctl()).
+                * Third, we generate an Wireless Event, so the
+                * caller can wait itself on that - Jean II */
+               err = -EAGAIN;
+               goto out;
+       }
+
+       if (priv->has_ext_scan) {
+               struct xbss_element *bss;
+
+               list_for_each_entry(bss, &priv->bss_list, list) {
+                       /* Translate this entry to WE format */
+                       current_ev =
+                               orinoco_translate_ext_scan(dev, info,
+                                                          current_ev,
+                                                          extra + srq->length,
+                                                          &bss->bss,
+                                                          bss->last_scanned);
+
+                       /* Check if there is space for one more entry */
+                       if ((extra + srq->length - current_ev)
+                           <= IW_EV_ADDR_LEN) {
+                               /* Ask user space to try again with a
+                                * bigger buffer */
+                               err = -E2BIG;
+                               goto out;
+                       }
+               }
+
+       } else {
+               struct bss_element *bss;
+
+               list_for_each_entry(bss, &priv->bss_list, list) {
+                       /* Translate this entry to WE format */
+                       current_ev = orinoco_translate_scan(dev, info,
+                                                           current_ev,
+                                                           extra + srq->length,
+                                                           &bss->bss,
+                                                           bss->last_scanned);
+
+                       /* Check if there is space for one more entry */
+                       if ((extra + srq->length - current_ev)
+                           <= IW_EV_ADDR_LEN) {
+                               /* Ask user space to try again with a
+                                * bigger buffer */
+                               err = -E2BIG;
+                               goto out;
+                       }
+               }
+       }
+
+       srq->length = (current_ev - extra);
+       srq->flags = (__u16) priv->scan_mode;
+
+out:
+       orinoco_unlock(priv, &flags);
+       return err;
+}
+
+/* Commit handler, called after set operations */
+static int orinoco_ioctl_commit(struct net_device *dev,
+                               struct iw_request_info *info,
+                               void *wrqu,
+                               char *extra)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct hermes *hw = &priv->hw;
+       unsigned long flags;
+       int err = 0;
+
+       if (!priv->open)
+               return 0;
+
+       if (priv->broken_disableport) {
+               orinoco_reset(&priv->reset_work);
+               return 0;
+       }
+
+       if (orinoco_lock(priv, &flags) != 0)
+               return err;
+
+       err = hermes_disable_port(hw, 0);
+       if (err) {
+               printk(KERN_WARNING "%s: Unable to disable port "
+                      "while reconfiguring card\n", dev->name);
+               priv->broken_disableport = 1;
+               goto out;
+       }
+
+       err = __orinoco_program_rids(dev);
+       if (err) {
+               printk(KERN_WARNING "%s: Unable to reconfigure card\n",
+                      dev->name);
+               goto out;
+       }
+
+       err = hermes_enable_port(hw, 0);
+       if (err) {
+               printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
+                      dev->name);
+               goto out;
+       }
+
+ out:
+       if (err) {
+               printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
+               schedule_work(&priv->reset_work);
+               err = 0;
+       }
+
+       orinoco_unlock(priv, &flags);
+       return err;
+}
+
+static const struct iw_priv_args orinoco_privtab[] = {
+       { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
+       { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
+       { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+         0, "set_port3" },
+       { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+         "get_port3" },
+       { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+         0, "set_preamble" },
+       { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+         "get_preamble" },
+       { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+         0, "set_ibssport" },
+       { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+         "get_ibssport" },
+       { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
+         "get_rid" },
+};
+
+
+/*
+ * Structures to export the Wireless Handlers
+ */
+
+#define STD_IW_HANDLER(id, func) \
+       [IW_IOCTL_IDX(id)] = (iw_handler) func
+static const iw_handler        orinoco_handler[] = {
+       STD_IW_HANDLER(SIOCSIWCOMMIT,   orinoco_ioctl_commit),
+       STD_IW_HANDLER(SIOCGIWNAME,     orinoco_ioctl_getname),
+       STD_IW_HANDLER(SIOCSIWFREQ,     orinoco_ioctl_setfreq),
+       STD_IW_HANDLER(SIOCGIWFREQ,     orinoco_ioctl_getfreq),
+       STD_IW_HANDLER(SIOCSIWMODE,     orinoco_ioctl_setmode),
+       STD_IW_HANDLER(SIOCGIWMODE,     orinoco_ioctl_getmode),
+       STD_IW_HANDLER(SIOCSIWSENS,     orinoco_ioctl_setsens),
+       STD_IW_HANDLER(SIOCGIWSENS,     orinoco_ioctl_getsens),
+       STD_IW_HANDLER(SIOCGIWRANGE,    orinoco_ioctl_getiwrange),
+       STD_IW_HANDLER(SIOCSIWSPY,      iw_handler_set_spy),
+       STD_IW_HANDLER(SIOCGIWSPY,      iw_handler_get_spy),
+       STD_IW_HANDLER(SIOCSIWTHRSPY,   iw_handler_set_thrspy),
+       STD_IW_HANDLER(SIOCGIWTHRSPY,   iw_handler_get_thrspy),
+       STD_IW_HANDLER(SIOCSIWAP,       orinoco_ioctl_setwap),
+       STD_IW_HANDLER(SIOCGIWAP,       orinoco_ioctl_getwap),
+       STD_IW_HANDLER(SIOCSIWSCAN,     orinoco_ioctl_setscan),
+       STD_IW_HANDLER(SIOCGIWSCAN,     orinoco_ioctl_getscan),
+       STD_IW_HANDLER(SIOCSIWESSID,    orinoco_ioctl_setessid),
+       STD_IW_HANDLER(SIOCGIWESSID,    orinoco_ioctl_getessid),
+       STD_IW_HANDLER(SIOCSIWNICKN,    orinoco_ioctl_setnick),
+       STD_IW_HANDLER(SIOCGIWNICKN,    orinoco_ioctl_getnick),
+       STD_IW_HANDLER(SIOCSIWRATE,     orinoco_ioctl_setrate),
+       STD_IW_HANDLER(SIOCGIWRATE,     orinoco_ioctl_getrate),
+       STD_IW_HANDLER(SIOCSIWRTS,      orinoco_ioctl_setrts),
+       STD_IW_HANDLER(SIOCGIWRTS,      orinoco_ioctl_getrts),
+       STD_IW_HANDLER(SIOCSIWFRAG,     orinoco_ioctl_setfrag),
+       STD_IW_HANDLER(SIOCGIWFRAG,     orinoco_ioctl_getfrag),
+       STD_IW_HANDLER(SIOCGIWRETRY,    orinoco_ioctl_getretry),
+       STD_IW_HANDLER(SIOCSIWENCODE,   orinoco_ioctl_setiwencode),
+       STD_IW_HANDLER(SIOCGIWENCODE,   orinoco_ioctl_getiwencode),
+       STD_IW_HANDLER(SIOCSIWPOWER,    orinoco_ioctl_setpower),
+       STD_IW_HANDLER(SIOCGIWPOWER,    orinoco_ioctl_getpower),
+       STD_IW_HANDLER(SIOCSIWGENIE,    orinoco_ioctl_set_genie),
+       STD_IW_HANDLER(SIOCGIWGENIE,    orinoco_ioctl_get_genie),
+       STD_IW_HANDLER(SIOCSIWMLME,     orinoco_ioctl_set_mlme),
+       STD_IW_HANDLER(SIOCSIWAUTH,     orinoco_ioctl_set_auth),
+       STD_IW_HANDLER(SIOCGIWAUTH,     orinoco_ioctl_get_auth),
+       STD_IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext),
+       STD_IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext),
+};
+
+
+/*
+  Added typecasting since we no longer use iwreq_data -- Moustafa
+ */
+static const iw_handler        orinoco_private_handler[] = {
+       [0] = (iw_handler) orinoco_ioctl_reset,
+       [1] = (iw_handler) orinoco_ioctl_reset,
+       [2] = (iw_handler) orinoco_ioctl_setport3,
+       [3] = (iw_handler) orinoco_ioctl_getport3,
+       [4] = (iw_handler) orinoco_ioctl_setpreamble,
+       [5] = (iw_handler) orinoco_ioctl_getpreamble,
+       [6] = (iw_handler) orinoco_ioctl_setibssport,
+       [7] = (iw_handler) orinoco_ioctl_getibssport,
+       [9] = (iw_handler) orinoco_ioctl_getrid,
+};
+
+static const struct iw_handler_def orinoco_handler_def = {
+       .num_standard = ARRAY_SIZE(orinoco_handler),
+       .num_private = ARRAY_SIZE(orinoco_private_handler),
+       .num_private_args = ARRAY_SIZE(orinoco_privtab),
+       .standard = orinoco_handler,
+       .private = orinoco_private_handler,
+       .private_args = orinoco_privtab,
+       .get_wireless_stats = orinoco_get_wireless_stats,
+};
+
+static void orinoco_get_drvinfo(struct net_device *dev,
+                               struct ethtool_drvinfo *info)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+
+       strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
+       strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
+       strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
+       if (dev->dev.parent)
+               strncpy(info->bus_info, dev_name(dev->dev.parent),
+                       sizeof(info->bus_info) - 1);
+       else
+               snprintf(info->bus_info, sizeof(info->bus_info) - 1,
+                        "PCMCIA %p", priv->hw.iobase);
+}
+
+static const struct ethtool_ops orinoco_ethtool_ops = {
+       .get_drvinfo = orinoco_get_drvinfo,
+       .get_link = ethtool_op_get_link,
+};
+
+/********************************************************************/
+/* Module initialization                                            */
+/********************************************************************/
+
+EXPORT_SYMBOL(alloc_orinocodev);
+EXPORT_SYMBOL(free_orinocodev);
+
+EXPORT_SYMBOL(__orinoco_up);
+EXPORT_SYMBOL(__orinoco_down);
+EXPORT_SYMBOL(orinoco_reinit_firmware);
+
+EXPORT_SYMBOL(orinoco_interrupt);
+
+/* Can't be declared "const" or the whole __initdata section will
+ * become const */
+static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
+       " (David Gibson <hermes@gibson.dropbear.id.au>, "
+       "Pavel Roskin <proski@gnu.org>, et al)";
+
+static int __init init_orinoco(void)
+{
+       printk(KERN_DEBUG "%s\n", version);
+       return 0;
+}
+
+static void __exit exit_orinoco(void)
+{
+}
+
+module_init(init_orinoco);
+module_exit(exit_orinoco);
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
new file mode 100644 (file)
index 0000000..8c29538
--- /dev/null
@@ -0,0 +1,218 @@
+/* orinoco.h
+ * 
+ * Common definitions to all pieces of the various orinoco
+ * drivers
+ */
+
+#ifndef _ORINOCO_H
+#define _ORINOCO_H
+
+#define DRIVER_VERSION "0.15"
+
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+
+#include "hermes.h"
+
+/* To enable debug messages */
+//#define ORINOCO_DEBUG                3
+
+#define WIRELESS_SPY           // enable iwspy support
+
+#define MAX_SCAN_LEN           4096
+
+#define ORINOCO_MAX_KEY_SIZE   14
+#define ORINOCO_MAX_KEYS       4
+
+struct orinoco_key {
+       __le16 len;     /* always stored as little-endian */
+       char data[ORINOCO_MAX_KEY_SIZE];
+} __attribute__ ((packed));
+
+#define TKIP_KEYLEN    16
+#define MIC_KEYLEN     8
+
+struct orinoco_tkip_key {
+       u8 tkip[TKIP_KEYLEN];
+       u8 tx_mic[MIC_KEYLEN];
+       u8 rx_mic[MIC_KEYLEN];
+};
+
+typedef enum {
+       FIRMWARE_TYPE_AGERE,
+       FIRMWARE_TYPE_INTERSIL,
+       FIRMWARE_TYPE_SYMBOL
+} fwtype_t;
+
+struct bss_element {
+       union hermes_scan_info bss;
+       unsigned long last_scanned;
+       struct list_head list;
+};
+
+struct xbss_element {
+       struct agere_ext_scan_info bss;
+       unsigned long last_scanned;
+       struct list_head list;
+};
+
+struct hermes_rx_descriptor;
+
+struct orinoco_rx_data {
+       struct hermes_rx_descriptor *desc;
+       struct sk_buff *skb;
+       struct list_head list;
+};
+
+struct firmware;
+
+struct orinoco_private {
+       void *card;     /* Pointer to card dependent structure */
+       struct device *dev;
+       int (*hard_reset)(struct orinoco_private *);
+       int (*stop_fw)(struct orinoco_private *, int);
+
+       /* Synchronisation stuff */
+       spinlock_t lock;
+       int hw_unavailable;
+       struct work_struct reset_work;
+
+       /* Interrupt tasklets */
+       struct tasklet_struct rx_tasklet;
+       struct list_head rx_list;
+       struct orinoco_rx_data *rx_data;
+
+       /* driver state */
+       int open;
+       u16 last_linkstatus;
+       struct work_struct join_work;
+       struct work_struct wevent_work;
+
+       /* Net device stuff */
+       struct net_device *ndev;
+       struct net_device_stats stats;
+       struct iw_statistics wstats;
+
+       /* Hardware control variables */
+       hermes_t hw;
+       u16 txfid;
+
+       /* Capabilities of the hardware/firmware */
+       fwtype_t firmware_type;
+       char fw_name[32];
+       int ibss_port;
+       int nicbuf_size;
+       u16 channel_mask;
+
+       /* Boolean capabilities */
+       unsigned int has_ibss:1;
+       unsigned int has_port3:1;
+       unsigned int has_wep:1;
+       unsigned int has_big_wep:1;
+       unsigned int has_mwo:1;
+       unsigned int has_pm:1;
+       unsigned int has_preamble:1;
+       unsigned int has_sensitivity:1;
+       unsigned int has_hostscan:1;
+       unsigned int has_alt_txcntl:1;
+       unsigned int has_ext_scan:1;
+       unsigned int has_wpa:1;
+       unsigned int do_fw_download:1;
+       unsigned int broken_disableport:1;
+       unsigned int broken_monitor:1;
+
+       /* Configuration paramaters */
+       u32 iw_mode;
+       int prefer_port3;
+       u16 encode_alg, wep_restrict, tx_key;
+       struct orinoco_key keys[ORINOCO_MAX_KEYS];
+       int bitratemode;
+       char nick[IW_ESSID_MAX_SIZE+1];
+       char desired_essid[IW_ESSID_MAX_SIZE+1];
+       char desired_bssid[ETH_ALEN];
+       int bssid_fixed;
+       u16 frag_thresh, mwo_robust;
+       u16 channel;
+       u16 ap_density, rts_thresh;
+       u16 pm_on, pm_mcast, pm_period, pm_timeout;
+       u16 preamble;
+#ifdef WIRELESS_SPY
+       struct iw_spy_data spy_data; /* iwspy support */
+       struct iw_public_data   wireless_data;
+#endif
+
+       /* Configuration dependent variables */
+       int port_type, createibss;
+       int promiscuous, mc_count;
+
+       /* Scanning support */
+       struct list_head bss_list;
+       struct list_head bss_free_list;
+       void *bss_xbss_data;
+
+       int     scan_inprogress;        /* Scan pending... */
+       u32     scan_mode;              /* Type of scan done */
+
+       /* WPA support */
+       u8 *wpa_ie;
+       int wpa_ie_len;
+
+       struct orinoco_tkip_key tkip_key[ORINOCO_MAX_KEYS];
+       struct crypto_hash *rx_tfm_mic;
+       struct crypto_hash *tx_tfm_mic;
+
+       unsigned int wpa_enabled:1;
+       unsigned int tkip_cm_active:1;
+       unsigned int key_mgmt:3;
+
+       /* Cached in memory firmware to use in ->resume */
+       const struct firmware *cached_fw;
+};
+
+#ifdef ORINOCO_DEBUG
+extern int orinoco_debug;
+#define DEBUG(n, args...) do { if (orinoco_debug>(n)) printk(KERN_DEBUG args); } while(0)
+#else
+#define DEBUG(n, args...) do { } while (0)
+#endif /* ORINOCO_DEBUG */
+
+/********************************************************************/
+/* Exported prototypes                                              */
+/********************************************************************/
+
+extern struct net_device *alloc_orinocodev(
+       int sizeof_card, struct device *device,
+       int (*hard_reset)(struct orinoco_private *),
+       int (*stop_fw)(struct orinoco_private *, int));
+extern void free_orinocodev(struct net_device *dev);
+extern int __orinoco_up(struct net_device *dev);
+extern int __orinoco_down(struct net_device *dev);
+extern int orinoco_reinit_firmware(struct net_device *dev);
+extern irqreturn_t orinoco_interrupt(int irq, void * dev_id);
+
+/********************************************************************/
+/* Locking and synchronization functions                            */
+/********************************************************************/
+
+static inline int orinoco_lock(struct orinoco_private *priv,
+                              unsigned long *flags)
+{
+       spin_lock_irqsave(&priv->lock, *flags);
+       if (priv->hw_unavailable) {
+               DEBUG(1, "orinoco_lock() called with hw_unavailable (dev=%p)\n",
+                      priv->ndev);
+               spin_unlock_irqrestore(&priv->lock, *flags);
+               return -EBUSY;
+       }
+       return 0;
+}
+
+static inline void orinoco_unlock(struct orinoco_private *priv,
+                                 unsigned long *flags)
+{
+       spin_unlock_irqrestore(&priv->lock, *flags);
+}
+
+#endif /* _ORINOCO_H */
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
new file mode 100644 (file)
index 0000000..bf6a51d
--- /dev/null
@@ -0,0 +1,533 @@
+/* orinoco_cs.c (formerly known as dldwd_cs.c)
+ *
+ * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
+ * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
+ * EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and others).
+ * It should also be usable on various Prism II based cards such as the
+ * Linksys, D-Link and Farallon Skyline. It should also work on Symbol
+ * cards such as the 3Com AirConnect and Ericsson WLAN.
+ * 
+ * Copyright notice & release notes in file orinoco.c
+ */
+
+#define DRIVER_NAME "orinoco_cs"
+#define PFX DRIVER_NAME ": "
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+#include "orinoco.h"
+
+/********************************************************************/
+/* Module stuff                                                            */
+/********************************************************************/
+
+MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
+MODULE_DESCRIPTION("Driver for PCMCIA Lucent Orinoco, Prism II based and similar wireless cards");
+MODULE_LICENSE("Dual MPL/GPL");
+
+/* Module parameters */
+
+/* Some D-Link cards have buggy CIS. They do work at 5v properly, but
+ * don't have any CIS entry for it. This workaround it... */
+static int ignore_cis_vcc; /* = 0 */
+module_param(ignore_cis_vcc, int, 0);
+MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
+
+/********************************************************************/
+/* Data structures                                                 */
+/********************************************************************/
+
+/* PCMCIA specific device information (goes in the card field of
+ * struct orinoco_private */
+struct orinoco_pccard {
+       struct pcmcia_device    *p_dev;
+       dev_node_t node;
+
+       /* Used to handle hard reset */
+       /* yuck, we need this hack to work around the insanity of the
+         * PCMCIA layer */
+       unsigned long hard_reset_in_progress; 
+};
+
+
+/********************************************************************/
+/* Function prototypes                                             */
+/********************************************************************/
+
+static int orinoco_cs_config(struct pcmcia_device *link);
+static void orinoco_cs_release(struct pcmcia_device *link);
+static void orinoco_cs_detach(struct pcmcia_device *p_dev);
+
+/********************************************************************/
+/* Device methods                                                  */
+/********************************************************************/
+
+static int
+orinoco_cs_hard_reset(struct orinoco_private *priv)
+{
+       struct orinoco_pccard *card = priv->card;
+       struct pcmcia_device *link = card->p_dev;
+       int err;
+
+       /* We need atomic ops here, because we're not holding the lock */
+       set_bit(0, &card->hard_reset_in_progress);
+
+       err = pcmcia_reset_card(link->socket);
+       if (err)
+               return err;
+
+       msleep(100);
+       clear_bit(0, &card->hard_reset_in_progress);
+
+       return 0;
+}
+
+/********************************************************************/
+/* PCMCIA stuff                                                    */
+/********************************************************************/
+
+/*
+ * This creates an "instance" of the driver, allocating local data
+ * structures for one device.  The device is registered with Card
+ * Services.
+ * 
+ * The dev_link structure is initialized, but we don't actually
+ * configure the card at this point -- we wait until we receive a card
+ * insertion event.  */
+static int
+orinoco_cs_probe(struct pcmcia_device *link)
+{
+       struct net_device *dev;
+       struct orinoco_private *priv;
+       struct orinoco_pccard *card;
+
+       dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
+                              orinoco_cs_hard_reset, NULL);
+       if (! dev)
+               return -ENOMEM;
+       priv = netdev_priv(dev);
+       card = priv->card;
+
+       /* Link both structures together */
+       card->p_dev = link;
+       link->priv = dev;
+
+       /* Interrupt setup */
+       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; 
+
+       /* General socket configuration defaults can go here.  In this
+        * client, we assume very little, and rely on the CIS for
+        * almost everything.  In most clients, many details (i.e.,
+        * number, sizes, and attributes of IO windows) are fixed by
+        * the nature of the device, and can be hard-wired here. */
+       link->conf.Attributes = 0;
+       link->conf.IntType = INT_MEMORY_AND_IO;
+
+       return orinoco_cs_config(link);
+}                              /* orinoco_cs_attach */
+
+/*
+ * This deletes a driver "instance".  The device is de-registered with
+ * Card Services.  If it has been released, all local data structures
+ * are freed.  Otherwise, the structures will be freed when the device
+ * is released.
+ */
+static void orinoco_cs_detach(struct pcmcia_device *link)
+{
+       struct net_device *dev = link->priv;
+
+       if (link->dev_node)
+               unregister_netdev(dev);
+
+       orinoco_cs_release(link);
+
+       free_orinocodev(dev);
+}                              /* orinoco_cs_detach */
+
+/*
+ * orinoco_cs_config() is scheduled to run after a CARD_INSERTION
+ * event is received, to configure the PCMCIA socket, and to make the
+ * device available to the system.
+ */
+
+#define CS_CHECK(fn, ret) do { \
+               last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \
+       } while (0)
+
+static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
+                                  cistpl_cftable_entry_t *cfg,
+                                  cistpl_cftable_entry_t *dflt,
+                                  unsigned int vcc,
+                                  void *priv_data)
+{
+       if (cfg->index == 0)
+               goto next_entry;
+
+       /* Use power settings for Vcc and Vpp if present */
+       /* Note that the CIS values need to be rescaled */
+       if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
+               if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
+                       DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n",  vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
+                       if (!ignore_cis_vcc)
+                               goto next_entry;
+               }
+       } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
+               if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) {
+                       DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n",  vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
+                       if (!ignore_cis_vcc)
+                               goto next_entry;
+               }
+       }
+
+       if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
+               p_dev->conf.Vpp =
+                       cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+       else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
+               p_dev->conf.Vpp =
+                       dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+
+       /* Do we need to allocate an interrupt? */
+       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+       /* IO window settings */
+       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+               cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+               if (!(io->flags & CISTPL_IO_8BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+               if (!(io->flags & CISTPL_IO_16BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->io.BasePort1 = io->win[0].base;
+               p_dev->io.NumPorts1 = io->win[0].len;
+               if (io->nwin > 1) {
+                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
+                       p_dev->io.BasePort2 = io->win[1].base;
+                       p_dev->io.NumPorts2 = io->win[1].len;
+               }
+
+               /* This reserves IO space but doesn't actually enable it */
+               if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+                       goto next_entry;
+       }
+       return 0;
+
+next_entry:
+       pcmcia_disable_device(p_dev);
+       return -ENODEV;
+};
+
+static int
+orinoco_cs_config(struct pcmcia_device *link)
+{
+       struct net_device *dev = link->priv;
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct orinoco_pccard *card = priv->card;
+       hermes_t *hw = &priv->hw;
+       int last_fn, last_ret;
+       void __iomem *mem;
+
+       /*
+        * In this loop, we scan the CIS for configuration table
+        * entries, each of which describes a valid card
+        * configuration, including voltage, IO window, memory window,
+        * and interrupt settings.
+        *
+        * We make no assumptions about the card to be configured: we
+        * use just the information available in the CIS.  In an ideal
+        * world, this would work for any PCMCIA card, but it requires
+        * a complete and accurate CIS.  In practice, a driver usually
+        * "knows" most of these things without consulting the CIS,
+        * and most client drivers will only use the CIS to fill in
+        * implementation-defined details.
+        */
+       last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
+       if (last_ret) {
+               if (!ignore_cis_vcc)
+                       printk(KERN_ERR PFX "GetNextTuple(): No matching "
+                              "CIS configuration.  Maybe you need the "
+                              "ignore_cis_vcc=1 parameter.\n");
+               cs_error(link, RequestIO, last_ret);
+               goto failed;
+       }
+
+       /*
+        * Allocate an interrupt line.  Note that this does not assign
+        * a handler to the interrupt, unless the 'Handler' member of
+        * the irq structure is initialized.
+        */
+       CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+
+       /* We initialize the hermes structure before completing PCMCIA
+        * configuration just in case the interrupt handler gets
+        * called. */
+       mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
+       if (!mem)
+               goto cs_failed;
+
+       hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
+
+       /*
+        * This actually configures the PCMCIA socket -- setting up
+        * the I/O windows and the interrupt mapping, and putting the
+        * card and host interface into "Memory and IO" mode.
+        */
+       CS_CHECK(RequestConfiguration,
+                pcmcia_request_configuration(link, &link->conf));
+
+       /* Ok, we have the configuration, prepare to register the netdev */
+       dev->base_addr = link->io.BasePort1;
+       dev->irq = link->irq.AssignedIRQ;
+       card->node.major = card->node.minor = 0;
+
+       SET_NETDEV_DEV(dev, &handle_to_dev(link));
+       /* Tell the stack we exist */
+       if (register_netdev(dev) != 0) {
+               printk(KERN_ERR PFX "register_netdev() failed\n");
+               goto failed;
+       }
+
+       /* At this point, the dev_node_t structure(s) needs to be
+        * initialized and arranged in a linked list at link->dev_node. */
+       strcpy(card->node.dev_name, dev->name);
+       link->dev_node = &card->node; /* link->dev_node being non-NULL is also
+                                    used to indicate that the
+                                    net_device has been registered */
+
+       /* Finally, report what we've done */
+       printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
+              "0x%04x-0x%04x\n", dev->name, dev_name(dev->dev.parent),
+              link->irq.AssignedIRQ, link->io.BasePort1,
+              link->io.BasePort1 + link->io.NumPorts1 - 1);
+       return 0;
+
+ cs_failed:
+       cs_error(link, last_fn, last_ret);
+
+ failed:
+       orinoco_cs_release(link);
+       return -ENODEV;
+}                              /* orinoco_cs_config */
+
+/*
+ * After a card is removed, orinoco_cs_release() will unregister the
+ * device, and release the PCMCIA configuration.  If the device is
+ * still open, this will be postponed until it is closed.
+ */
+static void
+orinoco_cs_release(struct pcmcia_device *link)
+{
+       struct net_device *dev = link->priv;
+       struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
+
+       /* We're committed to taking the device away now, so mark the
+        * hardware as unavailable */
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->hw_unavailable++;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       pcmcia_disable_device(link);
+       if (priv->hw.iobase)
+               ioport_unmap(priv->hw.iobase);
+}                              /* orinoco_cs_release */
+
+static int orinoco_cs_suspend(struct pcmcia_device *link)
+{
+       struct net_device *dev = link->priv;
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct orinoco_pccard *card = priv->card;
+       int err = 0;
+       unsigned long flags;
+
+       /* This is probably racy, but I can't think of
+          a better way, short of rewriting the PCMCIA
+          layer to not suck :-( */
+       if (! test_bit(0, &card->hard_reset_in_progress)) {
+               spin_lock_irqsave(&priv->lock, flags);
+
+               err = __orinoco_down(dev);
+               if (err)
+                       printk(KERN_WARNING "%s: Error %d downing interface\n",
+                              dev->name, err);
+
+               netif_device_detach(dev);
+               priv->hw_unavailable++;
+
+               spin_unlock_irqrestore(&priv->lock, flags);
+       }
+
+       return 0;
+}
+
+static int orinoco_cs_resume(struct pcmcia_device *link)
+{
+       struct net_device *dev = link->priv;
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct orinoco_pccard *card = priv->card;
+       int err = 0;
+       unsigned long flags;
+
+       if (! test_bit(0, &card->hard_reset_in_progress)) {
+               err = orinoco_reinit_firmware(dev);
+               if (err) {
+                       printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
+                              dev->name, err);
+                       return -EIO;
+               }
+
+               spin_lock_irqsave(&priv->lock, flags);
+
+               netif_device_attach(dev);
+               priv->hw_unavailable--;
+
+               if (priv->open && ! priv->hw_unavailable) {
+                       err = __orinoco_up(dev);
+                       if (err)
+                               printk(KERN_ERR "%s: Error %d restarting card\n",
+                                      dev->name, err);
+               }
+
+               spin_unlock_irqrestore(&priv->lock, flags);
+       }
+
+       return err;
+}
+
+
+/********************************************************************/
+/* Module initialization                                           */
+/********************************************************************/
+
+/* Can't be declared "const" or the whole __initdata section will
+ * become const */
+static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
+       " (David Gibson <hermes@gibson.dropbear.id.au>, "
+       "Pavel Roskin <proski@gnu.org>, et al)";
+
+static struct pcmcia_device_id orinoco_cs_ids[] = {
+       PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */
+       PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */
+       PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */
+       PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */
+       PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */
+       PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */
+       PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */
+       PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */
+       PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */
+       PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */
+       PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */
+       PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */
+       PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */
+       PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */
+       PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */
+       PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */
+       PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */
+       PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */
+       PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */
+       PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */
+       PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x3021), /* SpeedStream Wireless Adapter */
+       PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */
+       PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */
+       PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */
+       PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */
+       PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */
+       PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */
+       PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */
+       PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9),
+       PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
+       PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5),
+       PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2),
+       PCMCIA_DEVICE_PROD_ID123("AIRVAST", "IEEE 802.11b Wireless PCMCIA Card", "HFA3863", 0xea569531, 0x4bcb9645, 0x355cb092),
+       PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f),
+       PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842),
+       PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e),
+       PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169),
+       PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb),
+       PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3),
+       PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18),
+       PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90),
+       PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b),
+       PCMCIA_DEVICE_PROD_ID123("corega", "WL PCCL-11", "ISL37300P", 0x0a21501a, 0x59868926, 0xc9049a39),
+       PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584),
+       PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9),
+       PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae),
+       PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac),
+       PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab),
+       PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916),
+       PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146),
+       PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3),
+       PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c),
+       PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
+       PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077),
+       PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18),
+       PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77),
+       PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf),
+       PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2),
+       PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92),
+       PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395),
+       PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
+       PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410),
+       PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3),
+       PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01),
+       PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a),
+       PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", 0xa37434e9, 0x9762e8f1),
+       PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1),
+       PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767),
+       PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6),
+       PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed),
+       PCMCIA_DEVICE_PROD_ID123("PCMCIA", "11M WLAN Card v2.5", "ISL37300P", 0x281f1c5d, 0x6e440487, 0xc9049a39),
+       PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264),
+       PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178),
+       PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
+       PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),
+       PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),
+       PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757),
+       PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a),
+       PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
+       PCMCIA_DEVICE_PROD_ID123("The Linksys Group, Inc.", "Instant Wireless Network PC Card", "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39),
+       PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee),
+       PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids);
+
+static struct pcmcia_driver orinoco_driver = {
+       .owner          = THIS_MODULE,
+       .drv            = {
+               .name   = DRIVER_NAME,
+       },
+       .probe          = orinoco_cs_probe,
+       .remove         = orinoco_cs_detach,
+       .id_table       = orinoco_cs_ids,
+       .suspend        = orinoco_cs_suspend,
+       .resume         = orinoco_cs_resume,
+};
+
+static int __init
+init_orinoco_cs(void)
+{
+       printk(KERN_DEBUG "%s\n", version);
+
+       return pcmcia_register_driver(&orinoco_driver);
+}
+
+static void __exit
+exit_orinoco_cs(void)
+{
+       pcmcia_unregister_driver(&orinoco_driver);
+}
+
+module_init(init_orinoco_cs);
+module_exit(exit_orinoco_cs);
diff --git a/drivers/net/wireless/orinoco/orinoco_nortel.c b/drivers/net/wireless/orinoco/orinoco_nortel.c
new file mode 100644 (file)
index 0000000..2fc8659
--- /dev/null
@@ -0,0 +1,324 @@
+/* orinoco_nortel.c
+ *
+ * Driver for Prism II devices which would usually be driven by orinoco_cs,
+ * but are connected to the PCI bus by a PCI-to-PCMCIA adapter used in
+ * Nortel emobility, Symbol LA-4113 and Symbol LA-4123.
+ *
+ * Copyright (C) 2002 Tobias Hoffmann
+ *           (C) 2003 Christoph Jungegger <disdos@traum404.de>
+ *
+ * Some of this code is borrowed from orinoco_plx.c
+ *     Copyright (C) 2001 Daniel Barlow
+ * Some of this code is borrowed from orinoco_pci.c 
+ *  Copyright (C) 2001 Jean Tourrilhes
+ * Some of this code is "inspired" by linux-wlan-ng-0.1.10, but nothing
+ * has been copied from it. linux-wlan-ng-0.1.10 is originally :
+ *     Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+ * 
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.
+ */
+
+#define DRIVER_NAME "orinoco_nortel"
+#define PFX DRIVER_NAME ": "
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <pcmcia/cisreg.h>
+
+#include "orinoco.h"
+#include "orinoco_pci.h"
+
+#define COR_OFFSET    (0xe0)   /* COR attribute offset of Prism2 PC card */
+#define COR_VALUE     (COR_LEVEL_REQ | COR_FUNC_ENA)   /* Enable PC card with interrupt in level trigger */
+
+
+/*
+ * Do a soft reset of the card using the Configuration Option Register
+ * We need this to get going...
+ * This is the part of the code that is strongly inspired from wlan-ng
+ *
+ * Note bis : Don't try to access HERMES_CMD during the reset phase.
+ * It just won't work !
+ */
+static int orinoco_nortel_cor_reset(struct orinoco_private *priv)
+{
+       struct orinoco_pci_card *card = priv->card;
+
+       /* Assert the reset until the card notices */
+       iowrite16(8, card->bridge_io + 2);
+       ioread16(card->attr_io + COR_OFFSET);
+       iowrite16(0x80, card->attr_io + COR_OFFSET);
+       mdelay(1);
+
+       /* Give time for the card to recover from this hard effort */
+       iowrite16(0, card->attr_io + COR_OFFSET);
+       iowrite16(0, card->attr_io + COR_OFFSET);
+       mdelay(1);
+
+       /* Set COR as usual */
+       iowrite16(COR_VALUE, card->attr_io + COR_OFFSET);
+       iowrite16(COR_VALUE, card->attr_io + COR_OFFSET);
+       mdelay(1);
+
+       iowrite16(0x228, card->bridge_io + 2);
+
+       return 0;
+}
+
+static int orinoco_nortel_hw_init(struct orinoco_pci_card *card)
+{
+       int i;
+       u32 reg;
+
+       /* Setup bridge */
+       if (ioread16(card->bridge_io) & 1) {
+               printk(KERN_ERR PFX "brg1 answer1 wrong\n");
+               return -EBUSY;
+       }
+       iowrite16(0x118, card->bridge_io + 2);
+       iowrite16(0x108, card->bridge_io + 2);
+       mdelay(30);
+       iowrite16(0x8, card->bridge_io + 2);
+       for (i = 0; i < 30; i++) {
+               mdelay(30);
+               if (ioread16(card->bridge_io) & 0x10) {
+                       break;
+               }
+       }
+       if (i == 30) {
+               printk(KERN_ERR PFX "brg1 timed out\n");
+               return -EBUSY;
+       }
+       if (ioread16(card->attr_io + COR_OFFSET) & 1) {
+               printk(KERN_ERR PFX "brg2 answer1 wrong\n");
+               return -EBUSY;
+       }
+       if (ioread16(card->attr_io + COR_OFFSET + 2) & 1) {
+               printk(KERN_ERR PFX "brg2 answer2 wrong\n");
+               return -EBUSY;
+       }
+       if (ioread16(card->attr_io + COR_OFFSET + 4) & 1) {
+               printk(KERN_ERR PFX "brg2 answer3 wrong\n");
+               return -EBUSY;
+       }
+
+       /* Set the PCMCIA COR register */
+       iowrite16(COR_VALUE, card->attr_io + COR_OFFSET);
+       mdelay(1);
+       reg = ioread16(card->attr_io + COR_OFFSET);
+       if (reg != COR_VALUE) {
+               printk(KERN_ERR PFX "Error setting COR value (reg=%x)\n",
+                      reg);
+               return -EBUSY;
+       }
+
+       /* Set LEDs */
+       iowrite16(1, card->bridge_io + 10);
+       return 0;
+}
+
+static int orinoco_nortel_init_one(struct pci_dev *pdev,
+                                  const struct pci_device_id *ent)
+{
+       int err;
+       struct orinoco_private *priv;
+       struct orinoco_pci_card *card;
+       struct net_device *dev;
+       void __iomem *hermes_io, *bridge_io, *attr_io;
+
+       err = pci_enable_device(pdev);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot enable PCI device\n");
+               return err;
+       }
+
+       err = pci_request_regions(pdev, DRIVER_NAME);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
+               goto fail_resources;
+       }
+
+       bridge_io = pci_iomap(pdev, 0, 0);
+       if (!bridge_io) {
+               printk(KERN_ERR PFX "Cannot map bridge registers\n");
+               err = -EIO;
+               goto fail_map_bridge;
+       }
+
+       attr_io = pci_iomap(pdev, 1, 0);
+       if (!attr_io) {
+               printk(KERN_ERR PFX "Cannot map PCMCIA attributes\n");
+               err = -EIO;
+               goto fail_map_attr;
+       }
+
+       hermes_io = pci_iomap(pdev, 2, 0);
+       if (!hermes_io) {
+               printk(KERN_ERR PFX "Cannot map chipset registers\n");
+               err = -EIO;
+               goto fail_map_hermes;
+       }
+
+       /* Allocate network device */
+       dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
+                              orinoco_nortel_cor_reset, NULL);
+       if (!dev) {
+               printk(KERN_ERR PFX "Cannot allocate network device\n");
+               err = -ENOMEM;
+               goto fail_alloc;
+       }
+
+       priv = netdev_priv(dev);
+       card = priv->card;
+       card->bridge_io = bridge_io;
+       card->attr_io = attr_io;
+       SET_NETDEV_DEV(dev, &pdev->dev);
+
+       hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
+
+       err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
+                         dev->name, dev);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
+               err = -EBUSY;
+               goto fail_irq;
+       }
+
+       err = orinoco_nortel_hw_init(card);
+       if (err) {
+               printk(KERN_ERR PFX "Hardware initialization failed\n");
+               goto fail;
+       }
+
+       err = orinoco_nortel_cor_reset(priv);
+       if (err) {
+               printk(KERN_ERR PFX "Initial reset failed\n");
+               goto fail;
+       }
+
+       err = register_netdev(dev);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot register network device\n");
+               goto fail;
+       }
+
+       pci_set_drvdata(pdev, dev);
+       printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
+              pci_name(pdev));
+
+       return 0;
+
+ fail:
+       free_irq(pdev->irq, dev);
+
+ fail_irq:
+       pci_set_drvdata(pdev, NULL);
+       free_orinocodev(dev);
+
+ fail_alloc:
+       pci_iounmap(pdev, hermes_io);
+
+ fail_map_hermes:
+       pci_iounmap(pdev, attr_io);
+
+ fail_map_attr:
+       pci_iounmap(pdev, bridge_io);
+
+ fail_map_bridge:
+       pci_release_regions(pdev);
+
+ fail_resources:
+       pci_disable_device(pdev);
+
+       return err;
+}
+
+static void __devexit orinoco_nortel_remove_one(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct orinoco_pci_card *card = priv->card;
+
+       /* Clear LEDs */
+       iowrite16(0, card->bridge_io + 10);
+
+       unregister_netdev(dev);
+       free_irq(pdev->irq, dev);
+       pci_set_drvdata(pdev, NULL);
+       free_orinocodev(dev);
+       pci_iounmap(pdev, priv->hw.iobase);
+       pci_iounmap(pdev, card->attr_io);
+       pci_iounmap(pdev, card->bridge_io);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+}
+
+static struct pci_device_id orinoco_nortel_id_table[] = {
+       /* Nortel emobility PCI */
+       {0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,},
+       /* Symbol LA-4123 PCI */
+       {0x1562, 0x0001, PCI_ANY_ID, PCI_ANY_ID,},
+       {0,},
+};
+
+MODULE_DEVICE_TABLE(pci, orinoco_nortel_id_table);
+
+static struct pci_driver orinoco_nortel_driver = {
+       .name           = DRIVER_NAME,
+       .id_table       = orinoco_nortel_id_table,
+       .probe          = orinoco_nortel_init_one,
+       .remove         = __devexit_p(orinoco_nortel_remove_one),
+       .suspend        = orinoco_pci_suspend,
+       .resume         = orinoco_pci_resume,
+};
+
+static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
+       " (Tobias Hoffmann & Christoph Jungegger <disdos@traum404.de>)";
+MODULE_AUTHOR("Christoph Jungegger <disdos@traum404.de>");
+MODULE_DESCRIPTION
+    ("Driver for wireless LAN cards using the Nortel PCI bridge");
+MODULE_LICENSE("Dual MPL/GPL");
+
+static int __init orinoco_nortel_init(void)
+{
+       printk(KERN_DEBUG "%s\n", version);
+       return pci_register_driver(&orinoco_nortel_driver);
+}
+
+static void __exit orinoco_nortel_exit(void)
+{
+       pci_unregister_driver(&orinoco_nortel_driver);
+}
+
+module_init(orinoco_nortel_init);
+module_exit(orinoco_nortel_exit);
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.c b/drivers/net/wireless/orinoco/orinoco_pci.c
new file mode 100644 (file)
index 0000000..4ebd638
--- /dev/null
@@ -0,0 +1,264 @@
+/* orinoco_pci.c
+ * 
+ * Driver for Prism 2.5/3 devices that have a direct PCI interface
+ * (i.e. these are not PCMCIA cards in a PCMCIA-to-PCI bridge).
+ * The card contains only one PCI region, which contains all the usual
+ * hermes registers, as well as the COR register.
+ *
+ * Current maintainers are:
+ *     Pavel Roskin <proski AT gnu.org>
+ * and David Gibson <hermes AT gibson.dropbear.id.au>
+ *
+ * Some of this code is borrowed from orinoco_plx.c
+ *     Copyright (C) 2001 Daniel Barlow <dan AT telent.net>
+ * Some of this code is "inspired" by linux-wlan-ng-0.1.10, but nothing
+ * has been copied from it. linux-wlan-ng-0.1.10 is originally :
+ *     Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+ * This file originally written by:
+ *     Copyright (C) 2001 Jean Tourrilhes <jt AT hpl.hp.com>
+ * And is now maintained by:
+ *     (C) Copyright David Gibson, IBM Corp. 2002-2003.
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.
+ */
+
+#define DRIVER_NAME "orinoco_pci"
+#define PFX DRIVER_NAME ": "
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include "orinoco.h"
+#include "orinoco_pci.h"
+
+/* Offset of the COR register of the PCI card */
+#define HERMES_PCI_COR         (0x26)
+
+/* Bitmask to reset the card */
+#define HERMES_PCI_COR_MASK    (0x0080)
+
+/* Magic timeouts for doing the reset.
+ * Those times are straight from wlan-ng, and it is claimed that they
+ * are necessary. Alan will kill me. Take your time and grab a coffee. */
+#define HERMES_PCI_COR_ONT     (250)           /* ms */
+#define HERMES_PCI_COR_OFFT    (500)           /* ms */
+#define HERMES_PCI_COR_BUSYT   (500)           /* ms */
+
+/*
+ * Do a soft reset of the card using the Configuration Option Register
+ * We need this to get going...
+ * This is the part of the code that is strongly inspired from wlan-ng
+ *
+ * Note : This code is done with irq enabled. This mean that many
+ * interrupts will occur while we are there. This is why we use the
+ * jiffies to regulate time instead of a straight mdelay(). Usually we
+ * need only around 245 iteration of the loop to do 250 ms delay.
+ *
+ * Note bis : Don't try to access HERMES_CMD during the reset phase.
+ * It just won't work !
+ */
+static int orinoco_pci_cor_reset(struct orinoco_private *priv)
+{
+       hermes_t *hw = &priv->hw;
+       unsigned long timeout;
+       u16 reg;
+
+       /* Assert the reset until the card notices */
+       hermes_write_regn(hw, PCI_COR, HERMES_PCI_COR_MASK);
+       mdelay(HERMES_PCI_COR_ONT);
+
+       /* Give time for the card to recover from this hard effort */
+       hermes_write_regn(hw, PCI_COR, 0x0000);
+       mdelay(HERMES_PCI_COR_OFFT);
+
+       /* The card is ready when it's no longer busy */
+       timeout = jiffies + (HERMES_PCI_COR_BUSYT * HZ / 1000);
+       reg = hermes_read_regn(hw, CMD);
+       while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
+               mdelay(1);
+               reg = hermes_read_regn(hw, CMD);
+       }
+
+       /* Still busy? */
+       if (reg & HERMES_CMD_BUSY) {
+               printk(KERN_ERR PFX "Busy timeout\n");
+               return -ETIMEDOUT;
+       }
+
+       return 0;
+}
+
+static int orinoco_pci_init_one(struct pci_dev *pdev,
+                               const struct pci_device_id *ent)
+{
+       int err;
+       struct orinoco_private *priv;
+       struct orinoco_pci_card *card;
+       struct net_device *dev;
+       void __iomem *hermes_io;
+
+       err = pci_enable_device(pdev);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot enable PCI device\n");
+               return err;
+       }
+
+       err = pci_request_regions(pdev, DRIVER_NAME);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
+               goto fail_resources;
+       }
+
+       hermes_io = pci_iomap(pdev, 0, 0);
+       if (!hermes_io) {
+               printk(KERN_ERR PFX "Cannot remap chipset registers\n");
+               err = -EIO;
+               goto fail_map_hermes;
+       }
+
+       /* Allocate network device */
+       dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
+                              orinoco_pci_cor_reset, NULL);
+       if (!dev) {
+               printk(KERN_ERR PFX "Cannot allocate network device\n");
+               err = -ENOMEM;
+               goto fail_alloc;
+       }
+
+       priv = netdev_priv(dev);
+       card = priv->card;
+       SET_NETDEV_DEV(dev, &pdev->dev);
+
+       hermes_struct_init(&priv->hw, hermes_io, HERMES_32BIT_REGSPACING);
+
+       err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
+                         dev->name, dev);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
+               err = -EBUSY;
+               goto fail_irq;
+       }
+
+       err = orinoco_pci_cor_reset(priv);
+       if (err) {
+               printk(KERN_ERR PFX "Initial reset failed\n");
+               goto fail;
+       }
+
+       err = register_netdev(dev);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot register network device\n");
+               goto fail;
+       }
+
+       pci_set_drvdata(pdev, dev);
+       printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
+              pci_name(pdev));
+
+       return 0;
+
+ fail:
+       free_irq(pdev->irq, dev);
+
+ fail_irq:
+       pci_set_drvdata(pdev, NULL);
+       free_orinocodev(dev);
+
+ fail_alloc:
+       pci_iounmap(pdev, hermes_io);
+
+ fail_map_hermes:
+       pci_release_regions(pdev);
+
+ fail_resources:
+       pci_disable_device(pdev);
+
+       return err;
+}
+
+static void __devexit orinoco_pci_remove_one(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct orinoco_private *priv = netdev_priv(dev);
+
+       unregister_netdev(dev);
+       free_irq(pdev->irq, dev);
+       pci_set_drvdata(pdev, NULL);
+       free_orinocodev(dev);
+       pci_iounmap(pdev, priv->hw.iobase);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+}
+
+static struct pci_device_id orinoco_pci_id_table[] = {
+       /* Intersil Prism 3 */
+       {0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID,},
+       /* Intersil Prism 2.5 */
+       {0x1260, 0x3873, PCI_ANY_ID, PCI_ANY_ID,},
+       /* Samsung MagicLAN SWL-2210P */
+       {0x167d, 0xa000, PCI_ANY_ID, PCI_ANY_ID,},
+       {0,},
+};
+
+MODULE_DEVICE_TABLE(pci, orinoco_pci_id_table);
+
+static struct pci_driver orinoco_pci_driver = {
+       .name           = DRIVER_NAME,
+       .id_table       = orinoco_pci_id_table,
+       .probe          = orinoco_pci_init_one,
+       .remove         = __devexit_p(orinoco_pci_remove_one),
+       .suspend        = orinoco_pci_suspend,
+       .resume         = orinoco_pci_resume,
+};
+
+static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
+       " (Pavel Roskin <proski@gnu.org>,"
+       " David Gibson <hermes@gibson.dropbear.id.au> &"
+       " Jean Tourrilhes <jt@hpl.hp.com>)";
+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
+MODULE_DESCRIPTION("Driver for wireless LAN cards using direct PCI interface");
+MODULE_LICENSE("Dual MPL/GPL");
+
+static int __init orinoco_pci_init(void)
+{
+       printk(KERN_DEBUG "%s\n", version);
+       return pci_register_driver(&orinoco_pci_driver);
+}
+
+static void __exit orinoco_pci_exit(void)
+{
+       pci_unregister_driver(&orinoco_pci_driver);
+}
+
+module_init(orinoco_pci_init);
+module_exit(orinoco_pci_exit);
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.h b/drivers/net/wireless/orinoco/orinoco_pci.h
new file mode 100644 (file)
index 0000000..f4e5e06
--- /dev/null
@@ -0,0 +1,109 @@
+/* orinoco_pci.h
+ * 
+ * Common code for all Orinoco drivers for PCI devices, including
+ * both native PCI and PCMCIA-to-PCI bridges.
+ *
+ * Copyright (C) 2005, Pavel Roskin.
+ * See orinoco.c for license.
+ */
+
+#ifndef _ORINOCO_PCI_H
+#define _ORINOCO_PCI_H
+
+#include <linux/netdevice.h>
+
+/* Driver specific data */
+struct orinoco_pci_card {
+       void __iomem *bridge_io;
+       void __iomem *attr_io;
+};
+
+#ifdef CONFIG_PM
+static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
+       int err;
+
+       err = orinoco_lock(priv, &flags);
+       if (err) {
+               printk(KERN_ERR "%s: cannot lock hardware for suspend\n",
+                      dev->name);
+               return err;
+       }
+
+       err = __orinoco_down(dev);
+       if (err)
+               printk(KERN_WARNING "%s: error %d bringing interface down "
+                      "for suspend\n", dev->name, err);
+       
+       netif_device_detach(dev);
+
+       priv->hw_unavailable++;
+       
+       orinoco_unlock(priv, &flags);
+
+       free_irq(pdev->irq, dev);
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, PCI_D3hot);
+
+       return 0;
+}
+
+static int orinoco_pci_resume(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
+       int err;
+
+       pci_set_power_state(pdev, 0);
+       err = pci_enable_device(pdev);
+       if (err) {
+               printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
+                      dev->name);
+               return err;
+       }
+       pci_restore_state(pdev);
+
+       err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
+                         dev->name, dev);
+       if (err) {
+               printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n",
+                      dev->name);
+               pci_disable_device(pdev);
+               return -EBUSY;
+       }
+
+       err = orinoco_reinit_firmware(dev);
+       if (err) {
+               printk(KERN_ERR "%s: error %d re-initializing firmware "
+                      "on resume\n", dev->name, err);
+               return err;
+       }
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       netif_device_attach(dev);
+
+       priv->hw_unavailable--;
+
+       if (priv->open && (! priv->hw_unavailable)) {
+               err = __orinoco_up(dev);
+               if (err)
+                       printk(KERN_ERR "%s: Error %d restarting card on resume\n",
+                              dev->name, err);
+       }
+       
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return 0;
+}
+#else
+#define orinoco_pci_suspend NULL
+#define orinoco_pci_resume NULL
+#endif
+
+#endif /* _ORINOCO_PCI_H */
diff --git a/drivers/net/wireless/orinoco/orinoco_plx.c b/drivers/net/wireless/orinoco/orinoco_plx.c
new file mode 100644 (file)
index 0000000..ef76185
--- /dev/null
@@ -0,0 +1,371 @@
+/* orinoco_plx.c
+ *
+ * Driver for Prism II devices which would usually be driven by orinoco_cs,
+ * but are connected to the PCI bus by a PLX9052.
+ *
+ * Current maintainers are:
+ *     Pavel Roskin <proski AT gnu.org>
+ * and David Gibson <hermes AT gibson.dropbear.id.au>
+ *
+ * (C) Copyright David Gibson, IBM Corp. 2001-2003.
+ * Copyright (C) 2001 Daniel Barlow
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.
+ *
+ * Here's the general details on how the PLX9052 adapter works:
+ *
+ * - Two PCI I/O address spaces, one 0x80 long which contains the
+ * PLX9052 registers, and one that's 0x40 long mapped to the PCMCIA
+ * slot I/O address space.
+ *
+ * - One PCI memory address space, mapped to the PCMCIA attribute space
+ * (containing the CIS).
+ *
+ * Using the later, you can read through the CIS data to make sure the
+ * card is compatible with the driver. Keep in mind that the PCMCIA
+ * spec specifies the CIS as the lower 8 bits of each word read from
+ * the CIS, so to read the bytes of the CIS, read every other byte
+ * (0,2,4,...). Passing that test, you need to enable the I/O address
+ * space on the PCMCIA card via the PCMCIA COR register. This is the
+ * first byte following the CIS. In my case (which may not have any
+ * relation to what's on the PRISM2 cards), COR was at offset 0x800
+ * within the PCI memory space. Write 0x41 to the COR register to
+ * enable I/O mode and to select level triggered interrupts. To
+ * confirm you actually succeeded, read the COR register back and make
+ * sure it actually got set to 0x41, in case you have an unexpected
+ * card inserted.
+ *
+ * Following that, you can treat the second PCI I/O address space (the
+ * one that's not 0x80 in length) as the PCMCIA I/O space.
+ *
+ * Note that in the Eumitcom's source for their drivers, they register
+ * the interrupt as edge triggered when registering it with the
+ * Windows kernel. I don't recall how to register edge triggered on
+ * Linux (if it can be done at all). But in some experimentation, I
+ * don't see much operational difference between using either
+ * interrupt mode. Don't mess with the interrupt mode in the COR
+ * register though, as the PLX9052 wants level triggers with the way
+ * the serial EEPROM configures it on the WL11000.
+ *
+ * There's some other little quirks related to timing that I bumped
+ * into, but I don't recall right now. Also, there's two variants of
+ * the WL11000 I've seen, revision A1 and T2. These seem to differ
+ * slightly in the timings configured in the wait-state generator in
+ * the PLX9052. There have also been some comments from Eumitcom that
+ * cards shouldn't be hot swapped, apparently due to risk of cooking
+ * the PLX9052. I'm unsure why they believe this, as I can't see
+ * anything in the design that would really cause a problem, except
+ * for crashing drivers not written to expect it. And having developed
+ * drivers for the WL11000, I'd say it's quite tricky to write code
+ * that will successfully deal with a hot unplug. Very odd things
+ * happen on the I/O side of things. But anyway, be warned. Despite
+ * that, I've hot-swapped a number of times during debugging and
+ * driver development for various reasons (stuck WAIT# line after the
+ * radio card's firmware locks up).
+ */
+
+#define DRIVER_NAME "orinoco_plx"
+#define PFX DRIVER_NAME ": "
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <pcmcia/cisreg.h>
+
+#include "orinoco.h"
+#include "orinoco_pci.h"
+
+#define COR_OFFSET     (0x3e0) /* COR attribute offset of Prism2 PC card */
+#define COR_VALUE      (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
+#define COR_RESET     (0x80)   /* reset bit in the COR register */
+#define PLX_RESET_TIME (500)   /* milliseconds */
+
+#define PLX_INTCSR             0x4c /* Interrupt Control & Status Register */
+#define PLX_INTCSR_INTEN       (1<<6) /* Interrupt Enable bit */
+
+/*
+ * Do a soft reset of the card using the Configuration Option Register
+ */
+static int orinoco_plx_cor_reset(struct orinoco_private *priv)
+{
+       hermes_t *hw = &priv->hw;
+       struct orinoco_pci_card *card = priv->card;
+       unsigned long timeout;
+       u16 reg;
+
+       iowrite8(COR_VALUE | COR_RESET, card->attr_io + COR_OFFSET);
+       mdelay(1);
+
+       iowrite8(COR_VALUE, card->attr_io + COR_OFFSET);
+       mdelay(1);
+
+       /* Just in case, wait more until the card is no longer busy */
+       timeout = jiffies + (PLX_RESET_TIME * HZ / 1000);
+       reg = hermes_read_regn(hw, CMD);
+       while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
+               mdelay(1);
+               reg = hermes_read_regn(hw, CMD);
+       }
+
+       /* Still busy? */
+       if (reg & HERMES_CMD_BUSY) {
+               printk(KERN_ERR PFX "Busy timeout\n");
+               return -ETIMEDOUT;
+       }
+
+       return 0;
+}
+
+static int orinoco_plx_hw_init(struct orinoco_pci_card *card)
+{
+       int i;
+       u32 csr_reg;
+       static const u8 cis_magic[] = {
+               0x01, 0x03, 0x00, 0x00, 0xff, 0x17, 0x04, 0x67
+       };
+
+       printk(KERN_DEBUG PFX "CIS: ");
+       for (i = 0; i < 16; i++) {
+               printk("%02X:", ioread8(card->attr_io + (i << 1)));
+       }
+       printk("\n");
+
+       /* Verify whether a supported PC card is present */
+       /* FIXME: we probably need to be smarted about this */
+       for (i = 0; i < sizeof(cis_magic); i++) {
+               if (cis_magic[i] != ioread8(card->attr_io + (i << 1))) {
+                       printk(KERN_ERR PFX "The CIS value of Prism2 PC "
+                              "card is unexpected\n");
+                       return -ENODEV;
+               }
+       }
+
+       /* bjoern: We need to tell the card to enable interrupts, in
+          case the serial eprom didn't do this already.  See the
+          PLX9052 data book, p8-1 and 8-24 for reference. */
+       csr_reg = ioread32(card->bridge_io + PLX_INTCSR);
+       if (!(csr_reg & PLX_INTCSR_INTEN)) {
+               csr_reg |= PLX_INTCSR_INTEN;
+               iowrite32(csr_reg, card->bridge_io + PLX_INTCSR);
+               csr_reg = ioread32(card->bridge_io + PLX_INTCSR);
+               if (!(csr_reg & PLX_INTCSR_INTEN)) {
+                       printk(KERN_ERR PFX "Cannot enable interrupts\n");
+                       return -EIO;
+               }
+       }
+
+       return 0;
+}
+
+static int orinoco_plx_init_one(struct pci_dev *pdev,
+                               const struct pci_device_id *ent)
+{
+       int err;
+       struct orinoco_private *priv;
+       struct orinoco_pci_card *card;
+       struct net_device *dev;
+       void __iomem *hermes_io, *attr_io, *bridge_io;
+
+       err = pci_enable_device(pdev);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot enable PCI device\n");
+               return err;
+       }
+
+       err = pci_request_regions(pdev, DRIVER_NAME);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
+               goto fail_resources;
+       }
+
+       bridge_io = pci_iomap(pdev, 1, 0);
+       if (!bridge_io) {
+               printk(KERN_ERR PFX "Cannot map bridge registers\n");
+               err = -EIO;
+               goto fail_map_bridge;
+       }
+
+       attr_io = pci_iomap(pdev, 2, 0);
+       if (!attr_io) {
+               printk(KERN_ERR PFX "Cannot map PCMCIA attributes\n");
+               err = -EIO;
+               goto fail_map_attr;
+       }
+
+       hermes_io = pci_iomap(pdev, 3, 0);
+       if (!hermes_io) {
+               printk(KERN_ERR PFX "Cannot map chipset registers\n");
+               err = -EIO;
+               goto fail_map_hermes;
+       }
+
+       /* Allocate network device */
+       dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
+                              orinoco_plx_cor_reset, NULL);
+       if (!dev) {
+               printk(KERN_ERR PFX "Cannot allocate network device\n");
+               err = -ENOMEM;
+               goto fail_alloc;
+       }
+
+       priv = netdev_priv(dev);
+       card = priv->card;
+       card->bridge_io = bridge_io;
+       card->attr_io = attr_io;
+       SET_NETDEV_DEV(dev, &pdev->dev);
+
+       hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
+
+       err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
+                         dev->name, dev);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
+               err = -EBUSY;
+               goto fail_irq;
+       }
+
+       err = orinoco_plx_hw_init(card);
+       if (err) {
+               printk(KERN_ERR PFX "Hardware initialization failed\n");
+               goto fail;
+       }
+
+       err = orinoco_plx_cor_reset(priv);
+       if (err) {
+               printk(KERN_ERR PFX "Initial reset failed\n");
+               goto fail;
+       }
+
+       err = register_netdev(dev);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot register network device\n");
+               goto fail;
+       }
+
+       pci_set_drvdata(pdev, dev);
+       printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
+              pci_name(pdev));
+
+       return 0;
+
+ fail:
+       free_irq(pdev->irq, dev);
+
+ fail_irq:
+       pci_set_drvdata(pdev, NULL);
+       free_orinocodev(dev);
+
+ fail_alloc:
+       pci_iounmap(pdev, hermes_io);
+
+ fail_map_hermes:
+       pci_iounmap(pdev, attr_io);
+
+ fail_map_attr:
+       pci_iounmap(pdev, bridge_io);
+
+ fail_map_bridge:
+       pci_release_regions(pdev);
+
+ fail_resources:
+       pci_disable_device(pdev);
+
+       return err;
+}
+
+static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct orinoco_pci_card *card = priv->card;
+
+       unregister_netdev(dev);
+       free_irq(pdev->irq, dev);
+       pci_set_drvdata(pdev, NULL);
+       free_orinocodev(dev);
+       pci_iounmap(pdev, priv->hw.iobase);
+       pci_iounmap(pdev, card->attr_io);
+       pci_iounmap(pdev, card->bridge_io);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+}
+
+static struct pci_device_id orinoco_plx_id_table[] = {
+       {0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,},      /* Siemens SpeedStream SS1023 */
+       {0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,},      /* Netgear MA301 */
+       {0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,},      /* Correga  - does this work? */
+       {0x1638, 0x1100, PCI_ANY_ID, PCI_ANY_ID,},      /* SMC EZConnect SMC2602W,
+                                                          Eumitcom PCI WL11000,
+                                                          Addtron AWA-100 */
+       {0x16ab, 0x1100, PCI_ANY_ID, PCI_ANY_ID,},      /* Global Sun Tech GL24110P */
+       {0x16ab, 0x1101, PCI_ANY_ID, PCI_ANY_ID,},      /* Reported working, but unknown */
+       {0x16ab, 0x1102, PCI_ANY_ID, PCI_ANY_ID,},      /* Linksys WDT11 */
+       {0x16ec, 0x3685, PCI_ANY_ID, PCI_ANY_ID,},      /* USR 2415 */
+       {0xec80, 0xec00, PCI_ANY_ID, PCI_ANY_ID,},      /* Belkin F5D6000 tested by
+                                                          Brendan W. McAdams <rit AT jacked-in.org> */
+       {0x10b7, 0x7770, PCI_ANY_ID, PCI_ANY_ID,},      /* 3Com AirConnect PCI tested by
+                                                          Damien Persohn <damien AT persohn.net> */
+       {0,},
+};
+
+MODULE_DEVICE_TABLE(pci, orinoco_plx_id_table);
+
+static struct pci_driver orinoco_plx_driver = {
+       .name           = DRIVER_NAME,
+       .id_table       = orinoco_plx_id_table,
+       .probe          = orinoco_plx_init_one,
+       .remove         = __devexit_p(orinoco_plx_remove_one),
+       .suspend        = orinoco_pci_suspend,
+       .resume         = orinoco_pci_resume,
+};
+
+static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
+       " (Pavel Roskin <proski@gnu.org>,"
+       " David Gibson <hermes@gibson.dropbear.id.au>,"
+       " Daniel Barlow <dan@telent.net>)";
+MODULE_AUTHOR("Daniel Barlow <dan@telent.net>");
+MODULE_DESCRIPTION("Driver for wireless LAN cards using the PLX9052 PCI bridge");
+MODULE_LICENSE("Dual MPL/GPL");
+
+static int __init orinoco_plx_init(void)
+{
+       printk(KERN_DEBUG "%s\n", version);
+       return pci_register_driver(&orinoco_plx_driver);
+}
+
+static void __exit orinoco_plx_exit(void)
+{
+       pci_unregister_driver(&orinoco_plx_driver);
+}
+
+module_init(orinoco_plx_init);
+module_exit(orinoco_plx_exit);
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff --git a/drivers/net/wireless/orinoco/orinoco_tmd.c b/drivers/net/wireless/orinoco/orinoco_tmd.c
new file mode 100644 (file)
index 0000000..ede24ec
--- /dev/null
@@ -0,0 +1,248 @@
+/* orinoco_tmd.c
+ *
+ * Driver for Prism II devices which would usually be driven by orinoco_cs,
+ * but are connected to the PCI bus by a TMD7160. 
+ *
+ * Copyright (C) 2003 Joerg Dorchain <joerg AT dorchain.net>
+ * based heavily upon orinoco_plx.c Copyright (C) 2001 Daniel Barlow
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.
+ *
+ * The actual driving is done by orinoco.c, this is just resource
+ * allocation stuff.
+ *
+ * This driver is modeled after the orinoco_plx driver. The main
+ * difference is that the TMD chip has only IO port ranges and doesn't
+ * provide access to the PCMCIA attribute space.
+ *
+ * Pheecom sells cards with the TMD chip as "ASIC version"
+ */
+
+#define DRIVER_NAME "orinoco_tmd"
+#define PFX DRIVER_NAME ": "
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <pcmcia/cisreg.h>
+
+#include "orinoco.h"
+#include "orinoco_pci.h"
+
+#define COR_VALUE      (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
+#define COR_RESET     (0x80)   /* reset bit in the COR register */
+#define TMD_RESET_TIME (500)   /* milliseconds */
+
+/*
+ * Do a soft reset of the card using the Configuration Option Register
+ */
+static int orinoco_tmd_cor_reset(struct orinoco_private *priv)
+{
+       hermes_t *hw = &priv->hw;
+       struct orinoco_pci_card *card = priv->card;
+       unsigned long timeout;
+       u16 reg;
+
+       iowrite8(COR_VALUE | COR_RESET, card->bridge_io);
+       mdelay(1);
+
+       iowrite8(COR_VALUE, card->bridge_io);
+       mdelay(1);
+
+       /* Just in case, wait more until the card is no longer busy */
+       timeout = jiffies + (TMD_RESET_TIME * HZ / 1000);
+       reg = hermes_read_regn(hw, CMD);
+       while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
+               mdelay(1);
+               reg = hermes_read_regn(hw, CMD);
+       }
+
+       /* Still busy? */
+       if (reg & HERMES_CMD_BUSY) {
+               printk(KERN_ERR PFX "Busy timeout\n");
+               return -ETIMEDOUT;
+       }
+
+       return 0;
+}
+
+
+static int orinoco_tmd_init_one(struct pci_dev *pdev,
+                               const struct pci_device_id *ent)
+{
+       int err;
+       struct orinoco_private *priv;
+       struct orinoco_pci_card *card;
+       struct net_device *dev;
+       void __iomem *hermes_io, *bridge_io;
+
+       err = pci_enable_device(pdev);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot enable PCI device\n");
+               return err;
+       }
+
+       err = pci_request_regions(pdev, DRIVER_NAME);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
+               goto fail_resources;
+       }
+
+       bridge_io = pci_iomap(pdev, 1, 0);
+       if (!bridge_io) {
+               printk(KERN_ERR PFX "Cannot map bridge registers\n");
+               err = -EIO;
+               goto fail_map_bridge;
+       }
+
+       hermes_io = pci_iomap(pdev, 2, 0);
+       if (!hermes_io) {
+               printk(KERN_ERR PFX "Cannot map chipset registers\n");
+               err = -EIO;
+               goto fail_map_hermes;
+       }
+
+       /* Allocate network device */
+       dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
+                              orinoco_tmd_cor_reset, NULL);
+       if (!dev) {
+               printk(KERN_ERR PFX "Cannot allocate network device\n");
+               err = -ENOMEM;
+               goto fail_alloc;
+       }
+
+       priv = netdev_priv(dev);
+       card = priv->card;
+       card->bridge_io = bridge_io;
+       SET_NETDEV_DEV(dev, &pdev->dev);
+
+       hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
+
+       err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
+                         dev->name, dev);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
+               err = -EBUSY;
+               goto fail_irq;
+       }
+
+       err = orinoco_tmd_cor_reset(priv);
+       if (err) {
+               printk(KERN_ERR PFX "Initial reset failed\n");
+               goto fail;
+       }
+
+       err = register_netdev(dev);
+       if (err) {
+               printk(KERN_ERR PFX "Cannot register network device\n");
+               goto fail;
+       }
+
+       pci_set_drvdata(pdev, dev);
+       printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
+              pci_name(pdev));
+
+       return 0;
+
+ fail:
+       free_irq(pdev->irq, dev);
+
+ fail_irq:
+       pci_set_drvdata(pdev, NULL);
+       free_orinocodev(dev);
+
+ fail_alloc:
+       pci_iounmap(pdev, hermes_io);
+
+ fail_map_hermes:
+       pci_iounmap(pdev, bridge_io);
+
+ fail_map_bridge:
+       pci_release_regions(pdev);
+
+ fail_resources:
+       pci_disable_device(pdev);
+
+       return err;
+}
+
+static void __devexit orinoco_tmd_remove_one(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct orinoco_pci_card *card = priv->card;
+
+       unregister_netdev(dev);
+       free_irq(pdev->irq, dev);
+       pci_set_drvdata(pdev, NULL);
+       free_orinocodev(dev);
+       pci_iounmap(pdev, priv->hw.iobase);
+       pci_iounmap(pdev, card->bridge_io);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+}
+
+static struct pci_device_id orinoco_tmd_id_table[] = {
+       {0x15e8, 0x0131, PCI_ANY_ID, PCI_ANY_ID,},      /* NDC and OEMs, e.g. pheecom */
+       {0,},
+};
+
+MODULE_DEVICE_TABLE(pci, orinoco_tmd_id_table);
+
+static struct pci_driver orinoco_tmd_driver = {
+       .name           = DRIVER_NAME,
+       .id_table       = orinoco_tmd_id_table,
+       .probe          = orinoco_tmd_init_one,
+       .remove         = __devexit_p(orinoco_tmd_remove_one),
+       .suspend        = orinoco_pci_suspend,
+       .resume         = orinoco_pci_resume,
+};
+
+static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
+       " (Joerg Dorchain <joerg@dorchain.net>)";
+MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
+MODULE_DESCRIPTION("Driver for wireless LAN cards using the TMD7160 PCI bridge");
+MODULE_LICENSE("Dual MPL/GPL");
+
+static int __init orinoco_tmd_init(void)
+{
+       printk(KERN_DEBUG "%s\n", version);
+       return pci_register_driver(&orinoco_tmd_driver);
+}
+
+static void __exit orinoco_tmd_exit(void)
+{
+       pci_unregister_driver(&orinoco_tmd_driver);
+}
+
+module_init(orinoco_tmd_init);
+module_exit(orinoco_tmd_exit);
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
new file mode 100644 (file)
index 0000000..0bae3dc
--- /dev/null
@@ -0,0 +1,507 @@
+/*
+ * Driver for 802.11b cards using RAM-loadable Symbol firmware, such as
+ * Symbol Wireless Networker LA4137, CompactFlash cards by Socket
+ * Communications and Intel PRO/Wireless 2011B.
+ *
+ * The driver implements Symbol firmware download.  The rest is handled
+ * in hermes.c and orinoco.c.
+ *
+ * Utilities for downloading the Symbol firmware are available at
+ * http://sourceforge.net/projects/orinoco/
+ *
+ * Copyright (C) 2002-2005 Pavel Roskin <proski@gnu.org>
+ * Portions based on orinoco_cs.c:
+ *     Copyright (C) David Gibson, Linuxcare Australia
+ * Portions based on Spectrum24tDnld.c from original spectrum24 driver:
+ *     Copyright (C) Symbol Technologies.
+ *
+ * See copyright notice in file orinoco.c.
+ */
+
+#define DRIVER_NAME "spectrum_cs"
+#define PFX DRIVER_NAME ": "
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+#include "orinoco.h"
+
+/********************************************************************/
+/* Module stuff                                                            */
+/********************************************************************/
+
+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
+MODULE_DESCRIPTION("Driver for Symbol Spectrum24 Trilogy cards with firmware downloader");
+MODULE_LICENSE("Dual MPL/GPL");
+
+/* Module parameters */
+
+/* Some D-Link cards have buggy CIS. They do work at 5v properly, but
+ * don't have any CIS entry for it. This workaround it... */
+static int ignore_cis_vcc; /* = 0 */
+module_param(ignore_cis_vcc, int, 0);
+MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
+
+/********************************************************************/
+/* Data structures                                                 */
+/********************************************************************/
+
+/* PCMCIA specific device information (goes in the card field of
+ * struct orinoco_private */
+struct orinoco_pccard {
+       struct pcmcia_device    *p_dev;
+       dev_node_t node;
+};
+
+/********************************************************************/
+/* Function prototypes                                             */
+/********************************************************************/
+
+static int spectrum_cs_config(struct pcmcia_device *link);
+static void spectrum_cs_release(struct pcmcia_device *link);
+
+/* Constants for the CISREG_CCSR register */
+#define HCR_RUN                0x07    /* run firmware after reset */
+#define HCR_IDLE       0x0E    /* don't run firmware after reset */
+#define HCR_MEM16      0x10    /* memory width bit, should be preserved */
+
+
+#define CS_CHECK(fn, ret) \
+  do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+
+/*
+ * Reset the card using configuration registers COR and CCSR.
+ * If IDLE is 1, stop the firmware, so that it can be safely rewritten.
+ */
+static int
+spectrum_reset(struct pcmcia_device *link, int idle)
+{
+       int last_ret, last_fn;
+       conf_reg_t reg;
+       u_int save_cor;
+
+       /* Doing it if hardware is gone is guaranteed crash */
+       if (!pcmcia_dev_present(link))
+               return -ENODEV;
+
+       /* Save original COR value */
+       reg.Function = 0;
+       reg.Action = CS_READ;
+       reg.Offset = CISREG_COR;
+       CS_CHECK(AccessConfigurationRegister,
+                pcmcia_access_configuration_register(link, &reg));
+       save_cor = reg.Value;
+
+       /* Soft-Reset card */
+       reg.Action = CS_WRITE;
+       reg.Offset = CISREG_COR;
+       reg.Value = (save_cor | COR_SOFT_RESET);
+       CS_CHECK(AccessConfigurationRegister,
+                pcmcia_access_configuration_register(link, &reg));
+       udelay(1000);
+
+       /* Read CCSR */
+       reg.Action = CS_READ;
+       reg.Offset = CISREG_CCSR;
+       CS_CHECK(AccessConfigurationRegister,
+                pcmcia_access_configuration_register(link, &reg));
+
+       /*
+        * Start or stop the firmware.  Memory width bit should be
+        * preserved from the value we've just read.
+        */
+       reg.Action = CS_WRITE;
+       reg.Offset = CISREG_CCSR;
+       reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16);
+       CS_CHECK(AccessConfigurationRegister,
+                pcmcia_access_configuration_register(link, &reg));
+       udelay(1000);
+
+       /* Restore original COR configuration index */
+       reg.Action = CS_WRITE;
+       reg.Offset = CISREG_COR;
+       reg.Value = (save_cor & ~COR_SOFT_RESET);
+       CS_CHECK(AccessConfigurationRegister,
+                pcmcia_access_configuration_register(link, &reg));
+       udelay(1000);
+       return 0;
+
+      cs_failed:
+       cs_error(link, last_fn, last_ret);
+       return -ENODEV;
+}
+
+/********************************************************************/
+/* Device methods                                                  */
+/********************************************************************/
+
+static int
+spectrum_cs_hard_reset(struct orinoco_private *priv)
+{
+       struct orinoco_pccard *card = priv->card;
+       struct pcmcia_device *link = card->p_dev;
+
+       /* Soft reset using COR and HCR */
+       spectrum_reset(link, 0);
+
+       return 0;
+}
+
+static int
+spectrum_cs_stop_firmware(struct orinoco_private *priv, int idle)
+{
+       struct orinoco_pccard *card = priv->card;
+       struct pcmcia_device *link = card->p_dev;
+
+       return spectrum_reset(link, idle);
+}
+
+/********************************************************************/
+/* PCMCIA stuff                                                    */
+/********************************************************************/
+
+/*
+ * This creates an "instance" of the driver, allocating local data
+ * structures for one device.  The device is registered with Card
+ * Services.
+ * 
+ * The dev_link structure is initialized, but we don't actually
+ * configure the card at this point -- we wait until we receive a card
+ * insertion event.  */
+static int
+spectrum_cs_probe(struct pcmcia_device *link)
+{
+       struct net_device *dev;
+       struct orinoco_private *priv;
+       struct orinoco_pccard *card;
+
+       dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
+                              spectrum_cs_hard_reset,
+                              spectrum_cs_stop_firmware);
+       if (! dev)
+               return -ENOMEM;
+       priv = netdev_priv(dev);
+       card = priv->card;
+
+       /* Link both structures together */
+       card->p_dev = link;
+       link->priv = dev;
+
+       /* Interrupt setup */
+       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; 
+
+       /* General socket configuration defaults can go here.  In this
+        * client, we assume very little, and rely on the CIS for
+        * almost everything.  In most clients, many details (i.e.,
+        * number, sizes, and attributes of IO windows) are fixed by
+        * the nature of the device, and can be hard-wired here. */
+       link->conf.Attributes = 0;
+       link->conf.IntType = INT_MEMORY_AND_IO;
+
+       return spectrum_cs_config(link);
+}                              /* spectrum_cs_attach */
+
+/*
+ * This deletes a driver "instance".  The device is de-registered with
+ * Card Services.  If it has been released, all local data structures
+ * are freed.  Otherwise, the structures will be freed when the device
+ * is released.
+ */
+static void spectrum_cs_detach(struct pcmcia_device *link)
+{
+       struct net_device *dev = link->priv;
+
+       if (link->dev_node)
+               unregister_netdev(dev);
+
+       spectrum_cs_release(link);
+
+       free_orinocodev(dev);
+}                              /* spectrum_cs_detach */
+
+/*
+ * spectrum_cs_config() is scheduled to run after a CARD_INSERTION
+ * event is received, to configure the PCMCIA socket, and to make the
+ * device available to the system.
+ */
+
+static int spectrum_cs_config_check(struct pcmcia_device *p_dev,
+                                   cistpl_cftable_entry_t *cfg,
+                                   cistpl_cftable_entry_t *dflt,
+                                   unsigned int vcc,
+                                   void *priv_data)
+{
+       if (cfg->index == 0)
+               goto next_entry;
+
+       /* Use power settings for Vcc and Vpp if present */
+       /* Note that the CIS values need to be rescaled */
+       if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
+               if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
+                       DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n",  vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
+                       if (!ignore_cis_vcc)
+                               goto next_entry;
+               }
+       } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
+               if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) {
+                       DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n",  vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
+                       if (!ignore_cis_vcc)
+                               goto next_entry;
+               }
+       }
+
+       if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
+               p_dev->conf.Vpp =
+                       cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+       else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
+               p_dev->conf.Vpp =
+                       dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+
+       /* Do we need to allocate an interrupt? */
+       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+       /* IO window settings */
+       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+               cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+               if (!(io->flags & CISTPL_IO_8BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+               if (!(io->flags & CISTPL_IO_16BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->io.BasePort1 = io->win[0].base;
+               p_dev->io.NumPorts1 = io->win[0].len;
+               if (io->nwin > 1) {
+                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
+                       p_dev->io.BasePort2 = io->win[1].base;
+                       p_dev->io.NumPorts2 = io->win[1].len;
+               }
+
+               /* This reserves IO space but doesn't actually enable it */
+               if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+                       goto next_entry;
+       }
+       return 0;
+
+next_entry:
+       pcmcia_disable_device(p_dev);
+       return -ENODEV;
+};
+
+static int
+spectrum_cs_config(struct pcmcia_device *link)
+{
+       struct net_device *dev = link->priv;
+       struct orinoco_private *priv = netdev_priv(dev);
+       struct orinoco_pccard *card = priv->card;
+       hermes_t *hw = &priv->hw;
+       int last_fn, last_ret;
+       void __iomem *mem;
+
+       /*
+        * In this loop, we scan the CIS for configuration table
+        * entries, each of which describes a valid card
+        * configuration, including voltage, IO window, memory window,
+        * and interrupt settings.
+        *
+        * We make no assumptions about the card to be configured: we
+        * use just the information available in the CIS.  In an ideal
+        * world, this would work for any PCMCIA card, but it requires
+        * a complete and accurate CIS.  In practice, a driver usually
+        * "knows" most of these things without consulting the CIS,
+        * and most client drivers will only use the CIS to fill in
+        * implementation-defined details.
+        */
+       last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
+       if (last_ret) {
+               if (!ignore_cis_vcc)
+                       printk(KERN_ERR PFX "GetNextTuple(): No matching "
+                              "CIS configuration.  Maybe you need the "
+                              "ignore_cis_vcc=1 parameter.\n");
+               cs_error(link, RequestIO, last_ret);
+               goto failed;
+       }
+
+       /*
+        * Allocate an interrupt line.  Note that this does not assign
+        * a handler to the interrupt, unless the 'Handler' member of
+        * the irq structure is initialized.
+        */
+       CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+
+       /* We initialize the hermes structure before completing PCMCIA
+        * configuration just in case the interrupt handler gets
+        * called. */
+       mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
+       if (!mem)
+               goto cs_failed;
+
+       hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
+
+       /*
+        * This actually configures the PCMCIA socket -- setting up
+        * the I/O windows and the interrupt mapping, and putting the
+        * card and host interface into "Memory and IO" mode.
+        */
+       CS_CHECK(RequestConfiguration,
+                pcmcia_request_configuration(link, &link->conf));
+
+       /* Ok, we have the configuration, prepare to register the netdev */
+       dev->base_addr = link->io.BasePort1;
+       dev->irq = link->irq.AssignedIRQ;
+       card->node.major = card->node.minor = 0;
+
+       /* Reset card */
+       if (spectrum_cs_hard_reset(priv) != 0) {
+               goto failed;
+       }
+
+       SET_NETDEV_DEV(dev, &handle_to_dev(link));
+       /* Tell the stack we exist */
+       if (register_netdev(dev) != 0) {
+               printk(KERN_ERR PFX "register_netdev() failed\n");
+               goto failed;
+       }
+
+       /* At this point, the dev_node_t structure(s) needs to be
+        * initialized and arranged in a linked list at link->dev_node. */
+       strcpy(card->node.dev_name, dev->name);
+       link->dev_node = &card->node; /* link->dev_node being non-NULL is also
+                                    used to indicate that the
+                                    net_device has been registered */
+
+       /* Finally, report what we've done */
+       printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
+              "0x%04x-0x%04x\n", dev->name, dev_name(dev->dev.parent),
+              link->irq.AssignedIRQ, link->io.BasePort1,
+              link->io.BasePort1 + link->io.NumPorts1 - 1);
+
+       return 0;
+
+ cs_failed:
+       cs_error(link, last_fn, last_ret);
+
+ failed:
+       spectrum_cs_release(link);
+       return -ENODEV;
+}                              /* spectrum_cs_config */
+
+/*
+ * After a card is removed, spectrum_cs_release() will unregister the
+ * device, and release the PCMCIA configuration.  If the device is
+ * still open, this will be postponed until it is closed.
+ */
+static void
+spectrum_cs_release(struct pcmcia_device *link)
+{
+       struct net_device *dev = link->priv;
+       struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
+
+       /* We're committed to taking the device away now, so mark the
+        * hardware as unavailable */
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->hw_unavailable++;
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       pcmcia_disable_device(link);
+       if (priv->hw.iobase)
+               ioport_unmap(priv->hw.iobase);
+}                              /* spectrum_cs_release */
+
+
+static int
+spectrum_cs_suspend(struct pcmcia_device *link)
+{
+       struct net_device *dev = link->priv;
+       struct orinoco_private *priv = netdev_priv(dev);
+       unsigned long flags;
+       int err = 0;
+
+       /* Mark the device as stopped, to block IO until later */
+       spin_lock_irqsave(&priv->lock, flags);
+
+       err = __orinoco_down(dev);
+       if (err)
+               printk(KERN_WARNING "%s: Error %d downing interface\n",
+                      dev->name, err);
+
+       netif_device_detach(dev);
+       priv->hw_unavailable++;
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return err;
+}
+
+static int
+spectrum_cs_resume(struct pcmcia_device *link)
+{
+       struct net_device *dev = link->priv;
+       struct orinoco_private *priv = netdev_priv(dev);
+
+       netif_device_attach(dev);
+       priv->hw_unavailable--;
+       schedule_work(&priv->reset_work);
+
+       return 0;
+}
+
+
+/********************************************************************/
+/* Module initialization                                           */
+/********************************************************************/
+
+/* Can't be declared "const" or the whole __initdata section will
+ * become const */
+static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
+       " (Pavel Roskin <proski@gnu.org>,"
+       " David Gibson <hermes@gibson.dropbear.id.au>, et al)";
+
+static struct pcmcia_device_id spectrum_cs_ids[] = {
+       PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4137 */
+       PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */
+       PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless LAN PC Card", 0x816cc815, 0x6fbf459a), /* 2011B, not 2011 */
+       PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, spectrum_cs_ids);
+
+static struct pcmcia_driver orinoco_driver = {
+       .owner          = THIS_MODULE,
+       .drv            = {
+               .name   = DRIVER_NAME,
+       },
+       .probe          = spectrum_cs_probe,
+       .remove         = spectrum_cs_detach,
+       .suspend        = spectrum_cs_suspend,
+       .resume         = spectrum_cs_resume,
+       .id_table       = spectrum_cs_ids,
+};
+
+static int __init
+init_spectrum_cs(void)
+{
+       printk(KERN_DEBUG "%s\n", version);
+
+       return pcmcia_register_driver(&orinoco_driver);
+}
+
+static void __exit
+exit_spectrum_cs(void)
+{
+       pcmcia_unregister_driver(&orinoco_driver);
+}
+
+module_init(init_spectrum_cs);
+module_exit(exit_spectrum_cs);
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
deleted file mode 100644 (file)
index 6fcf2bd..0000000
+++ /dev/null
@@ -1,533 +0,0 @@
-/* orinoco_cs.c (formerly known as dldwd_cs.c)
- *
- * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
- * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
- * EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and others).
- * It should also be usable on various Prism II based cards such as the
- * Linksys, D-Link and Farallon Skyline. It should also work on Symbol
- * cards such as the 3Com AirConnect and Ericsson WLAN.
- * 
- * Copyright notice & release notes in file orinoco.c
- */
-
-#define DRIVER_NAME "orinoco_cs"
-#define PFX DRIVER_NAME ": "
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
-#include <pcmcia/cisreg.h>
-#include <pcmcia/ds.h>
-
-#include "orinoco.h"
-
-/********************************************************************/
-/* Module stuff                                                            */
-/********************************************************************/
-
-MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
-MODULE_DESCRIPTION("Driver for PCMCIA Lucent Orinoco, Prism II based and similar wireless cards");
-MODULE_LICENSE("Dual MPL/GPL");
-
-/* Module parameters */
-
-/* Some D-Link cards have buggy CIS. They do work at 5v properly, but
- * don't have any CIS entry for it. This workaround it... */
-static int ignore_cis_vcc; /* = 0 */
-module_param(ignore_cis_vcc, int, 0);
-MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
-
-/********************************************************************/
-/* Data structures                                                 */
-/********************************************************************/
-
-/* PCMCIA specific device information (goes in the card field of
- * struct orinoco_private */
-struct orinoco_pccard {
-       struct pcmcia_device    *p_dev;
-       dev_node_t node;
-
-       /* Used to handle hard reset */
-       /* yuck, we need this hack to work around the insanity of the
-         * PCMCIA layer */
-       unsigned long hard_reset_in_progress; 
-};
-
-
-/********************************************************************/
-/* Function prototypes                                             */
-/********************************************************************/
-
-static int orinoco_cs_config(struct pcmcia_device *link);
-static void orinoco_cs_release(struct pcmcia_device *link);
-static void orinoco_cs_detach(struct pcmcia_device *p_dev);
-
-/********************************************************************/
-/* Device methods                                                  */
-/********************************************************************/
-
-static int
-orinoco_cs_hard_reset(struct orinoco_private *priv)
-{
-       struct orinoco_pccard *card = priv->card;
-       struct pcmcia_device *link = card->p_dev;
-       int err;
-
-       /* We need atomic ops here, because we're not holding the lock */
-       set_bit(0, &card->hard_reset_in_progress);
-
-       err = pcmcia_reset_card(link->socket);
-       if (err)
-               return err;
-
-       msleep(100);
-       clear_bit(0, &card->hard_reset_in_progress);
-
-       return 0;
-}
-
-/********************************************************************/
-/* PCMCIA stuff                                                    */
-/********************************************************************/
-
-/*
- * This creates an "instance" of the driver, allocating local data
- * structures for one device.  The device is registered with Card
- * Services.
- * 
- * The dev_link structure is initialized, but we don't actually
- * configure the card at this point -- we wait until we receive a card
- * insertion event.  */
-static int
-orinoco_cs_probe(struct pcmcia_device *link)
-{
-       struct net_device *dev;
-       struct orinoco_private *priv;
-       struct orinoco_pccard *card;
-
-       dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
-                              orinoco_cs_hard_reset, NULL);
-       if (! dev)
-               return -ENOMEM;
-       priv = netdev_priv(dev);
-       card = priv->card;
-
-       /* Link both structures together */
-       card->p_dev = link;
-       link->priv = dev;
-
-       /* Interrupt setup */
-       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; 
-
-       /* General socket configuration defaults can go here.  In this
-        * client, we assume very little, and rely on the CIS for
-        * almost everything.  In most clients, many details (i.e.,
-        * number, sizes, and attributes of IO windows) are fixed by
-        * the nature of the device, and can be hard-wired here. */
-       link->conf.Attributes = 0;
-       link->conf.IntType = INT_MEMORY_AND_IO;
-
-       return orinoco_cs_config(link);
-}                              /* orinoco_cs_attach */
-
-/*
- * This deletes a driver "instance".  The device is de-registered with
- * Card Services.  If it has been released, all local data structures
- * are freed.  Otherwise, the structures will be freed when the device
- * is released.
- */
-static void orinoco_cs_detach(struct pcmcia_device *link)
-{
-       struct net_device *dev = link->priv;
-
-       if (link->dev_node)
-               unregister_netdev(dev);
-
-       orinoco_cs_release(link);
-
-       free_orinocodev(dev);
-}                              /* orinoco_cs_detach */
-
-/*
- * orinoco_cs_config() is scheduled to run after a CARD_INSERTION
- * event is received, to configure the PCMCIA socket, and to make the
- * device available to the system.
- */
-
-#define CS_CHECK(fn, ret) do { \
-               last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \
-       } while (0)
-
-static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
-                                  cistpl_cftable_entry_t *cfg,
-                                  cistpl_cftable_entry_t *dflt,
-                                  unsigned int vcc,
-                                  void *priv_data)
-{
-       if (cfg->index == 0)
-               goto next_entry;
-
-       /* Use power settings for Vcc and Vpp if present */
-       /* Note that the CIS values need to be rescaled */
-       if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
-               if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
-                       DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n",  vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
-                       if (!ignore_cis_vcc)
-                               goto next_entry;
-               }
-       } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
-               if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) {
-                       DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n",  vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
-                       if (!ignore_cis_vcc)
-                               goto next_entry;
-               }
-       }
-
-       if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
-               p_dev->conf.Vpp =
-                       cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-       else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
-               p_dev->conf.Vpp =
-                       dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-
-       /* Do we need to allocate an interrupt? */
-       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
-
-       /* IO window settings */
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
-       if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
-               cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-               if (!(io->flags & CISTPL_IO_8BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
-               if (io->nwin > 1) {
-                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
-               }
-
-               /* This reserves IO space but doesn't actually enable it */
-               if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
-                       goto next_entry;
-       }
-       return 0;
-
-next_entry:
-       pcmcia_disable_device(p_dev);
-       return -ENODEV;
-};
-
-static int
-orinoco_cs_config(struct pcmcia_device *link)
-{
-       struct net_device *dev = link->priv;
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct orinoco_pccard *card = priv->card;
-       hermes_t *hw = &priv->hw;
-       int last_fn, last_ret;
-       void __iomem *mem;
-
-       /*
-        * In this loop, we scan the CIS for configuration table
-        * entries, each of which describes a valid card
-        * configuration, including voltage, IO window, memory window,
-        * and interrupt settings.
-        *
-        * We make no assumptions about the card to be configured: we
-        * use just the information available in the CIS.  In an ideal
-        * world, this would work for any PCMCIA card, but it requires
-        * a complete and accurate CIS.  In practice, a driver usually
-        * "knows" most of these things without consulting the CIS,
-        * and most client drivers will only use the CIS to fill in
-        * implementation-defined details.
-        */
-       last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
-       if (last_ret) {
-               if (!ignore_cis_vcc)
-                       printk(KERN_ERR PFX "GetNextTuple(): No matching "
-                              "CIS configuration.  Maybe you need the "
-                              "ignore_cis_vcc=1 parameter.\n");
-               cs_error(link, RequestIO, last_ret);
-               goto failed;
-       }
-
-       /*
-        * Allocate an interrupt line.  Note that this does not assign
-        * a handler to the interrupt, unless the 'Handler' member of
-        * the irq structure is initialized.
-        */
-       CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-
-       /* We initialize the hermes structure before completing PCMCIA
-        * configuration just in case the interrupt handler gets
-        * called. */
-       mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
-       if (!mem)
-               goto cs_failed;
-
-       hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
-
-       /*
-        * This actually configures the PCMCIA socket -- setting up
-        * the I/O windows and the interrupt mapping, and putting the
-        * card and host interface into "Memory and IO" mode.
-        */
-       CS_CHECK(RequestConfiguration,
-                pcmcia_request_configuration(link, &link->conf));
-
-       /* Ok, we have the configuration, prepare to register the netdev */
-       dev->base_addr = link->io.BasePort1;
-       dev->irq = link->irq.AssignedIRQ;
-       card->node.major = card->node.minor = 0;
-
-       SET_NETDEV_DEV(dev, &handle_to_dev(link));
-       /* Tell the stack we exist */
-       if (register_netdev(dev) != 0) {
-               printk(KERN_ERR PFX "register_netdev() failed\n");
-               goto failed;
-       }
-
-       /* At this point, the dev_node_t structure(s) needs to be
-        * initialized and arranged in a linked list at link->dev_node. */
-       strcpy(card->node.dev_name, dev->name);
-       link->dev_node = &card->node; /* link->dev_node being non-NULL is also
-                                    used to indicate that the
-                                    net_device has been registered */
-
-       /* Finally, report what we've done */
-       printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
-              "0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id,
-              link->irq.AssignedIRQ, link->io.BasePort1,
-              link->io.BasePort1 + link->io.NumPorts1 - 1);
-       return 0;
-
- cs_failed:
-       cs_error(link, last_fn, last_ret);
-
- failed:
-       orinoco_cs_release(link);
-       return -ENODEV;
-}                              /* orinoco_cs_config */
-
-/*
- * After a card is removed, orinoco_cs_release() will unregister the
- * device, and release the PCMCIA configuration.  If the device is
- * still open, this will be postponed until it is closed.
- */
-static void
-orinoco_cs_release(struct pcmcia_device *link)
-{
-       struct net_device *dev = link->priv;
-       struct orinoco_private *priv = netdev_priv(dev);
-       unsigned long flags;
-
-       /* We're committed to taking the device away now, so mark the
-        * hardware as unavailable */
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->hw_unavailable++;
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       pcmcia_disable_device(link);
-       if (priv->hw.iobase)
-               ioport_unmap(priv->hw.iobase);
-}                              /* orinoco_cs_release */
-
-static int orinoco_cs_suspend(struct pcmcia_device *link)
-{
-       struct net_device *dev = link->priv;
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct orinoco_pccard *card = priv->card;
-       int err = 0;
-       unsigned long flags;
-
-       /* This is probably racy, but I can't think of
-          a better way, short of rewriting the PCMCIA
-          layer to not suck :-( */
-       if (! test_bit(0, &card->hard_reset_in_progress)) {
-               spin_lock_irqsave(&priv->lock, flags);
-
-               err = __orinoco_down(dev);
-               if (err)
-                       printk(KERN_WARNING "%s: Error %d downing interface\n",
-                              dev->name, err);
-
-               netif_device_detach(dev);
-               priv->hw_unavailable++;
-
-               spin_unlock_irqrestore(&priv->lock, flags);
-       }
-
-       return 0;
-}
-
-static int orinoco_cs_resume(struct pcmcia_device *link)
-{
-       struct net_device *dev = link->priv;
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct orinoco_pccard *card = priv->card;
-       int err = 0;
-       unsigned long flags;
-
-       if (! test_bit(0, &card->hard_reset_in_progress)) {
-               err = orinoco_reinit_firmware(dev);
-               if (err) {
-                       printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
-                              dev->name, err);
-                       return -EIO;
-               }
-
-               spin_lock_irqsave(&priv->lock, flags);
-
-               netif_device_attach(dev);
-               priv->hw_unavailable--;
-
-               if (priv->open && ! priv->hw_unavailable) {
-                       err = __orinoco_up(dev);
-                       if (err)
-                               printk(KERN_ERR "%s: Error %d restarting card\n",
-                                      dev->name, err);
-               }
-
-               spin_unlock_irqrestore(&priv->lock, flags);
-       }
-
-       return err;
-}
-
-
-/********************************************************************/
-/* Module initialization                                           */
-/********************************************************************/
-
-/* Can't be declared "const" or the whole __initdata section will
- * become const */
-static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
-       " (David Gibson <hermes@gibson.dropbear.id.au>, "
-       "Pavel Roskin <proski@gnu.org>, et al)";
-
-static struct pcmcia_device_id orinoco_cs_ids[] = {
-       PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */
-       PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */
-       PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */
-       PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */
-       PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */
-       PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */
-       PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */
-       PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */
-       PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */
-       PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */
-       PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */
-       PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */
-       PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */
-       PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */
-       PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */
-       PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */
-       PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */
-       PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */
-       PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */
-       PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */
-       PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x3021), /* SpeedStream Wireless Adapter */
-       PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */
-       PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */
-       PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */
-       PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */
-       PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */
-       PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */
-       PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */
-       PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9),
-       PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
-       PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5),
-       PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2),
-       PCMCIA_DEVICE_PROD_ID123("AIRVAST", "IEEE 802.11b Wireless PCMCIA Card", "HFA3863", 0xea569531, 0x4bcb9645, 0x355cb092),
-       PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f),
-       PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842),
-       PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e),
-       PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169),
-       PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb),
-       PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3),
-       PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18),
-       PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90),
-       PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b),
-       PCMCIA_DEVICE_PROD_ID123("corega", "WL PCCL-11", "ISL37300P", 0x0a21501a, 0x59868926, 0xc9049a39),
-       PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584),
-       PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9),
-       PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae),
-       PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac),
-       PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab),
-       PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916),
-       PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146),
-       PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3),
-       PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c),
-       PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
-       PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077),
-       PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18),
-       PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77),
-       PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf),
-       PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2),
-       PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92),
-       PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395),
-       PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
-       PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410),
-       PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3),
-       PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01),
-       PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a),
-       PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", 0xa37434e9, 0x9762e8f1),
-       PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1),
-       PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767),
-       PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6),
-       PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed),
-       PCMCIA_DEVICE_PROD_ID123("PCMCIA", "11M WLAN Card v2.5", "ISL37300P", 0x281f1c5d, 0x6e440487, 0xc9049a39),
-       PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264),
-       PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178),
-       PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
-       PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),
-       PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),
-       PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757),
-       PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a),
-       PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
-       PCMCIA_DEVICE_PROD_ID123("The Linksys Group, Inc.", "Instant Wireless Network PC Card", "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39),
-       PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee),
-       PCMCIA_DEVICE_NULL,
-};
-MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids);
-
-static struct pcmcia_driver orinoco_driver = {
-       .owner          = THIS_MODULE,
-       .drv            = {
-               .name   = DRIVER_NAME,
-       },
-       .probe          = orinoco_cs_probe,
-       .remove         = orinoco_cs_detach,
-       .id_table       = orinoco_cs_ids,
-       .suspend        = orinoco_cs_suspend,
-       .resume         = orinoco_cs_resume,
-};
-
-static int __init
-init_orinoco_cs(void)
-{
-       printk(KERN_DEBUG "%s\n", version);
-
-       return pcmcia_register_driver(&orinoco_driver);
-}
-
-static void __exit
-exit_orinoco_cs(void)
-{
-       pcmcia_unregister_driver(&orinoco_driver);
-}
-
-module_init(init_orinoco_cs);
-module_exit(exit_orinoco_cs);
diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c
deleted file mode 100644 (file)
index 2fc8659..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-/* orinoco_nortel.c
- *
- * Driver for Prism II devices which would usually be driven by orinoco_cs,
- * but are connected to the PCI bus by a PCI-to-PCMCIA adapter used in
- * Nortel emobility, Symbol LA-4113 and Symbol LA-4123.
- *
- * Copyright (C) 2002 Tobias Hoffmann
- *           (C) 2003 Christoph Jungegger <disdos@traum404.de>
- *
- * Some of this code is borrowed from orinoco_plx.c
- *     Copyright (C) 2001 Daniel Barlow
- * Some of this code is borrowed from orinoco_pci.c 
- *  Copyright (C) 2001 Jean Tourrilhes
- * Some of this code is "inspired" by linux-wlan-ng-0.1.10, but nothing
- * has been copied from it. linux-wlan-ng-0.1.10 is originally :
- *     Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
- * 
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in
- * which case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
- */
-
-#define DRIVER_NAME "orinoco_nortel"
-#define PFX DRIVER_NAME ": "
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <pcmcia/cisreg.h>
-
-#include "orinoco.h"
-#include "orinoco_pci.h"
-
-#define COR_OFFSET    (0xe0)   /* COR attribute offset of Prism2 PC card */
-#define COR_VALUE     (COR_LEVEL_REQ | COR_FUNC_ENA)   /* Enable PC card with interrupt in level trigger */
-
-
-/*
- * Do a soft reset of the card using the Configuration Option Register
- * We need this to get going...
- * This is the part of the code that is strongly inspired from wlan-ng
- *
- * Note bis : Don't try to access HERMES_CMD during the reset phase.
- * It just won't work !
- */
-static int orinoco_nortel_cor_reset(struct orinoco_private *priv)
-{
-       struct orinoco_pci_card *card = priv->card;
-
-       /* Assert the reset until the card notices */
-       iowrite16(8, card->bridge_io + 2);
-       ioread16(card->attr_io + COR_OFFSET);
-       iowrite16(0x80, card->attr_io + COR_OFFSET);
-       mdelay(1);
-
-       /* Give time for the card to recover from this hard effort */
-       iowrite16(0, card->attr_io + COR_OFFSET);
-       iowrite16(0, card->attr_io + COR_OFFSET);
-       mdelay(1);
-
-       /* Set COR as usual */
-       iowrite16(COR_VALUE, card->attr_io + COR_OFFSET);
-       iowrite16(COR_VALUE, card->attr_io + COR_OFFSET);
-       mdelay(1);
-
-       iowrite16(0x228, card->bridge_io + 2);
-
-       return 0;
-}
-
-static int orinoco_nortel_hw_init(struct orinoco_pci_card *card)
-{
-       int i;
-       u32 reg;
-
-       /* Setup bridge */
-       if (ioread16(card->bridge_io) & 1) {
-               printk(KERN_ERR PFX "brg1 answer1 wrong\n");
-               return -EBUSY;
-       }
-       iowrite16(0x118, card->bridge_io + 2);
-       iowrite16(0x108, card->bridge_io + 2);
-       mdelay(30);
-       iowrite16(0x8, card->bridge_io + 2);
-       for (i = 0; i < 30; i++) {
-               mdelay(30);
-               if (ioread16(card->bridge_io) & 0x10) {
-                       break;
-               }
-       }
-       if (i == 30) {
-               printk(KERN_ERR PFX "brg1 timed out\n");
-               return -EBUSY;
-       }
-       if (ioread16(card->attr_io + COR_OFFSET) & 1) {
-               printk(KERN_ERR PFX "brg2 answer1 wrong\n");
-               return -EBUSY;
-       }
-       if (ioread16(card->attr_io + COR_OFFSET + 2) & 1) {
-               printk(KERN_ERR PFX "brg2 answer2 wrong\n");
-               return -EBUSY;
-       }
-       if (ioread16(card->attr_io + COR_OFFSET + 4) & 1) {
-               printk(KERN_ERR PFX "brg2 answer3 wrong\n");
-               return -EBUSY;
-       }
-
-       /* Set the PCMCIA COR register */
-       iowrite16(COR_VALUE, card->attr_io + COR_OFFSET);
-       mdelay(1);
-       reg = ioread16(card->attr_io + COR_OFFSET);
-       if (reg != COR_VALUE) {
-               printk(KERN_ERR PFX "Error setting COR value (reg=%x)\n",
-                      reg);
-               return -EBUSY;
-       }
-
-       /* Set LEDs */
-       iowrite16(1, card->bridge_io + 10);
-       return 0;
-}
-
-static int orinoco_nortel_init_one(struct pci_dev *pdev,
-                                  const struct pci_device_id *ent)
-{
-       int err;
-       struct orinoco_private *priv;
-       struct orinoco_pci_card *card;
-       struct net_device *dev;
-       void __iomem *hermes_io, *bridge_io, *attr_io;
-
-       err = pci_enable_device(pdev);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot enable PCI device\n");
-               return err;
-       }
-
-       err = pci_request_regions(pdev, DRIVER_NAME);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
-               goto fail_resources;
-       }
-
-       bridge_io = pci_iomap(pdev, 0, 0);
-       if (!bridge_io) {
-               printk(KERN_ERR PFX "Cannot map bridge registers\n");
-               err = -EIO;
-               goto fail_map_bridge;
-       }
-
-       attr_io = pci_iomap(pdev, 1, 0);
-       if (!attr_io) {
-               printk(KERN_ERR PFX "Cannot map PCMCIA attributes\n");
-               err = -EIO;
-               goto fail_map_attr;
-       }
-
-       hermes_io = pci_iomap(pdev, 2, 0);
-       if (!hermes_io) {
-               printk(KERN_ERR PFX "Cannot map chipset registers\n");
-               err = -EIO;
-               goto fail_map_hermes;
-       }
-
-       /* Allocate network device */
-       dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
-                              orinoco_nortel_cor_reset, NULL);
-       if (!dev) {
-               printk(KERN_ERR PFX "Cannot allocate network device\n");
-               err = -ENOMEM;
-               goto fail_alloc;
-       }
-
-       priv = netdev_priv(dev);
-       card = priv->card;
-       card->bridge_io = bridge_io;
-       card->attr_io = attr_io;
-       SET_NETDEV_DEV(dev, &pdev->dev);
-
-       hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
-
-       err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-                         dev->name, dev);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
-               err = -EBUSY;
-               goto fail_irq;
-       }
-
-       err = orinoco_nortel_hw_init(card);
-       if (err) {
-               printk(KERN_ERR PFX "Hardware initialization failed\n");
-               goto fail;
-       }
-
-       err = orinoco_nortel_cor_reset(priv);
-       if (err) {
-               printk(KERN_ERR PFX "Initial reset failed\n");
-               goto fail;
-       }
-
-       err = register_netdev(dev);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot register network device\n");
-               goto fail;
-       }
-
-       pci_set_drvdata(pdev, dev);
-       printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
-              pci_name(pdev));
-
-       return 0;
-
- fail:
-       free_irq(pdev->irq, dev);
-
- fail_irq:
-       pci_set_drvdata(pdev, NULL);
-       free_orinocodev(dev);
-
- fail_alloc:
-       pci_iounmap(pdev, hermes_io);
-
- fail_map_hermes:
-       pci_iounmap(pdev, attr_io);
-
- fail_map_attr:
-       pci_iounmap(pdev, bridge_io);
-
- fail_map_bridge:
-       pci_release_regions(pdev);
-
- fail_resources:
-       pci_disable_device(pdev);
-
-       return err;
-}
-
-static void __devexit orinoco_nortel_remove_one(struct pci_dev *pdev)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct orinoco_pci_card *card = priv->card;
-
-       /* Clear LEDs */
-       iowrite16(0, card->bridge_io + 10);
-
-       unregister_netdev(dev);
-       free_irq(pdev->irq, dev);
-       pci_set_drvdata(pdev, NULL);
-       free_orinocodev(dev);
-       pci_iounmap(pdev, priv->hw.iobase);
-       pci_iounmap(pdev, card->attr_io);
-       pci_iounmap(pdev, card->bridge_io);
-       pci_release_regions(pdev);
-       pci_disable_device(pdev);
-}
-
-static struct pci_device_id orinoco_nortel_id_table[] = {
-       /* Nortel emobility PCI */
-       {0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,},
-       /* Symbol LA-4123 PCI */
-       {0x1562, 0x0001, PCI_ANY_ID, PCI_ANY_ID,},
-       {0,},
-};
-
-MODULE_DEVICE_TABLE(pci, orinoco_nortel_id_table);
-
-static struct pci_driver orinoco_nortel_driver = {
-       .name           = DRIVER_NAME,
-       .id_table       = orinoco_nortel_id_table,
-       .probe          = orinoco_nortel_init_one,
-       .remove         = __devexit_p(orinoco_nortel_remove_one),
-       .suspend        = orinoco_pci_suspend,
-       .resume         = orinoco_pci_resume,
-};
-
-static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
-       " (Tobias Hoffmann & Christoph Jungegger <disdos@traum404.de>)";
-MODULE_AUTHOR("Christoph Jungegger <disdos@traum404.de>");
-MODULE_DESCRIPTION
-    ("Driver for wireless LAN cards using the Nortel PCI bridge");
-MODULE_LICENSE("Dual MPL/GPL");
-
-static int __init orinoco_nortel_init(void)
-{
-       printk(KERN_DEBUG "%s\n", version);
-       return pci_register_driver(&orinoco_nortel_driver);
-}
-
-static void __exit orinoco_nortel_exit(void)
-{
-       pci_unregister_driver(&orinoco_nortel_driver);
-}
-
-module_init(orinoco_nortel_init);
-module_exit(orinoco_nortel_exit);
-
-/*
- * Local variables:
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c
deleted file mode 100644 (file)
index 4ebd638..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/* orinoco_pci.c
- * 
- * Driver for Prism 2.5/3 devices that have a direct PCI interface
- * (i.e. these are not PCMCIA cards in a PCMCIA-to-PCI bridge).
- * The card contains only one PCI region, which contains all the usual
- * hermes registers, as well as the COR register.
- *
- * Current maintainers are:
- *     Pavel Roskin <proski AT gnu.org>
- * and David Gibson <hermes AT gibson.dropbear.id.au>
- *
- * Some of this code is borrowed from orinoco_plx.c
- *     Copyright (C) 2001 Daniel Barlow <dan AT telent.net>
- * Some of this code is "inspired" by linux-wlan-ng-0.1.10, but nothing
- * has been copied from it. linux-wlan-ng-0.1.10 is originally :
- *     Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
- * This file originally written by:
- *     Copyright (C) 2001 Jean Tourrilhes <jt AT hpl.hp.com>
- * And is now maintained by:
- *     (C) Copyright David Gibson, IBM Corp. 2002-2003.
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in
- * which case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
- */
-
-#define DRIVER_NAME "orinoco_pci"
-#define PFX DRIVER_NAME ": "
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-
-#include "orinoco.h"
-#include "orinoco_pci.h"
-
-/* Offset of the COR register of the PCI card */
-#define HERMES_PCI_COR         (0x26)
-
-/* Bitmask to reset the card */
-#define HERMES_PCI_COR_MASK    (0x0080)
-
-/* Magic timeouts for doing the reset.
- * Those times are straight from wlan-ng, and it is claimed that they
- * are necessary. Alan will kill me. Take your time and grab a coffee. */
-#define HERMES_PCI_COR_ONT     (250)           /* ms */
-#define HERMES_PCI_COR_OFFT    (500)           /* ms */
-#define HERMES_PCI_COR_BUSYT   (500)           /* ms */
-
-/*
- * Do a soft reset of the card using the Configuration Option Register
- * We need this to get going...
- * This is the part of the code that is strongly inspired from wlan-ng
- *
- * Note : This code is done with irq enabled. This mean that many
- * interrupts will occur while we are there. This is why we use the
- * jiffies to regulate time instead of a straight mdelay(). Usually we
- * need only around 245 iteration of the loop to do 250 ms delay.
- *
- * Note bis : Don't try to access HERMES_CMD during the reset phase.
- * It just won't work !
- */
-static int orinoco_pci_cor_reset(struct orinoco_private *priv)
-{
-       hermes_t *hw = &priv->hw;
-       unsigned long timeout;
-       u16 reg;
-
-       /* Assert the reset until the card notices */
-       hermes_write_regn(hw, PCI_COR, HERMES_PCI_COR_MASK);
-       mdelay(HERMES_PCI_COR_ONT);
-
-       /* Give time for the card to recover from this hard effort */
-       hermes_write_regn(hw, PCI_COR, 0x0000);
-       mdelay(HERMES_PCI_COR_OFFT);
-
-       /* The card is ready when it's no longer busy */
-       timeout = jiffies + (HERMES_PCI_COR_BUSYT * HZ / 1000);
-       reg = hermes_read_regn(hw, CMD);
-       while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
-               mdelay(1);
-               reg = hermes_read_regn(hw, CMD);
-       }
-
-       /* Still busy? */
-       if (reg & HERMES_CMD_BUSY) {
-               printk(KERN_ERR PFX "Busy timeout\n");
-               return -ETIMEDOUT;
-       }
-
-       return 0;
-}
-
-static int orinoco_pci_init_one(struct pci_dev *pdev,
-                               const struct pci_device_id *ent)
-{
-       int err;
-       struct orinoco_private *priv;
-       struct orinoco_pci_card *card;
-       struct net_device *dev;
-       void __iomem *hermes_io;
-
-       err = pci_enable_device(pdev);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot enable PCI device\n");
-               return err;
-       }
-
-       err = pci_request_regions(pdev, DRIVER_NAME);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
-               goto fail_resources;
-       }
-
-       hermes_io = pci_iomap(pdev, 0, 0);
-       if (!hermes_io) {
-               printk(KERN_ERR PFX "Cannot remap chipset registers\n");
-               err = -EIO;
-               goto fail_map_hermes;
-       }
-
-       /* Allocate network device */
-       dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
-                              orinoco_pci_cor_reset, NULL);
-       if (!dev) {
-               printk(KERN_ERR PFX "Cannot allocate network device\n");
-               err = -ENOMEM;
-               goto fail_alloc;
-       }
-
-       priv = netdev_priv(dev);
-       card = priv->card;
-       SET_NETDEV_DEV(dev, &pdev->dev);
-
-       hermes_struct_init(&priv->hw, hermes_io, HERMES_32BIT_REGSPACING);
-
-       err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-                         dev->name, dev);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
-               err = -EBUSY;
-               goto fail_irq;
-       }
-
-       err = orinoco_pci_cor_reset(priv);
-       if (err) {
-               printk(KERN_ERR PFX "Initial reset failed\n");
-               goto fail;
-       }
-
-       err = register_netdev(dev);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot register network device\n");
-               goto fail;
-       }
-
-       pci_set_drvdata(pdev, dev);
-       printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
-              pci_name(pdev));
-
-       return 0;
-
- fail:
-       free_irq(pdev->irq, dev);
-
- fail_irq:
-       pci_set_drvdata(pdev, NULL);
-       free_orinocodev(dev);
-
- fail_alloc:
-       pci_iounmap(pdev, hermes_io);
-
- fail_map_hermes:
-       pci_release_regions(pdev);
-
- fail_resources:
-       pci_disable_device(pdev);
-
-       return err;
-}
-
-static void __devexit orinoco_pci_remove_one(struct pci_dev *pdev)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-       struct orinoco_private *priv = netdev_priv(dev);
-
-       unregister_netdev(dev);
-       free_irq(pdev->irq, dev);
-       pci_set_drvdata(pdev, NULL);
-       free_orinocodev(dev);
-       pci_iounmap(pdev, priv->hw.iobase);
-       pci_release_regions(pdev);
-       pci_disable_device(pdev);
-}
-
-static struct pci_device_id orinoco_pci_id_table[] = {
-       /* Intersil Prism 3 */
-       {0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID,},
-       /* Intersil Prism 2.5 */
-       {0x1260, 0x3873, PCI_ANY_ID, PCI_ANY_ID,},
-       /* Samsung MagicLAN SWL-2210P */
-       {0x167d, 0xa000, PCI_ANY_ID, PCI_ANY_ID,},
-       {0,},
-};
-
-MODULE_DEVICE_TABLE(pci, orinoco_pci_id_table);
-
-static struct pci_driver orinoco_pci_driver = {
-       .name           = DRIVER_NAME,
-       .id_table       = orinoco_pci_id_table,
-       .probe          = orinoco_pci_init_one,
-       .remove         = __devexit_p(orinoco_pci_remove_one),
-       .suspend        = orinoco_pci_suspend,
-       .resume         = orinoco_pci_resume,
-};
-
-static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
-       " (Pavel Roskin <proski@gnu.org>,"
-       " David Gibson <hermes@gibson.dropbear.id.au> &"
-       " Jean Tourrilhes <jt@hpl.hp.com>)";
-MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
-MODULE_DESCRIPTION("Driver for wireless LAN cards using direct PCI interface");
-MODULE_LICENSE("Dual MPL/GPL");
-
-static int __init orinoco_pci_init(void)
-{
-       printk(KERN_DEBUG "%s\n", version);
-       return pci_register_driver(&orinoco_pci_driver);
-}
-
-static void __exit orinoco_pci_exit(void)
-{
-       pci_unregister_driver(&orinoco_pci_driver);
-}
-
-module_init(orinoco_pci_init);
-module_exit(orinoco_pci_exit);
-
-/*
- * Local variables:
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
diff --git a/drivers/net/wireless/orinoco_pci.h b/drivers/net/wireless/orinoco_pci.h
deleted file mode 100644 (file)
index f4e5e06..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/* orinoco_pci.h
- * 
- * Common code for all Orinoco drivers for PCI devices, including
- * both native PCI and PCMCIA-to-PCI bridges.
- *
- * Copyright (C) 2005, Pavel Roskin.
- * See orinoco.c for license.
- */
-
-#ifndef _ORINOCO_PCI_H
-#define _ORINOCO_PCI_H
-
-#include <linux/netdevice.h>
-
-/* Driver specific data */
-struct orinoco_pci_card {
-       void __iomem *bridge_io;
-       void __iomem *attr_io;
-};
-
-#ifdef CONFIG_PM
-static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-       struct orinoco_private *priv = netdev_priv(dev);
-       unsigned long flags;
-       int err;
-
-       err = orinoco_lock(priv, &flags);
-       if (err) {
-               printk(KERN_ERR "%s: cannot lock hardware for suspend\n",
-                      dev->name);
-               return err;
-       }
-
-       err = __orinoco_down(dev);
-       if (err)
-               printk(KERN_WARNING "%s: error %d bringing interface down "
-                      "for suspend\n", dev->name, err);
-       
-       netif_device_detach(dev);
-
-       priv->hw_unavailable++;
-       
-       orinoco_unlock(priv, &flags);
-
-       free_irq(pdev->irq, dev);
-       pci_save_state(pdev);
-       pci_disable_device(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
-
-       return 0;
-}
-
-static int orinoco_pci_resume(struct pci_dev *pdev)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-       struct orinoco_private *priv = netdev_priv(dev);
-       unsigned long flags;
-       int err;
-
-       pci_set_power_state(pdev, 0);
-       err = pci_enable_device(pdev);
-       if (err) {
-               printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
-                      dev->name);
-               return err;
-       }
-       pci_restore_state(pdev);
-
-       err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-                         dev->name, dev);
-       if (err) {
-               printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n",
-                      dev->name);
-               pci_disable_device(pdev);
-               return -EBUSY;
-       }
-
-       err = orinoco_reinit_firmware(dev);
-       if (err) {
-               printk(KERN_ERR "%s: error %d re-initializing firmware "
-                      "on resume\n", dev->name, err);
-               return err;
-       }
-
-       spin_lock_irqsave(&priv->lock, flags);
-
-       netif_device_attach(dev);
-
-       priv->hw_unavailable--;
-
-       if (priv->open && (! priv->hw_unavailable)) {
-               err = __orinoco_up(dev);
-               if (err)
-                       printk(KERN_ERR "%s: Error %d restarting card on resume\n",
-                              dev->name, err);
-       }
-       
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       return 0;
-}
-#else
-#define orinoco_pci_suspend NULL
-#define orinoco_pci_resume NULL
-#endif
-
-#endif /* _ORINOCO_PCI_H */
diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c
deleted file mode 100644 (file)
index ef76185..0000000
+++ /dev/null
@@ -1,371 +0,0 @@
-/* orinoco_plx.c
- *
- * Driver for Prism II devices which would usually be driven by orinoco_cs,
- * but are connected to the PCI bus by a PLX9052.
- *
- * Current maintainers are:
- *     Pavel Roskin <proski AT gnu.org>
- * and David Gibson <hermes AT gibson.dropbear.id.au>
- *
- * (C) Copyright David Gibson, IBM Corp. 2001-2003.
- * Copyright (C) 2001 Daniel Barlow
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in
- * which case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
- *
- * Here's the general details on how the PLX9052 adapter works:
- *
- * - Two PCI I/O address spaces, one 0x80 long which contains the
- * PLX9052 registers, and one that's 0x40 long mapped to the PCMCIA
- * slot I/O address space.
- *
- * - One PCI memory address space, mapped to the PCMCIA attribute space
- * (containing the CIS).
- *
- * Using the later, you can read through the CIS data to make sure the
- * card is compatible with the driver. Keep in mind that the PCMCIA
- * spec specifies the CIS as the lower 8 bits of each word read from
- * the CIS, so to read the bytes of the CIS, read every other byte
- * (0,2,4,...). Passing that test, you need to enable the I/O address
- * space on the PCMCIA card via the PCMCIA COR register. This is the
- * first byte following the CIS. In my case (which may not have any
- * relation to what's on the PRISM2 cards), COR was at offset 0x800
- * within the PCI memory space. Write 0x41 to the COR register to
- * enable I/O mode and to select level triggered interrupts. To
- * confirm you actually succeeded, read the COR register back and make
- * sure it actually got set to 0x41, in case you have an unexpected
- * card inserted.
- *
- * Following that, you can treat the second PCI I/O address space (the
- * one that's not 0x80 in length) as the PCMCIA I/O space.
- *
- * Note that in the Eumitcom's source for their drivers, they register
- * the interrupt as edge triggered when registering it with the
- * Windows kernel. I don't recall how to register edge triggered on
- * Linux (if it can be done at all). But in some experimentation, I
- * don't see much operational difference between using either
- * interrupt mode. Don't mess with the interrupt mode in the COR
- * register though, as the PLX9052 wants level triggers with the way
- * the serial EEPROM configures it on the WL11000.
- *
- * There's some other little quirks related to timing that I bumped
- * into, but I don't recall right now. Also, there's two variants of
- * the WL11000 I've seen, revision A1 and T2. These seem to differ
- * slightly in the timings configured in the wait-state generator in
- * the PLX9052. There have also been some comments from Eumitcom that
- * cards shouldn't be hot swapped, apparently due to risk of cooking
- * the PLX9052. I'm unsure why they believe this, as I can't see
- * anything in the design that would really cause a problem, except
- * for crashing drivers not written to expect it. And having developed
- * drivers for the WL11000, I'd say it's quite tricky to write code
- * that will successfully deal with a hot unplug. Very odd things
- * happen on the I/O side of things. But anyway, be warned. Despite
- * that, I've hot-swapped a number of times during debugging and
- * driver development for various reasons (stuck WAIT# line after the
- * radio card's firmware locks up).
- */
-
-#define DRIVER_NAME "orinoco_plx"
-#define PFX DRIVER_NAME ": "
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <pcmcia/cisreg.h>
-
-#include "orinoco.h"
-#include "orinoco_pci.h"
-
-#define COR_OFFSET     (0x3e0) /* COR attribute offset of Prism2 PC card */
-#define COR_VALUE      (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
-#define COR_RESET     (0x80)   /* reset bit in the COR register */
-#define PLX_RESET_TIME (500)   /* milliseconds */
-
-#define PLX_INTCSR             0x4c /* Interrupt Control & Status Register */
-#define PLX_INTCSR_INTEN       (1<<6) /* Interrupt Enable bit */
-
-/*
- * Do a soft reset of the card using the Configuration Option Register
- */
-static int orinoco_plx_cor_reset(struct orinoco_private *priv)
-{
-       hermes_t *hw = &priv->hw;
-       struct orinoco_pci_card *card = priv->card;
-       unsigned long timeout;
-       u16 reg;
-
-       iowrite8(COR_VALUE | COR_RESET, card->attr_io + COR_OFFSET);
-       mdelay(1);
-
-       iowrite8(COR_VALUE, card->attr_io + COR_OFFSET);
-       mdelay(1);
-
-       /* Just in case, wait more until the card is no longer busy */
-       timeout = jiffies + (PLX_RESET_TIME * HZ / 1000);
-       reg = hermes_read_regn(hw, CMD);
-       while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
-               mdelay(1);
-               reg = hermes_read_regn(hw, CMD);
-       }
-
-       /* Still busy? */
-       if (reg & HERMES_CMD_BUSY) {
-               printk(KERN_ERR PFX "Busy timeout\n");
-               return -ETIMEDOUT;
-       }
-
-       return 0;
-}
-
-static int orinoco_plx_hw_init(struct orinoco_pci_card *card)
-{
-       int i;
-       u32 csr_reg;
-       static const u8 cis_magic[] = {
-               0x01, 0x03, 0x00, 0x00, 0xff, 0x17, 0x04, 0x67
-       };
-
-       printk(KERN_DEBUG PFX "CIS: ");
-       for (i = 0; i < 16; i++) {
-               printk("%02X:", ioread8(card->attr_io + (i << 1)));
-       }
-       printk("\n");
-
-       /* Verify whether a supported PC card is present */
-       /* FIXME: we probably need to be smarted about this */
-       for (i = 0; i < sizeof(cis_magic); i++) {
-               if (cis_magic[i] != ioread8(card->attr_io + (i << 1))) {
-                       printk(KERN_ERR PFX "The CIS value of Prism2 PC "
-                              "card is unexpected\n");
-                       return -ENODEV;
-               }
-       }
-
-       /* bjoern: We need to tell the card to enable interrupts, in
-          case the serial eprom didn't do this already.  See the
-          PLX9052 data book, p8-1 and 8-24 for reference. */
-       csr_reg = ioread32(card->bridge_io + PLX_INTCSR);
-       if (!(csr_reg & PLX_INTCSR_INTEN)) {
-               csr_reg |= PLX_INTCSR_INTEN;
-               iowrite32(csr_reg, card->bridge_io + PLX_INTCSR);
-               csr_reg = ioread32(card->bridge_io + PLX_INTCSR);
-               if (!(csr_reg & PLX_INTCSR_INTEN)) {
-                       printk(KERN_ERR PFX "Cannot enable interrupts\n");
-                       return -EIO;
-               }
-       }
-
-       return 0;
-}
-
-static int orinoco_plx_init_one(struct pci_dev *pdev,
-                               const struct pci_device_id *ent)
-{
-       int err;
-       struct orinoco_private *priv;
-       struct orinoco_pci_card *card;
-       struct net_device *dev;
-       void __iomem *hermes_io, *attr_io, *bridge_io;
-
-       err = pci_enable_device(pdev);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot enable PCI device\n");
-               return err;
-       }
-
-       err = pci_request_regions(pdev, DRIVER_NAME);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
-               goto fail_resources;
-       }
-
-       bridge_io = pci_iomap(pdev, 1, 0);
-       if (!bridge_io) {
-               printk(KERN_ERR PFX "Cannot map bridge registers\n");
-               err = -EIO;
-               goto fail_map_bridge;
-       }
-
-       attr_io = pci_iomap(pdev, 2, 0);
-       if (!attr_io) {
-               printk(KERN_ERR PFX "Cannot map PCMCIA attributes\n");
-               err = -EIO;
-               goto fail_map_attr;
-       }
-
-       hermes_io = pci_iomap(pdev, 3, 0);
-       if (!hermes_io) {
-               printk(KERN_ERR PFX "Cannot map chipset registers\n");
-               err = -EIO;
-               goto fail_map_hermes;
-       }
-
-       /* Allocate network device */
-       dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
-                              orinoco_plx_cor_reset, NULL);
-       if (!dev) {
-               printk(KERN_ERR PFX "Cannot allocate network device\n");
-               err = -ENOMEM;
-               goto fail_alloc;
-       }
-
-       priv = netdev_priv(dev);
-       card = priv->card;
-       card->bridge_io = bridge_io;
-       card->attr_io = attr_io;
-       SET_NETDEV_DEV(dev, &pdev->dev);
-
-       hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
-
-       err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-                         dev->name, dev);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
-               err = -EBUSY;
-               goto fail_irq;
-       }
-
-       err = orinoco_plx_hw_init(card);
-       if (err) {
-               printk(KERN_ERR PFX "Hardware initialization failed\n");
-               goto fail;
-       }
-
-       err = orinoco_plx_cor_reset(priv);
-       if (err) {
-               printk(KERN_ERR PFX "Initial reset failed\n");
-               goto fail;
-       }
-
-       err = register_netdev(dev);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot register network device\n");
-               goto fail;
-       }
-
-       pci_set_drvdata(pdev, dev);
-       printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
-              pci_name(pdev));
-
-       return 0;
-
- fail:
-       free_irq(pdev->irq, dev);
-
- fail_irq:
-       pci_set_drvdata(pdev, NULL);
-       free_orinocodev(dev);
-
- fail_alloc:
-       pci_iounmap(pdev, hermes_io);
-
- fail_map_hermes:
-       pci_iounmap(pdev, attr_io);
-
- fail_map_attr:
-       pci_iounmap(pdev, bridge_io);
-
- fail_map_bridge:
-       pci_release_regions(pdev);
-
- fail_resources:
-       pci_disable_device(pdev);
-
-       return err;
-}
-
-static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct orinoco_pci_card *card = priv->card;
-
-       unregister_netdev(dev);
-       free_irq(pdev->irq, dev);
-       pci_set_drvdata(pdev, NULL);
-       free_orinocodev(dev);
-       pci_iounmap(pdev, priv->hw.iobase);
-       pci_iounmap(pdev, card->attr_io);
-       pci_iounmap(pdev, card->bridge_io);
-       pci_release_regions(pdev);
-       pci_disable_device(pdev);
-}
-
-static struct pci_device_id orinoco_plx_id_table[] = {
-       {0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,},      /* Siemens SpeedStream SS1023 */
-       {0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,},      /* Netgear MA301 */
-       {0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,},      /* Correga  - does this work? */
-       {0x1638, 0x1100, PCI_ANY_ID, PCI_ANY_ID,},      /* SMC EZConnect SMC2602W,
-                                                          Eumitcom PCI WL11000,
-                                                          Addtron AWA-100 */
-       {0x16ab, 0x1100, PCI_ANY_ID, PCI_ANY_ID,},      /* Global Sun Tech GL24110P */
-       {0x16ab, 0x1101, PCI_ANY_ID, PCI_ANY_ID,},      /* Reported working, but unknown */
-       {0x16ab, 0x1102, PCI_ANY_ID, PCI_ANY_ID,},      /* Linksys WDT11 */
-       {0x16ec, 0x3685, PCI_ANY_ID, PCI_ANY_ID,},      /* USR 2415 */
-       {0xec80, 0xec00, PCI_ANY_ID, PCI_ANY_ID,},      /* Belkin F5D6000 tested by
-                                                          Brendan W. McAdams <rit AT jacked-in.org> */
-       {0x10b7, 0x7770, PCI_ANY_ID, PCI_ANY_ID,},      /* 3Com AirConnect PCI tested by
-                                                          Damien Persohn <damien AT persohn.net> */
-       {0,},
-};
-
-MODULE_DEVICE_TABLE(pci, orinoco_plx_id_table);
-
-static struct pci_driver orinoco_plx_driver = {
-       .name           = DRIVER_NAME,
-       .id_table       = orinoco_plx_id_table,
-       .probe          = orinoco_plx_init_one,
-       .remove         = __devexit_p(orinoco_plx_remove_one),
-       .suspend        = orinoco_pci_suspend,
-       .resume         = orinoco_pci_resume,
-};
-
-static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
-       " (Pavel Roskin <proski@gnu.org>,"
-       " David Gibson <hermes@gibson.dropbear.id.au>,"
-       " Daniel Barlow <dan@telent.net>)";
-MODULE_AUTHOR("Daniel Barlow <dan@telent.net>");
-MODULE_DESCRIPTION("Driver for wireless LAN cards using the PLX9052 PCI bridge");
-MODULE_LICENSE("Dual MPL/GPL");
-
-static int __init orinoco_plx_init(void)
-{
-       printk(KERN_DEBUG "%s\n", version);
-       return pci_register_driver(&orinoco_plx_driver);
-}
-
-static void __exit orinoco_plx_exit(void)
-{
-       pci_unregister_driver(&orinoco_plx_driver);
-}
-
-module_init(orinoco_plx_init);
-module_exit(orinoco_plx_exit);
-
-/*
- * Local variables:
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
diff --git a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c
deleted file mode 100644 (file)
index ede24ec..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/* orinoco_tmd.c
- *
- * Driver for Prism II devices which would usually be driven by orinoco_cs,
- * but are connected to the PCI bus by a TMD7160. 
- *
- * Copyright (C) 2003 Joerg Dorchain <joerg AT dorchain.net>
- * based heavily upon orinoco_plx.c Copyright (C) 2001 Daniel Barlow
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in
- * which case the provisions of the GPL are applicable instead of the
- * above.  If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL.  If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
- *
- * The actual driving is done by orinoco.c, this is just resource
- * allocation stuff.
- *
- * This driver is modeled after the orinoco_plx driver. The main
- * difference is that the TMD chip has only IO port ranges and doesn't
- * provide access to the PCMCIA attribute space.
- *
- * Pheecom sells cards with the TMD chip as "ASIC version"
- */
-
-#define DRIVER_NAME "orinoco_tmd"
-#define PFX DRIVER_NAME ": "
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <pcmcia/cisreg.h>
-
-#include "orinoco.h"
-#include "orinoco_pci.h"
-
-#define COR_VALUE      (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
-#define COR_RESET     (0x80)   /* reset bit in the COR register */
-#define TMD_RESET_TIME (500)   /* milliseconds */
-
-/*
- * Do a soft reset of the card using the Configuration Option Register
- */
-static int orinoco_tmd_cor_reset(struct orinoco_private *priv)
-{
-       hermes_t *hw = &priv->hw;
-       struct orinoco_pci_card *card = priv->card;
-       unsigned long timeout;
-       u16 reg;
-
-       iowrite8(COR_VALUE | COR_RESET, card->bridge_io);
-       mdelay(1);
-
-       iowrite8(COR_VALUE, card->bridge_io);
-       mdelay(1);
-
-       /* Just in case, wait more until the card is no longer busy */
-       timeout = jiffies + (TMD_RESET_TIME * HZ / 1000);
-       reg = hermes_read_regn(hw, CMD);
-       while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
-               mdelay(1);
-               reg = hermes_read_regn(hw, CMD);
-       }
-
-       /* Still busy? */
-       if (reg & HERMES_CMD_BUSY) {
-               printk(KERN_ERR PFX "Busy timeout\n");
-               return -ETIMEDOUT;
-       }
-
-       return 0;
-}
-
-
-static int orinoco_tmd_init_one(struct pci_dev *pdev,
-                               const struct pci_device_id *ent)
-{
-       int err;
-       struct orinoco_private *priv;
-       struct orinoco_pci_card *card;
-       struct net_device *dev;
-       void __iomem *hermes_io, *bridge_io;
-
-       err = pci_enable_device(pdev);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot enable PCI device\n");
-               return err;
-       }
-
-       err = pci_request_regions(pdev, DRIVER_NAME);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
-               goto fail_resources;
-       }
-
-       bridge_io = pci_iomap(pdev, 1, 0);
-       if (!bridge_io) {
-               printk(KERN_ERR PFX "Cannot map bridge registers\n");
-               err = -EIO;
-               goto fail_map_bridge;
-       }
-
-       hermes_io = pci_iomap(pdev, 2, 0);
-       if (!hermes_io) {
-               printk(KERN_ERR PFX "Cannot map chipset registers\n");
-               err = -EIO;
-               goto fail_map_hermes;
-       }
-
-       /* Allocate network device */
-       dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
-                              orinoco_tmd_cor_reset, NULL);
-       if (!dev) {
-               printk(KERN_ERR PFX "Cannot allocate network device\n");
-               err = -ENOMEM;
-               goto fail_alloc;
-       }
-
-       priv = netdev_priv(dev);
-       card = priv->card;
-       card->bridge_io = bridge_io;
-       SET_NETDEV_DEV(dev, &pdev->dev);
-
-       hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
-
-       err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-                         dev->name, dev);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
-               err = -EBUSY;
-               goto fail_irq;
-       }
-
-       err = orinoco_tmd_cor_reset(priv);
-       if (err) {
-               printk(KERN_ERR PFX "Initial reset failed\n");
-               goto fail;
-       }
-
-       err = register_netdev(dev);
-       if (err) {
-               printk(KERN_ERR PFX "Cannot register network device\n");
-               goto fail;
-       }
-
-       pci_set_drvdata(pdev, dev);
-       printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
-              pci_name(pdev));
-
-       return 0;
-
- fail:
-       free_irq(pdev->irq, dev);
-
- fail_irq:
-       pci_set_drvdata(pdev, NULL);
-       free_orinocodev(dev);
-
- fail_alloc:
-       pci_iounmap(pdev, hermes_io);
-
- fail_map_hermes:
-       pci_iounmap(pdev, bridge_io);
-
- fail_map_bridge:
-       pci_release_regions(pdev);
-
- fail_resources:
-       pci_disable_device(pdev);
-
-       return err;
-}
-
-static void __devexit orinoco_tmd_remove_one(struct pci_dev *pdev)
-{
-       struct net_device *dev = pci_get_drvdata(pdev);
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct orinoco_pci_card *card = priv->card;
-
-       unregister_netdev(dev);
-       free_irq(pdev->irq, dev);
-       pci_set_drvdata(pdev, NULL);
-       free_orinocodev(dev);
-       pci_iounmap(pdev, priv->hw.iobase);
-       pci_iounmap(pdev, card->bridge_io);
-       pci_release_regions(pdev);
-       pci_disable_device(pdev);
-}
-
-static struct pci_device_id orinoco_tmd_id_table[] = {
-       {0x15e8, 0x0131, PCI_ANY_ID, PCI_ANY_ID,},      /* NDC and OEMs, e.g. pheecom */
-       {0,},
-};
-
-MODULE_DEVICE_TABLE(pci, orinoco_tmd_id_table);
-
-static struct pci_driver orinoco_tmd_driver = {
-       .name           = DRIVER_NAME,
-       .id_table       = orinoco_tmd_id_table,
-       .probe          = orinoco_tmd_init_one,
-       .remove         = __devexit_p(orinoco_tmd_remove_one),
-       .suspend        = orinoco_pci_suspend,
-       .resume         = orinoco_pci_resume,
-};
-
-static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
-       " (Joerg Dorchain <joerg@dorchain.net>)";
-MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
-MODULE_DESCRIPTION("Driver for wireless LAN cards using the TMD7160 PCI bridge");
-MODULE_LICENSE("Dual MPL/GPL");
-
-static int __init orinoco_tmd_init(void)
-{
-       printk(KERN_DEBUG "%s\n", version);
-       return pci_register_driver(&orinoco_tmd_driver);
-}
-
-static void __exit orinoco_tmd_exit(void)
-{
-       pci_unregister_driver(&orinoco_tmd_driver);
-}
-
-module_init(orinoco_tmd_init);
-module_exit(orinoco_tmd_exit);
-
-/*
- * Local variables:
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
index 1d0704fe146fb72ed0691271a7bd8491096481b2..b585ff65e0e42ec4957746cedd61ed1e6e95202e 100644 (file)
  * published by the Free Software Foundation.
  */
 
-enum control_frame_types {
-       P54_CONTROL_TYPE_FILTER_SET = 0,
-       P54_CONTROL_TYPE_CHANNEL_CHANGE,
-       P54_CONTROL_TYPE_FREQDONE,
+enum p54_control_frame_types {
+       P54_CONTROL_TYPE_SETUP = 0,
+       P54_CONTROL_TYPE_SCAN,
+       P54_CONTROL_TYPE_TRAP,
        P54_CONTROL_TYPE_DCFINIT,
-       P54_CONTROL_TYPE_ENCRYPTION,
+       P54_CONTROL_TYPE_RX_KEYCACHE,
        P54_CONTROL_TYPE_TIM,
-       P54_CONTROL_TYPE_POWERMGT,
-       P54_CONTROL_TYPE_FREEQUEUE,
+       P54_CONTROL_TYPE_PSM,
+       P54_CONTROL_TYPE_TXCANCEL,
        P54_CONTROL_TYPE_TXDONE,
-       P54_CONTROL_TYPE_PING,
+       P54_CONTROL_TYPE_BURST,
        P54_CONTROL_TYPE_STAT_READBACK,
        P54_CONTROL_TYPE_BBP,
        P54_CONTROL_TYPE_EEPROM_READBACK,
@@ -37,18 +37,30 @@ enum control_frame_types {
        P54_CONTROL_TYPE_XBOW_SYNTH_CFG,
        P54_CONTROL_TYPE_CCE_QUIET,
        P54_CONTROL_TYPE_PSM_STA_UNLOCK,
+       P54_CONTROL_TYPE_PCS,
+       P54_CONTROL_TYPE_BT_BALANCER = 28,
+       P54_CONTROL_TYPE_GROUP_ADDRESS_TABLE = 30,
+       P54_CONTROL_TYPE_ARPTABLE = 31,
+       P54_CONTROL_TYPE_BT_OPTIONS = 35
 };
 
-struct p54_control_hdr {
-       __le16 magic1;
+struct p54_hdr {
+       __le16 flags;
        __le16 len;
        __le32 req_id;
-       __le16 type;    /* enum control_frame_types */
-       u8 retry1;
-       u8 retry2;
+       __le16 type;    /* enum p54_control_frame_types */
+       u8 rts_tries;
+       u8 tries;
        u8 data[0];
 } __attribute__ ((packed));
 
+struct p54_edcf_queue_param {
+       __le16 aifs;
+       __le16 cwmin;
+       __le16 cwmax;
+       __le16 txop;
+} __attribute__ ((packed));
+
 #define EEPROM_READBACK_LEN 0x3fc
 
 #define ISL38XX_DEV_FIRMWARE_ADDR 0x20000
@@ -62,46 +74,48 @@ struct p54_common {
        u32 rx_start;
        u32 rx_end;
        struct sk_buff_head tx_queue;
-       void (*tx)(struct ieee80211_hw *dev, struct p54_control_hdr *data,
-                  size_t len, int free_on_tx);
+       void (*tx)(struct ieee80211_hw *dev, struct sk_buff *skb,
+                  int free_on_tx);
        int (*open)(struct ieee80211_hw *dev);
        void (*stop)(struct ieee80211_hw *dev);
        int mode;
-       u16 seqno;
        u16 rx_mtu;
        u8 headroom;
        u8 tailroom;
        struct mutex conf_mutex;
        u8 mac_addr[ETH_ALEN];
        u8 bssid[ETH_ALEN];
-       __le16 filter_type;
+       u16 mac_mode;
        struct pda_iq_autocal_entry *iq_autocal;
        unsigned int iq_autocal_len;
        struct pda_channel_output_limit *output_limit;
        unsigned int output_limit_len;
        struct pda_pa_curve_data *curve_data;
        unsigned int filter_flags;
+       bool use_short_slot;
        u16 rxhw;
        u8 version;
        u8 rx_antenna;
        unsigned int tx_hdr_len;
-       void *cached_vdcf;
        unsigned int fw_var;
        unsigned int fw_interface;
        unsigned int output_power;
        u32 tsf_low32;
        u32 tsf_high32;
        struct ieee80211_tx_queue_stats tx_stats[8];
+       struct p54_edcf_queue_param qos_params[8];
        struct ieee80211_low_level_stats stats;
        struct timer_list stats_timer;
        struct completion stats_comp;
-       void *cached_stats;
+       struct sk_buff *cached_stats;
+       struct sk_buff *cached_beacon;
        int noise;
        void *eeprom;
        struct completion eeprom_comp;
 };
 
 int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb);
+void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb);
 int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw);
 int p54_read_eeprom(struct ieee80211_hw *dev);
 struct ieee80211_hw *p54_init_common(size_t priv_data_len);
index 827ca0384a4ca220151a048528964ffcbf172ee3..1796b8c6c5b83111d8e2e526e080846ed0db05ee 100644 (file)
@@ -1,12 +1,15 @@
-
 /*
  * Common code for mac80211 Prism54 drivers
  *
  * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
  * Copyright (c) 2007, Christian Lamparter <chunkeey@web.de>
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
  *
- * Based on the islsm (softmac prism54) driver, which is:
- * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
+ * Based on:
+ * - the islsm (softmac prism54) driver, which is:
+ *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
+ * - stlc45xx driver
+ *   Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
  *
  * 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
@@ -183,7 +186,7 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
                        priv->headroom = desc->headroom;
                        priv->tailroom = desc->tailroom;
                        if (le32_to_cpu(bootrec->len) == 11)
-                               priv->rx_mtu = le16_to_cpu(bootrec->rx_mtu);
+                               priv->rx_mtu = le16_to_cpu(desc->rx_mtu);
                        else
                                priv->rx_mtu = (size_t)
                                        0x620 - priv->tx_hdr_len;
@@ -211,12 +214,17 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
                printk(KERN_INFO "p54: FW rev %s - Softmac protocol %x.%x\n",
                        fw_version, priv->fw_var >> 8, priv->fw_var & 0xff);
 
+       if (priv->fw_var < 0x500)
+               printk(KERN_INFO "p54: you are using an obsolete firmware. "
+                      "visit http://wireless.kernel.org/en/users/Drivers/p54 "
+                      "and grab one for \"kernel >= 2.6.28\"!\n");
+
        if (priv->fw_var >= 0x300) {
                /* Firmware supports QoS, use it! */
-               priv->tx_stats[4].limit = 3;
-               priv->tx_stats[5].limit = 4;
-               priv->tx_stats[6].limit = 3;
-               priv->tx_stats[7].limit = 1;
+               priv->tx_stats[4].limit = 3;            /* AC_VO */
+               priv->tx_stats[5].limit = 4;            /* AC_VI */
+               priv->tx_stats[6].limit = 3;            /* AC_BE */
+               priv->tx_stats[7].limit = 2;            /* AC_BK */
                dev->queues = 4;
        }
 
@@ -320,7 +328,6 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
        int err;
        u8 *end = (u8 *)eeprom + len;
        u16 synth = 0;
-       DECLARE_MAC_BUF(mac);
 
        wrap = (struct eeprom_pda_wrap *) eeprom;
        entry = (void *)wrap->data + le16_to_cpu(wrap->len);
@@ -413,6 +420,30 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
                        /* make it overrun */
                        entry_len = len;
                        break;
+               case PDR_MANUFACTURING_PART_NUMBER:
+               case PDR_PDA_VERSION:
+               case PDR_NIC_SERIAL_NUMBER:
+               case PDR_REGULATORY_DOMAIN_LIST:
+               case PDR_TEMPERATURE_TYPE:
+               case PDR_PRISM_PCI_IDENTIFIER:
+               case PDR_COUNTRY_INFORMATION:
+               case PDR_OEM_NAME:
+               case PDR_PRODUCT_NAME:
+               case PDR_UTF8_OEM_NAME:
+               case PDR_UTF8_PRODUCT_NAME:
+               case PDR_COUNTRY_LIST:
+               case PDR_DEFAULT_COUNTRY:
+               case PDR_ANTENNA_GAIN:
+               case PDR_PRISM_INDIGO_PA_CALIBRATION_DATA:
+               case PDR_RSSI_LINEAR_APPROXIMATION:
+               case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
+               case PDR_REGULATORY_POWER_LIMITS:
+               case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
+               case PDR_RADIATED_TRANSMISSION_CORRECTION:
+               case PDR_PRISM_TX_IQ_CALIBRATION:
+               case PDR_BASEBAND_REGISTERS:
+               case PDR_PER_CHANNEL_BASEBAND_REGISTERS:
+                       break;
                default:
                        printk(KERN_INFO "p54: unknown eeprom code : 0x%x\n",
                                le16_to_cpu(entry->code));
@@ -429,12 +460,12 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
                goto err;
        }
 
-       priv->rxhw = synth & 0x07;
+       priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK;
        if (priv->rxhw == 4)
                p54_init_xbow_synth(dev);
-       if (!(synth & 0x40))
+       if (!(synth & PDR_SYNTH_24_GHZ_DISABLED))
                dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
-       if (!(synth & 0x80))
+       if (!(synth & PDR_SYNTH_5_GHZ_DISABLED))
                dev->wiphy->bands[IEEE80211_BAND_5GHZ] = &band_5GHz;
 
        if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
@@ -446,9 +477,9 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
                SET_IEEE80211_PERM_ADDR(dev, perm_addr);
        }
 
-       printk(KERN_INFO "%s: hwaddr %s, MAC:isl38%02x RF:%s\n",
+       printk(KERN_INFO "%s: hwaddr %pM, MAC:isl38%02x RF:%s\n",
                wiphy_name(dev->wiphy),
-               print_mac(mac, dev->wiphy->perm_addr),
+               dev->wiphy->perm_addr,
                priv->version, p54_rf_chips[priv->rxhw]);
 
        return 0;
@@ -482,13 +513,13 @@ static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi)
 static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct p54_common *priv = dev->priv;
-       struct p54_rx_hdr *hdr = (struct p54_rx_hdr *) skb->data;
+       struct p54_rx_data *hdr = (struct p54_rx_data *) skb->data;
        struct ieee80211_rx_status rx_status = {0};
        u16 freq = le16_to_cpu(hdr->freq);
        size_t header_len = sizeof(*hdr);
        u32 tsf32;
 
-       if (!(hdr->magic & cpu_to_le16(0x0001))) {
+       if (!(hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_IN_FCS_GOOD))) {
                if (priv->filter_flags & FIF_FCSFAIL)
                        rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
                else
@@ -513,7 +544,7 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
 
        rx_status.flag |= RX_FLAG_TSFT;
 
-       if (hdr->magic & cpu_to_le16(0x4000))
+       if (hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN))
                header_len += hdr->align[0];
 
        skb_pull(skb, header_len);
@@ -529,81 +560,155 @@ static void inline p54_wake_free_queues(struct ieee80211_hw *dev)
        struct p54_common *priv = dev->priv;
        int i;
 
+       if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+               return ;
+
        for (i = 0; i < dev->queues; i++)
                if (priv->tx_stats[i + 4].len < priv->tx_stats[i + 4].limit)
                        ieee80211_wake_queue(dev, i);
 }
 
+void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
+{
+       struct p54_common *priv = dev->priv;
+       struct ieee80211_tx_info *info;
+       struct memrecord *range;
+       unsigned long flags;
+       u32 freed = 0, last_addr = priv->rx_start;
+
+       if (!skb || !dev)
+               return;
+
+       spin_lock_irqsave(&priv->tx_queue.lock, flags);
+       info = IEEE80211_SKB_CB(skb);
+       range = (void *)info->rate_driver_data;
+       if (skb->prev != (struct sk_buff *)&priv->tx_queue) {
+               struct ieee80211_tx_info *ni;
+               struct memrecord *mr;
+
+               ni = IEEE80211_SKB_CB(skb->prev);
+               mr = (struct memrecord *)ni->rate_driver_data;
+               last_addr = mr->end_addr;
+       }
+       if (skb->next != (struct sk_buff *)&priv->tx_queue) {
+               struct ieee80211_tx_info *ni;
+               struct memrecord *mr;
+
+               ni = IEEE80211_SKB_CB(skb->next);
+               mr = (struct memrecord *)ni->rate_driver_data;
+               freed = mr->start_addr - last_addr;
+       } else
+               freed = priv->rx_end - last_addr;
+       __skb_unlink(skb, &priv->tx_queue);
+       spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
+       kfree_skb(skb);
+
+       if (freed >= priv->headroom + sizeof(struct p54_hdr) + 48 +
+                    IEEE80211_MAX_RTS_THRESHOLD + priv->tailroom)
+               p54_wake_free_queues(dev);
+}
+EXPORT_SYMBOL_GPL(p54_free_skb);
+
 static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct p54_common *priv = dev->priv;
-       struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
-       struct p54_frame_sent_hdr *payload = (struct p54_frame_sent_hdr *) hdr->data;
+       struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
+       struct p54_frame_sent *payload = (struct p54_frame_sent *) hdr->data;
        struct sk_buff *entry = (struct sk_buff *) priv->tx_queue.next;
        u32 addr = le32_to_cpu(hdr->req_id) - priv->headroom;
        struct memrecord *range = NULL;
        u32 freed = 0;
        u32 last_addr = priv->rx_start;
        unsigned long flags;
+       int count, idx;
 
        spin_lock_irqsave(&priv->tx_queue.lock, flags);
        while (entry != (struct sk_buff *)&priv->tx_queue) {
                struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
-               range = (void *)info->driver_data;
-               if (range->start_addr == addr) {
-                       struct p54_control_hdr *entry_hdr;
-                       struct p54_tx_control_allocdata *entry_data;
-                       int pad = 0;
-
-                       if (entry->next != (struct sk_buff *)&priv->tx_queue) {
-                               struct ieee80211_tx_info *ni;
-                               struct memrecord *mr;
-
-                               ni = IEEE80211_SKB_CB(entry->next);
-                               mr = (struct memrecord *)ni->driver_data;
-                               freed = mr->start_addr - last_addr;
-                       } else
-                               freed = priv->rx_end - last_addr;
+               struct p54_hdr *entry_hdr;
+               struct p54_tx_data *entry_data;
+               int pad = 0;
 
+               range = (void *)info->rate_driver_data;
+               if (range->start_addr != addr) {
                        last_addr = range->end_addr;
-                       __skb_unlink(entry, &priv->tx_queue);
-                       spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
-
-                       memset(&info->status, 0, sizeof(info->status));
-                       entry_hdr = (struct p54_control_hdr *) entry->data;
-                       entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data;
-                       if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0)
-                               pad = entry_data->align[0];
-
-                       priv->tx_stats[entry_data->hw_queue].len--;
-                       if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
-                               if (!(payload->status & 0x01))
-                                       info->flags |= IEEE80211_TX_STAT_ACK;
-                               else
-                                       info->status.excessive_retries = 1;
-                       }
-                       info->status.retry_count = payload->retries - 1;
-                       info->status.ack_signal = p54_rssi_to_dbm(dev,
-                                       le16_to_cpu(payload->ack_rssi));
-                       skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
-                       ieee80211_tx_status_irqsafe(dev, entry);
-                       goto out;
+                       entry = entry->next;
+                       continue;
+               }
+
+               if (entry->next != (struct sk_buff *)&priv->tx_queue) {
+                       struct ieee80211_tx_info *ni;
+                       struct memrecord *mr;
+
+                       ni = IEEE80211_SKB_CB(entry->next);
+                       mr = (struct memrecord *)ni->rate_driver_data;
+                       freed = mr->start_addr - last_addr;
                } else
-                       last_addr = range->end_addr;
-               entry = entry->next;
+                       freed = priv->rx_end - last_addr;
+
+               last_addr = range->end_addr;
+               __skb_unlink(entry, &priv->tx_queue);
+               spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
+
+               if (unlikely(entry == priv->cached_beacon)) {
+                       kfree_skb(entry);
+                       priv->cached_beacon = NULL;
+                       goto out;
+               }
+
+               /*
+                * Clear manually, ieee80211_tx_info_clear_status would
+                * clear the counts too and we need them.
+                */
+               memset(&info->status.ampdu_ack_len, 0,
+                      sizeof(struct ieee80211_tx_info) -
+                      offsetof(struct ieee80211_tx_info, status.ampdu_ack_len));
+               BUILD_BUG_ON(offsetof(struct ieee80211_tx_info,
+                                     status.ampdu_ack_len) != 23);
+
+               entry_hdr = (struct p54_hdr *) entry->data;
+               entry_data = (struct p54_tx_data *) entry_hdr->data;
+               if (entry_hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN))
+                       pad = entry_data->align[0];
+
+               /* walk through the rates array and adjust the counts */
+               count = payload->tries;
+               for (idx = 0; idx < 4; idx++) {
+                       if (count >= info->status.rates[idx].count) {
+                               count -= info->status.rates[idx].count;
+                       } else if (count > 0) {
+                               info->status.rates[idx].count = count;
+                               count = 0;
+                       } else {
+                               info->status.rates[idx].idx = -1;
+                               info->status.rates[idx].count = 0;
+                       }
+               }
+
+               priv->tx_stats[entry_data->hw_queue].len--;
+               if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+                    (!payload->status))
+                       info->flags |= IEEE80211_TX_STAT_ACK;
+               if (payload->status & P54_TX_PSM_CANCELLED)
+                       info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+               info->status.ack_signal = p54_rssi_to_dbm(dev,
+                               (int)payload->ack_rssi);
+               skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
+               ieee80211_tx_status_irqsafe(dev, entry);
+               goto out;
        }
        spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
 
 out:
-       if (freed >= IEEE80211_MAX_RTS_THRESHOLD + 0x170 +
-           sizeof(struct p54_control_hdr))
+       if (freed >= priv->headroom + sizeof(struct p54_hdr) + 48 +
+                    IEEE80211_MAX_RTS_THRESHOLD + priv->tailroom)
                p54_wake_free_queues(dev);
 }
 
 static void p54_rx_eeprom_readback(struct ieee80211_hw *dev,
                                   struct sk_buff *skb)
 {
-       struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
+       struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
        struct p54_eeprom_lm86 *eeprom = (struct p54_eeprom_lm86 *) hdr->data;
        struct p54_common *priv = dev->priv;
 
@@ -618,7 +723,7 @@ static void p54_rx_eeprom_readback(struct ieee80211_hw *dev,
 static void p54_rx_stats(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct p54_common *priv = dev->priv;
-       struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
+       struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
        struct p54_statistics *stats = (struct p54_statistics *) hdr->data;
        u32 tsf32 = le32_to_cpu(stats->tsf32);
 
@@ -636,14 +741,46 @@ static void p54_rx_stats(struct ieee80211_hw *dev, struct sk_buff *skb)
        mod_timer(&priv->stats_timer, jiffies + 5 * HZ);
 }
 
+static void p54_rx_trap(struct ieee80211_hw *dev, struct sk_buff *skb)
+{
+       struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
+       struct p54_trap *trap = (struct p54_trap *) hdr->data;
+       u16 event = le16_to_cpu(trap->event);
+       u16 freq = le16_to_cpu(trap->frequency);
+
+       switch (event) {
+       case P54_TRAP_BEACON_TX:
+               break;
+       case P54_TRAP_RADAR:
+               printk(KERN_INFO "%s: radar (freq:%d MHz)\n",
+                       wiphy_name(dev->wiphy), freq);
+               break;
+       case P54_TRAP_NO_BEACON:
+               break;
+       case P54_TRAP_SCAN:
+               break;
+       case P54_TRAP_TBTT:
+               break;
+       case P54_TRAP_TIMER:
+               break;
+       default:
+               printk(KERN_INFO "%s: received event:%x freq:%d\n",
+                      wiphy_name(dev->wiphy), event, freq);
+               break;
+       }
+}
+
 static int p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
-       struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
+       struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
 
        switch (le16_to_cpu(hdr->type)) {
        case P54_CONTROL_TYPE_TXDONE:
                p54_rx_frame_sent(dev, skb);
                break;
+       case P54_CONTROL_TYPE_TRAP:
+               p54_rx_trap(dev, skb);
+               break;
        case P54_CONTROL_TYPE_BBP:
                break;
        case P54_CONTROL_TYPE_STAT_READBACK:
@@ -664,9 +801,9 @@ static int p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb)
 /* returns zero if skb can be reused */
 int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
-       u8 type = le16_to_cpu(*((__le16 *)skb->data)) >> 8;
+       u16 type = le16_to_cpu(*((__le16 *)skb->data));
 
-       if (type == 0x80)
+       if (type & P54_HDR_FLAG_CONTROL)
                return p54_rx_control(dev, skb);
        else
                return p54_rx_data(dev, skb);
@@ -682,12 +819,14 @@ EXPORT_SYMBOL_GPL(p54_rx);
  * marks allocated areas as reserved if necessary. p54_rx_frame_sent frees
  * allocated areas.
  */
-static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
-                              struct p54_control_hdr *data, u32 len)
+static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
+                              struct p54_hdr *data, u32 len)
 {
        struct p54_common *priv = dev->priv;
        struct sk_buff *entry = priv->tx_queue.next;
        struct sk_buff *target_skb = NULL;
+       struct ieee80211_tx_info *info;
+       struct memrecord *range;
        u32 last_addr = priv->rx_start;
        u32 largest_hole = 0;
        u32 target_addr = priv->rx_start;
@@ -695,12 +834,15 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
        unsigned int left;
        len = (len + priv->headroom + priv->tailroom + 3) & ~0x3;
 
+       if (!skb)
+               return -EINVAL;
+
        spin_lock_irqsave(&priv->tx_queue.lock, flags);
        left = skb_queue_len(&priv->tx_queue);
        while (left--) {
                u32 hole_size;
-               struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
-               struct memrecord *range = (void *)info->driver_data;
+               info = IEEE80211_SKB_CB(entry);
+               range = (void *)info->rate_driver_data;
                hole_size = range->start_addr - last_addr;
                if (!target_skb && hole_size >= len) {
                        target_skb = entry->prev;
@@ -715,64 +857,89 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
                target_skb = priv->tx_queue.prev;
                largest_hole = max(largest_hole, priv->rx_end - last_addr - len);
                if (!skb_queue_empty(&priv->tx_queue)) {
-                       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(target_skb);
-                       struct memrecord *range = (void *)info->driver_data;
+                       info = IEEE80211_SKB_CB(target_skb);
+                       range = (void *)info->rate_driver_data;
                        target_addr = range->end_addr;
                }
        } else
                largest_hole = max(largest_hole, priv->rx_end - last_addr);
 
-       if (skb) {
-               struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-               struct memrecord *range = (void *)info->driver_data;
-               range->start_addr = target_addr;
-               range->end_addr = target_addr + len;
-               __skb_queue_after(&priv->tx_queue, target_skb, skb);
-               if (largest_hole < priv->rx_mtu + priv->headroom +
-                                  priv->tailroom +
-                                  sizeof(struct p54_control_hdr))
-                       ieee80211_stop_queues(dev);
+       if (!target_skb) {
+               spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
+               ieee80211_stop_queues(dev);
+               return -ENOMEM;
        }
+
+       info = IEEE80211_SKB_CB(skb);
+       range = (void *)info->rate_driver_data;
+       range->start_addr = target_addr;
+       range->end_addr = target_addr + len;
+       __skb_queue_after(&priv->tx_queue, target_skb, skb);
        spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
 
+       if (largest_hole < priv->headroom + sizeof(struct p54_hdr) +
+                          48 + IEEE80211_MAX_RTS_THRESHOLD + priv->tailroom)
+               ieee80211_stop_queues(dev);
+
        data->req_id = cpu_to_le32(target_addr + priv->headroom);
+       return 0;
+}
+
+static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev,
+               u16 hdr_flags, u16 len, u16 type, gfp_t memflags)
+{
+       struct p54_common *priv = dev->priv;
+       struct p54_hdr *hdr;
+       struct sk_buff *skb;
+
+       skb = __dev_alloc_skb(len + priv->tx_hdr_len, memflags);
+       if (!skb)
+               return NULL;
+       skb_reserve(skb, priv->tx_hdr_len);
+
+       hdr = (struct p54_hdr *) skb_put(skb, sizeof(*hdr));
+       hdr->flags = cpu_to_le16(hdr_flags);
+       hdr->len = cpu_to_le16(len - sizeof(*hdr));
+       hdr->type = cpu_to_le16(type);
+       hdr->tries = hdr->rts_tries = 0;
+
+       if (unlikely(p54_assign_address(dev, skb, hdr, len))) {
+               kfree_skb(skb);
+               return NULL;
+       }
+       return skb;
 }
 
 int p54_read_eeprom(struct ieee80211_hw *dev)
 {
        struct p54_common *priv = dev->priv;
-       struct p54_control_hdr *hdr = NULL;
+       struct p54_hdr *hdr = NULL;
        struct p54_eeprom_lm86 *eeprom_hdr;
+       struct sk_buff *skb;
        size_t eeprom_size = 0x2020, offset = 0, blocksize;
        int ret = -ENOMEM;
        void *eeprom = NULL;
 
-       hdr = (struct p54_control_hdr *)kzalloc(sizeof(*hdr) +
-               sizeof(*eeprom_hdr) + EEPROM_READBACK_LEN, GFP_KERNEL);
-       if (!hdr)
+       skb = p54_alloc_skb(dev, 0x8000, sizeof(*hdr) + sizeof(*eeprom_hdr) +
+                           EEPROM_READBACK_LEN,
+                           P54_CONTROL_TYPE_EEPROM_READBACK, GFP_KERNEL);
+       if (!skb)
                goto free;
-
        priv->eeprom = kzalloc(EEPROM_READBACK_LEN, GFP_KERNEL);
        if (!priv->eeprom)
                goto free;
-
        eeprom = kzalloc(eeprom_size, GFP_KERNEL);
        if (!eeprom)
                goto free;
 
-       hdr->magic1 = cpu_to_le16(0x8000);
-       hdr->type = cpu_to_le16(P54_CONTROL_TYPE_EEPROM_READBACK);
-       hdr->retry1 = hdr->retry2 = 0;
-       eeprom_hdr = (struct p54_eeprom_lm86 *) hdr->data;
+       eeprom_hdr = (struct p54_eeprom_lm86 *) skb_put(skb,
+                    sizeof(*eeprom_hdr) + EEPROM_READBACK_LEN);
 
        while (eeprom_size) {
                blocksize = min(eeprom_size, (size_t)EEPROM_READBACK_LEN);
-               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, le16_to_cpu(hdr->len) +
-                                  sizeof(*hdr));
-               priv->tx(dev, hdr, le16_to_cpu(hdr->len) + sizeof(*hdr), 0);
+               priv->tx(dev, skb, 0);
 
                if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) {
                        printk(KERN_ERR "%s: device does not respond!\n",
@@ -790,165 +957,336 @@ int p54_read_eeprom(struct ieee80211_hw *dev)
 free:
        kfree(priv->eeprom);
        priv->eeprom = NULL;
-       kfree(hdr);
+       p54_free_skb(dev, skb);
        kfree(eeprom);
 
        return ret;
 }
 EXPORT_SYMBOL_GPL(p54_read_eeprom);
 
+static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
+               bool set)
+{
+       struct p54_common *priv = dev->priv;
+       struct sk_buff *skb;
+       struct p54_tim *tim;
+
+       skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
+                     sizeof(struct p54_hdr) + sizeof(*tim),
+                     P54_CONTROL_TYPE_TIM, GFP_KERNEL);
+       if (!skb)
+               return -ENOMEM;
+
+       tim = (struct p54_tim *) skb_put(skb, sizeof(*tim));
+       tim->count = 1;
+       tim->entry[0] = cpu_to_le16(set ? (sta->aid | 0x8000) : sta->aid);
+       priv->tx(dev, skb, 1);
+       return 0;
+}
+
+static int p54_sta_unlock(struct ieee80211_hw *dev, u8 *addr)
+{
+       struct p54_common *priv = dev->priv;
+       struct sk_buff *skb;
+       struct p54_sta_unlock *sta;
+
+       skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
+               sizeof(struct p54_hdr) + sizeof(*sta),
+               P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC);
+       if (!skb)
+               return -ENOMEM;
+
+       sta = (struct p54_sta_unlock *)skb_put(skb, sizeof(*sta));
+       memcpy(sta->addr, addr, ETH_ALEN);
+       priv->tx(dev, skb, 1);
+       return 0;
+}
+
+static int p54_tx_cancel(struct ieee80211_hw *dev, struct sk_buff *entry)
+{
+       struct p54_common *priv = dev->priv;
+       struct sk_buff *skb;
+       struct p54_hdr *hdr;
+       struct p54_txcancel *cancel;
+
+       skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
+               sizeof(struct p54_hdr) + sizeof(*cancel),
+               P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC);
+       if (!skb)
+               return -ENOMEM;
+
+       hdr = (void *)entry->data;
+       cancel = (struct p54_txcancel *)skb_put(skb, sizeof(*cancel));
+       cancel->req_id = hdr->req_id;
+       priv->tx(dev, skb, 1);
+       return 0;
+}
+
+static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb,
+               struct ieee80211_tx_info *info, u8 *queue, size_t *extra_len,
+               u16 *flags, u16 *aid)
+{
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct p54_common *priv = dev->priv;
+       int ret = 0;
+
+       if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
+               if (ieee80211_is_beacon(hdr->frame_control)) {
+                       *aid = 0;
+                       *queue = 0;
+                       *extra_len = IEEE80211_MAX_TIM_LEN;
+                       *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP;
+                       return 0;
+               } else if (ieee80211_is_probe_resp(hdr->frame_control)) {
+                       *aid = 0;
+                       *queue = 2;
+                       *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP |
+                                P54_HDR_FLAG_DATA_OUT_NOCANCEL;
+                       return 0;
+               } else {
+                       *queue = 2;
+                       ret = 0;
+               }
+       } else {
+               *queue += 4;
+               ret = 1;
+       }
+
+       switch (priv->mode) {
+       case NL80211_IFTYPE_STATION:
+               *aid = 1;
+               break;
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_ADHOC:
+               if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
+                       *aid = 0;
+                       *queue = 3;
+                       return 0;
+               }
+               if (info->control.sta)
+                       *aid = info->control.sta->aid;
+               else
+                       *flags = P54_HDR_FLAG_DATA_OUT_NOCANCEL;
+       }
+       return ret;
+}
+
 static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_tx_queue_stats *current_queue;
+       struct ieee80211_tx_queue_stats *current_queue = NULL;
        struct p54_common *priv = dev->priv;
-       struct p54_control_hdr *hdr;
-       struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
-       struct p54_tx_control_allocdata *txhdr;
-       size_t padding, len;
-       u8 rate;
+       struct p54_hdr *hdr;
+       struct p54_tx_data *txhdr;
+       size_t padding, len, tim_len = 0;
+       int i, j, ridx;
+       u16 hdr_flags = 0, aid = 0;
+       u8 rate, queue;
        u8 cts_rate = 0x20;
-
-       current_queue = &priv->tx_stats[skb_get_queue_mapping(skb) + 4];
-       if (unlikely(current_queue->len > current_queue->limit))
-               return NETDEV_TX_BUSY;
-       current_queue->len++;
-       current_queue->count++;
-       if (current_queue->len == current_queue->limit)
-               ieee80211_stop_queue(dev, skb_get_queue_mapping(skb));
+       u8 rc_flags;
+       u8 calculated_tries[4];
+       u8 nrates = 0, nremaining = 8;
+
+       queue = skb_get_queue_mapping(skb);
+
+       if (p54_tx_fill(dev, skb, info, &queue, &tim_len, &hdr_flags, &aid)) {
+               current_queue = &priv->tx_stats[queue];
+               if (unlikely(current_queue->len > current_queue->limit))
+                       return NETDEV_TX_BUSY;
+               current_queue->len++;
+               current_queue->count++;
+               if (current_queue->len == current_queue->limit)
+                       ieee80211_stop_queue(dev, skb_get_queue_mapping(skb));
+       }
 
        padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3;
        len = skb->len;
 
-       txhdr = (struct p54_tx_control_allocdata *)
-                       skb_push(skb, sizeof(*txhdr) + padding);
-       hdr = (struct p54_control_hdr *) skb_push(skb, sizeof(*hdr));
+       if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) {
+               if (info->control.sta)
+                       if (p54_sta_unlock(dev, info->control.sta->addr)) {
+                               if (current_queue) {
+                                       current_queue->len--;
+                                       current_queue->count--;
+                               }
+                               return NETDEV_TX_BUSY;
+                       }
+       }
+
+       txhdr = (struct p54_tx_data *) skb_push(skb, sizeof(*txhdr) + padding);
+       hdr = (struct p54_hdr *) skb_push(skb, sizeof(*hdr));
 
        if (padding)
-               hdr->magic1 = cpu_to_le16(0x4010);
-       else
-               hdr->magic1 = cpu_to_le16(0x0010);
+               hdr_flags |= P54_HDR_FLAG_DATA_ALIGN;
        hdr->len = cpu_to_le16(len);
-       hdr->type = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 0 : cpu_to_le16(1);
-       hdr->retry1 = hdr->retry2 = info->control.retry_limit;
-
-       /* TODO: add support for alternate retry TX rates */
-       rate = ieee80211_get_tx_rate(dev, info)->hw_value;
-       if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE) {
-               rate |= 0x10;
-               cts_rate |= 0x10;
+       hdr->type = cpu_to_le16(aid);
+       hdr->rts_tries = info->control.rates[0].count;
+
+       /*
+        * we register the rates in perfect order, and
+        * RTS/CTS won't happen on 5 GHz
+        */
+       cts_rate = info->control.rts_cts_rate_idx;
+
+       memset(&txhdr->rateset, 0, sizeof(txhdr->rateset));
+
+       /* see how many rates got used */
+       for (i = 0; i < 4; i++) {
+               if (info->control.rates[i].idx < 0)
+                       break;
+               nrates++;
+       }
+
+       /* limit tries to 8/nrates per rate */
+       for (i = 0; i < nrates; i++) {
+               /*
+                * The magic expression here is equivalent to 8/nrates for
+                * all values that matter, but avoids division and jumps.
+                * Note that nrates can only take the values 1 through 4.
+                */
+               calculated_tries[i] = min_t(int, ((15 >> nrates) | 1) + 1,
+                                                info->control.rates[i].count);
+               nremaining -= calculated_tries[i];
        }
-       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
-               rate |= 0x40;
-               cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value;
-       } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
-               rate |= 0x20;
-               cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value;
+
+       /* if there are tries left, distribute from back to front */
+       for (i = nrates - 1; nremaining > 0 && i >= 0; i--) {
+               int tmp = info->control.rates[i].count - calculated_tries[i];
+
+               if (tmp <= 0)
+                       continue;
+               /* RC requested more tries at this rate */
+
+               tmp = min_t(int, tmp, nremaining);
+               calculated_tries[i] += tmp;
+               nremaining -= tmp;
        }
-       memset(txhdr->rateset, rate, 8);
+
+       ridx = 0;
+       for (i = 0; i < nrates && ridx < 8; i++) {
+               /* we register the rates in perfect order */
+               rate = info->control.rates[i].idx;
+               if (info->band == IEEE80211_BAND_5GHZ)
+                       rate += 4;
+
+               /* store the count we actually calculated for TX status */
+               info->control.rates[i].count = calculated_tries[i];
+
+               rc_flags = info->control.rates[i].flags;
+               if (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) {
+                       rate |= 0x10;
+                       cts_rate |= 0x10;
+               }
+               if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS)
+                       rate |= 0x40;
+               else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
+                       rate |= 0x20;
+               for (j = 0; j < calculated_tries[i] && ridx < 8; j++) {
+                       txhdr->rateset[ridx] = rate;
+                       ridx++;
+               }
+       }
+
+       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
+               hdr_flags |= P54_HDR_FLAG_DATA_OUT_SEQNR;
+
+       /* TODO: enable bursting */
+       hdr->flags = cpu_to_le16(hdr_flags);
+       hdr->tries = ridx;
+       txhdr->crypt_offset = 0;
+       txhdr->rts_rate_idx = 0;
        txhdr->key_type = 0;
        txhdr->key_len = 0;
-       txhdr->hw_queue = skb_get_queue_mapping(skb) + 4;
+       txhdr->hw_queue = queue;
+       txhdr->backlog = 32;
+       memset(txhdr->durations, 0, sizeof(txhdr->durations));
        txhdr->tx_antenna = (info->antenna_sel_tx == 0) ?
                2 : info->antenna_sel_tx - 1;
        txhdr->output_power = priv->output_power;
-       txhdr->cts_rate = (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
-                         0 : cts_rate;
+       txhdr->cts_rate = cts_rate;
        if (padding)
                txhdr->align[0] = padding;
 
-       /* FIXME: The sequence that follows is needed for this driver to
-        * work with mac80211 since "mac80211: fix TX sequence numbers".
-        * As with the temporary code in rt2x00, changes will be needed
-        * to get proper sequence numbers on beacons. In addition, this
-        * patch places the sequence number in the hardware state, which
-        * limits us to a single virtual state.
-        */
-       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-               if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
-                       priv->seqno += 0x10;
-               ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-               ieee80211hdr->seq_ctrl |= cpu_to_le16(priv->seqno);
-       }
        /* modifies skb->cb and with it info, so must be last! */
-       p54_assign_address(dev, skb, hdr, skb->len);
-
-       priv->tx(dev, hdr, skb->len, 0);
+       if (unlikely(p54_assign_address(dev, skb, hdr, skb->len + tim_len))) {
+               skb_pull(skb, sizeof(*hdr) + sizeof(*txhdr) + padding);
+               if (current_queue) {
+                       current_queue->len--;
+                       current_queue->count--;
+               }
+               return NETDEV_TX_BUSY;
+       }
+       priv->tx(dev, skb, 0);
        return 0;
 }
 
-static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
-                         const u8 *bssid)
+static int p54_setup_mac(struct ieee80211_hw *dev, u16 mode, const u8 *bssid)
 {
        struct p54_common *priv = dev->priv;
-       struct p54_control_hdr *hdr;
-       struct p54_tx_control_filter *filter;
-       size_t data_len;
+       struct sk_buff *skb;
+       struct p54_setup_mac *setup;
 
-       hdr = kzalloc(sizeof(*hdr) + sizeof(*filter) +
-                     priv->tx_hdr_len, GFP_ATOMIC);
-       if (!hdr)
+       skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup) +
+                           sizeof(struct p54_hdr), P54_CONTROL_TYPE_SETUP,
+                           GFP_ATOMIC);
+       if (!skb)
                return -ENOMEM;
 
-       hdr = (void *)hdr + priv->tx_hdr_len;
-
-       filter = (struct p54_tx_control_filter *) hdr->data;
-       hdr->magic1 = cpu_to_le16(0x8001);
-       hdr->type = cpu_to_le16(P54_CONTROL_TYPE_FILTER_SET);
-
-       priv->filter_type = filter->filter_type = cpu_to_le16(filter_type);
-       memcpy(filter->mac_addr, priv->mac_addr, ETH_ALEN);
+       setup = (struct p54_setup_mac *) skb_put(skb, sizeof(*setup));
+       priv->mac_mode = mode;
+       setup->mac_mode = cpu_to_le16(mode);
+       memcpy(setup->mac_addr, priv->mac_addr, ETH_ALEN);
        if (!bssid)
-               memset(filter->bssid, ~0, ETH_ALEN);
+               memset(setup->bssid, ~0, ETH_ALEN);
        else
-               memcpy(filter->bssid, bssid, ETH_ALEN);
-
-       filter->rx_antenna = priv->rx_antenna;
-
+               memcpy(setup->bssid, bssid, ETH_ALEN);
+       setup->rx_antenna = priv->rx_antenna;
+       setup->rx_align = 0;
        if (priv->fw_var < 0x500) {
-               data_len = P54_TX_CONTROL_FILTER_V1_LEN;
-               filter->v1.basic_rate_mask = cpu_to_le32(0x15F);
-               filter->v1.rx_addr = cpu_to_le32(priv->rx_end);
-               filter->v1.max_rx = cpu_to_le16(priv->rx_mtu);
-               filter->v1.rxhw = cpu_to_le16(priv->rxhw);
-               filter->v1.wakeup_timer = cpu_to_le16(500);
+               setup->v1.basic_rate_mask = cpu_to_le32(0x15f);
+               memset(setup->v1.rts_rates, 0, 8);
+               setup->v1.rx_addr = cpu_to_le32(priv->rx_end);
+               setup->v1.max_rx = cpu_to_le16(priv->rx_mtu);
+               setup->v1.rxhw = cpu_to_le16(priv->rxhw);
+               setup->v1.wakeup_timer = cpu_to_le16(500);
+               setup->v1.unalloc0 = cpu_to_le16(0);
        } else {
-               data_len = P54_TX_CONTROL_FILTER_V2_LEN;
-               filter->v2.rx_addr = cpu_to_le32(priv->rx_end);
-               filter->v2.max_rx = cpu_to_le16(priv->rx_mtu);
-               filter->v2.rxhw = cpu_to_le16(priv->rxhw);
-               filter->v2.timer = cpu_to_le16(1000);
+               setup->v2.rx_addr = cpu_to_le32(priv->rx_end);
+               setup->v2.max_rx = cpu_to_le16(priv->rx_mtu);
+               setup->v2.rxhw = cpu_to_le16(priv->rxhw);
+               setup->v2.timer = cpu_to_le16(1000);
+               setup->v2.truncate = cpu_to_le16(48896);
+               setup->v2.basic_rate_mask = cpu_to_le32(0x15f);
+               setup->v2.sbss_offset = 0;
+               setup->v2.mcast_window = 0;
+               setup->v2.rx_rssi_threshold = 0;
+               setup->v2.rx_ed_threshold = 0;
+               setup->v2.ref_clock = cpu_to_le32(644245094);
+               setup->v2.lpf_bandwidth = cpu_to_le16(65535);
+               setup->v2.osc_start_delay = cpu_to_le16(65535);
        }
-
-       hdr->len = cpu_to_le16(data_len);
-       p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + data_len);
-       priv->tx(dev, hdr, sizeof(*hdr) + data_len, 1);
+       priv->tx(dev, skb, 1);
        return 0;
 }
 
-static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
+static int p54_set_freq(struct ieee80211_hw *dev, u16 frequency)
 {
        struct p54_common *priv = dev->priv;
-       struct p54_control_hdr *hdr;
-       struct p54_tx_control_channel *chan;
+       struct sk_buff *skb;
+       struct p54_scan *chan;
        unsigned int i;
-       size_t data_len;
        void *entry;
+       __le16 freq = cpu_to_le16(frequency);
 
-       hdr = kzalloc(sizeof(*hdr) + sizeof(*chan) +
-                     priv->tx_hdr_len, GFP_KERNEL);
-       if (!hdr)
+       skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*chan) +
+                           sizeof(struct p54_hdr), P54_CONTROL_TYPE_SCAN,
+                           GFP_ATOMIC);
+       if (!skb)
                return -ENOMEM;
 
-       hdr = (void *)hdr + priv->tx_hdr_len;
-
-       chan = (struct p54_tx_control_channel *) hdr->data;
-
-       hdr->magic1 = cpu_to_le16(0x8001);
-
-       hdr->type = cpu_to_le16(P54_CONTROL_TYPE_CHANNEL_CHANGE);
-
-       chan->flags = cpu_to_le16(0x1);
+       chan = (struct p54_scan *) skb_put(skb, sizeof(*chan));
+       memset(chan->padding1, 0, sizeof(chan->padding1));
+       chan->mode = cpu_to_le16(P54_SCAN_EXIT);
        chan->dwell = cpu_to_le16(0x0);
 
        for (i = 0; i < priv->iq_autocal_len; i++) {
@@ -990,61 +1328,50 @@ static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
                }
 
                entry += sizeof(__le16);
-               chan->pa_points_per_curve =
-                       min(priv->curve_data->points_per_channel, (u8) 8);
-
-               memcpy(chan->curve_data, entry, sizeof(*chan->curve_data) *
-                      chan->pa_points_per_curve);
+               chan->pa_points_per_curve = 8;
+               memset(chan->curve_data, 0, sizeof(*chan->curve_data));
+               memcpy(chan->curve_data, entry,
+                      sizeof(struct p54_pa_curve_data_sample) *
+                      min((u8)8, priv->curve_data->points_per_channel));
                break;
        }
 
        if (priv->fw_var < 0x500) {
-               data_len = P54_TX_CONTROL_CHANNEL_V1_LEN;
                chan->v1.rssical_mul = cpu_to_le16(130);
                chan->v1.rssical_add = cpu_to_le16(0xfe70);
        } else {
-               data_len = P54_TX_CONTROL_CHANNEL_V2_LEN;
                chan->v2.rssical_mul = cpu_to_le16(130);
                chan->v2.rssical_add = cpu_to_le16(0xfe70);
                chan->v2.basic_rate_mask = cpu_to_le32(0x15f);
+               memset(chan->v2.rts_rates, 0, 8);
        }
-
-       hdr->len = cpu_to_le16(data_len);
-       p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + data_len);
-       priv->tx(dev, hdr, sizeof(*hdr) + data_len, 1);
+       priv->tx(dev, skb, 1);
        return 0;
 
  err:
        printk(KERN_ERR "%s: frequency change failed\n", wiphy_name(dev->wiphy));
-       kfree(hdr);
+       kfree_skb(skb);
        return -EINVAL;
 }
 
 static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act)
 {
        struct p54_common *priv = dev->priv;
-       struct p54_control_hdr *hdr;
-       struct p54_tx_control_led *led;
+       struct sk_buff *skb;
+       struct p54_led *led;
 
-       hdr = kzalloc(sizeof(*hdr) + sizeof(*led) +
-                     priv->tx_hdr_len, GFP_KERNEL);
-       if (!hdr)
+       skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led) +
+                       sizeof(struct p54_hdr), P54_CONTROL_TYPE_LED,
+                       GFP_ATOMIC);
+       if (!skb)
                return -ENOMEM;
 
-       hdr = (void *)hdr + priv->tx_hdr_len;
-       hdr->magic1 = cpu_to_le16(0x8001);
-       hdr->len = cpu_to_le16(sizeof(*led));
-       hdr->type = cpu_to_le16(P54_CONTROL_TYPE_LED);
-       p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*led));
-
-       led = (struct p54_tx_control_led *) hdr->data;
+       led = (struct p54_led *)skb_put(skb, sizeof(*led));
        led->mode = cpu_to_le16(mode);
        led->led_permanent = cpu_to_le16(link);
        led->led_temporary = cpu_to_le16(act);
        led->duration = cpu_to_le16(1000);
-
-       priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*led), 1);
-
+       priv->tx(dev, skb, 1);
        return 0;
 }
 
@@ -1056,88 +1383,152 @@ do {                                                           \
        queue.txop = cpu_to_le16(_txop);                        \
 } while(0)
 
-static void p54_init_vdcf(struct ieee80211_hw *dev)
+static int p54_set_edcf(struct ieee80211_hw *dev)
 {
        struct p54_common *priv = dev->priv;
-       struct p54_control_hdr *hdr;
-       struct p54_tx_control_vdcf *vdcf;
-
-       /* all USB V1 adapters need a extra headroom */
-       hdr = (void *)priv->cached_vdcf + priv->tx_hdr_len;
-       hdr->magic1 = cpu_to_le16(0x8001);
-       hdr->len = cpu_to_le16(sizeof(*vdcf));
-       hdr->type = cpu_to_le16(P54_CONTROL_TYPE_DCFINIT);
-       hdr->req_id = cpu_to_le32(priv->rx_start);
-
-       vdcf = (struct p54_tx_control_vdcf *) hdr->data;
-
-       P54_SET_QUEUE(vdcf->queue[0], 0x0002, 0x0003, 0x0007, 47);
-       P54_SET_QUEUE(vdcf->queue[1], 0x0002, 0x0007, 0x000f, 94);
-       P54_SET_QUEUE(vdcf->queue[2], 0x0003, 0x000f, 0x03ff, 0);
-       P54_SET_QUEUE(vdcf->queue[3], 0x0007, 0x000f, 0x03ff, 0);
+       struct sk_buff *skb;
+       struct p54_edcf *edcf;
+
+       skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf) +
+                       sizeof(struct p54_hdr), P54_CONTROL_TYPE_DCFINIT,
+                       GFP_ATOMIC);
+       if (!skb)
+               return -ENOMEM;
+
+       edcf = (struct p54_edcf *)skb_put(skb, sizeof(*edcf));
+       if (priv->use_short_slot) {
+               edcf->slottime = 9;
+               edcf->sifs = 0x10;
+               edcf->eofpad = 0x00;
+       } else {
+               edcf->slottime = 20;
+               edcf->sifs = 0x0a;
+               edcf->eofpad = 0x06;
+       }
+       /* (see prism54/isl_oid.h for further details) */
+       edcf->frameburst = cpu_to_le16(0);
+       edcf->round_trip_delay = cpu_to_le16(0);
+       edcf->flags = 0;
+       memset(edcf->mapping, 0, sizeof(edcf->mapping));
+       memcpy(edcf->queue, priv->qos_params, sizeof(edcf->queue));
+       priv->tx(dev, skb, 1);
+       return 0;
 }
 
-static void p54_set_vdcf(struct ieee80211_hw *dev)
+static int p54_init_stats(struct ieee80211_hw *dev)
 {
        struct p54_common *priv = dev->priv;
-       struct p54_control_hdr *hdr;
-       struct p54_tx_control_vdcf *vdcf;
 
-       hdr = (void *)priv->cached_vdcf + priv->tx_hdr_len;
+       priv->cached_stats = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL,
+                       sizeof(struct p54_hdr) + sizeof(struct p54_statistics),
+                       P54_CONTROL_TYPE_STAT_READBACK, GFP_KERNEL);
+       if (!priv->cached_stats)
+                       return -ENOMEM;
+
+       mod_timer(&priv->stats_timer, jiffies + HZ);
+       return 0;
+}
 
-       p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*vdcf));
+static int p54_beacon_tim(struct sk_buff *skb)
+{
+       /*
+        * the good excuse for this mess is ... the firmware.
+        * The dummy TIM MUST be at the end of the beacon frame,
+        * because it'll be overwritten!
+        */
 
-       vdcf = (struct p54_tx_control_vdcf *) hdr->data;
+       struct ieee80211_mgmt *mgmt = (void *)skb->data;
+       u8 *pos, *end;
 
-       if (dev->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
-               vdcf->slottime = 9;
-               vdcf->magic1 = 0x10;
-               vdcf->magic2 = 0x00;
-       } else {
-               vdcf->slottime = 20;
-               vdcf->magic1 = 0x0a;
-               vdcf->magic2 = 0x06;
+       if (skb->len <= sizeof(mgmt)) {
+               printk(KERN_ERR "p54: beacon is too short!\n");
+               return -EINVAL;
        }
 
-       /* (see prism54/isl_oid.h for further details) */
-       vdcf->frameburst = cpu_to_le16(0);
+       pos = (u8 *)mgmt->u.beacon.variable;
+       end = skb->data + skb->len;
+       while (pos < end) {
+               if (pos + 2 + pos[1] > end) {
+                       printk(KERN_ERR "p54: parsing beacon failed\n");
+                       return -EINVAL;
+               }
+
+               if (pos[0] == WLAN_EID_TIM) {
+                       u8 dtim_len = pos[1];
+                       u8 dtim_period = pos[3];
+                       u8 *next = pos + 2 + dtim_len;
+
+                       if (dtim_len < 3) {
+                               printk(KERN_ERR "p54: invalid dtim len!\n");
+                               return -EINVAL;
+                       }
+                       memmove(pos, next, end - next);
 
-       priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*vdcf), 0);
+                       if (dtim_len > 3)
+                               skb_trim(skb, skb->len - (dtim_len - 3));
+
+                       pos = end - (dtim_len + 2);
+
+                       /* add the dummy at the end */
+                       pos[0] = WLAN_EID_TIM;
+                       pos[1] = 3;
+                       pos[2] = 0;
+                       pos[3] = dtim_period;
+                       pos[4] = 0;
+                       return 0;
+               }
+               pos += 2 + pos[1];
+       }
+       return 0;
 }
 
-static int p54_start(struct ieee80211_hw *dev)
+static int p54_beacon_update(struct ieee80211_hw *dev,
+                       struct ieee80211_vif *vif)
 {
        struct p54_common *priv = dev->priv;
-       int err;
-
-       if (!priv->cached_vdcf) {
-               priv->cached_vdcf = kzalloc(sizeof(struct p54_tx_control_vdcf)+
-                       priv->tx_hdr_len + sizeof(struct p54_control_hdr),
-                       GFP_KERNEL);
+       struct sk_buff *beacon;
+       int ret;
 
-               if (!priv->cached_vdcf)
-                       return -ENOMEM;
+       if (priv->cached_beacon) {
+               p54_tx_cancel(dev, priv->cached_beacon);
+               /* wait for the last beacon the be freed */
+               msleep(10);
        }
 
-       if (!priv->cached_stats) {
-               priv->cached_stats = kzalloc(sizeof(struct p54_statistics) +
-                       priv->tx_hdr_len + sizeof(struct p54_control_hdr),
-                       GFP_KERNEL);
+       beacon = ieee80211_beacon_get(dev, vif);
+       if (!beacon)
+               return -ENOMEM;
+       ret = p54_beacon_tim(beacon);
+       if (ret)
+               return ret;
+       ret = p54_tx(dev, beacon);
+       if (ret)
+               return ret;
+       priv->cached_beacon = beacon;
+       priv->tsf_high32 = 0;
+       priv->tsf_low32 = 0;
 
-               if (!priv->cached_stats) {
-                       kfree(priv->cached_vdcf);
-                       priv->cached_vdcf = NULL;
-                       return -ENOMEM;
-               }
-       }
+       return 0;
+}
 
+static int p54_start(struct ieee80211_hw *dev)
+{
+       struct p54_common *priv = dev->priv;
+       int err;
+
+       mutex_lock(&priv->conf_mutex);
        err = priv->open(dev);
        if (!err)
                priv->mode = NL80211_IFTYPE_MONITOR;
+       P54_SET_QUEUE(priv->qos_params[0], 0x0002, 0x0003, 0x0007, 47);
+       P54_SET_QUEUE(priv->qos_params[1], 0x0002, 0x0007, 0x000f, 94);
+       P54_SET_QUEUE(priv->qos_params[2], 0x0003, 0x000f, 0x03ff, 0);
+       P54_SET_QUEUE(priv->qos_params[3], 0x0007, 0x000f, 0x03ff, 0);
+       err = p54_set_edcf(dev);
+       if (!err)
+               err = p54_init_stats(dev);
 
-       p54_init_vdcf(dev);
-
-       mod_timer(&priv->stats_timer, jiffies + HZ);
+       mutex_unlock(&priv->conf_mutex);
        return err;
 }
 
@@ -1146,12 +1537,22 @@ static void p54_stop(struct ieee80211_hw *dev)
        struct p54_common *priv = dev->priv;
        struct sk_buff *skb;
 
+       mutex_lock(&priv->conf_mutex);
        del_timer(&priv->stats_timer);
+       p54_free_skb(dev, priv->cached_stats);
+       priv->cached_stats = NULL;
+       if (priv->cached_beacon)
+               p54_tx_cancel(dev, priv->cached_beacon);
+
        while ((skb = skb_dequeue(&priv->tx_queue)))
                kfree_skb(skb);
+
+       kfree(priv->cached_beacon);
+       priv->cached_beacon = NULL;
        priv->stop(dev);
        priv->tsf_high32 = priv->tsf_low32 = 0;
        priv->mode = NL80211_IFTYPE_UNSPECIFIED;
+       mutex_unlock(&priv->conf_mutex);
 }
 
 static int p54_add_interface(struct ieee80211_hw *dev,
@@ -1159,24 +1560,36 @@ static int p54_add_interface(struct ieee80211_hw *dev,
 {
        struct p54_common *priv = dev->priv;
 
-       if (priv->mode != NL80211_IFTYPE_MONITOR)
+       mutex_lock(&priv->conf_mutex);
+       if (priv->mode != NL80211_IFTYPE_MONITOR) {
+               mutex_unlock(&priv->conf_mutex);
                return -EOPNOTSUPP;
+       }
 
        switch (conf->type) {
        case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_AP:
                priv->mode = conf->type;
                break;
        default:
+               mutex_unlock(&priv->conf_mutex);
                return -EOPNOTSUPP;
        }
 
        memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
 
-       p54_set_filter(dev, 0, NULL);
+       p54_setup_mac(dev, P54_FILTER_TYPE_NONE, NULL);
 
        switch (conf->type) {
        case NL80211_IFTYPE_STATION:
-               p54_set_filter(dev, 1, NULL);
+               p54_setup_mac(dev, P54_FILTER_TYPE_STATION, NULL);
+               break;
+       case NL80211_IFTYPE_AP:
+               p54_setup_mac(dev, P54_FILTER_TYPE_AP, priv->mac_addr);
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               p54_setup_mac(dev, P54_FILTER_TYPE_IBSS, NULL);
                break;
        default:
                BUG();  /* impossible */
@@ -1185,6 +1598,7 @@ static int p54_add_interface(struct ieee80211_hw *dev,
 
        p54_set_leds(dev, 1, 0, 0);
 
+       mutex_unlock(&priv->conf_mutex);
        return 0;
 }
 
@@ -1192,22 +1606,28 @@ static void p54_remove_interface(struct ieee80211_hw *dev,
                                 struct ieee80211_if_init_conf *conf)
 {
        struct p54_common *priv = dev->priv;
+
+       mutex_lock(&priv->conf_mutex);
+       if (priv->cached_beacon)
+               p54_tx_cancel(dev, priv->cached_beacon);
+       p54_setup_mac(dev, P54_FILTER_TYPE_NONE, NULL);
        priv->mode = NL80211_IFTYPE_MONITOR;
        memset(priv->mac_addr, 0, ETH_ALEN);
-       p54_set_filter(dev, 0, NULL);
+       mutex_unlock(&priv->conf_mutex);
 }
 
-static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
+static int p54_config(struct ieee80211_hw *dev, u32 changed)
 {
        int ret;
        struct p54_common *priv = dev->priv;
+       struct ieee80211_conf *conf = &dev->conf;
 
        mutex_lock(&priv->conf_mutex);
-       priv->rx_antenna = (conf->antenna_sel_rx == 0) ?
-               2 : conf->antenna_sel_tx - 1;
+       priv->rx_antenna = 2; /* automatic */
        priv->output_power = conf->power_level << 2;
-       ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq));
-       p54_set_vdcf(dev);
+       ret = p54_set_freq(dev, conf->channel->center_freq);
+       if (!ret)
+               ret = p54_set_edcf(dev);
        mutex_unlock(&priv->conf_mutex);
        return ret;
 }
@@ -1217,13 +1637,41 @@ static int p54_config_interface(struct ieee80211_hw *dev,
                                struct ieee80211_if_conf *conf)
 {
        struct p54_common *priv = dev->priv;
+       int ret = 0;
 
        mutex_lock(&priv->conf_mutex);
-       p54_set_filter(dev, 0, conf->bssid);
-       p54_set_leds(dev, 1, !is_multicast_ether_addr(conf->bssid), 0);
-       memcpy(priv->bssid, conf->bssid, ETH_ALEN);
+       switch (priv->mode) {
+       case NL80211_IFTYPE_STATION:
+               ret = p54_setup_mac(dev, P54_FILTER_TYPE_STATION, conf->bssid);
+               if (ret)
+                       goto out;
+               ret = p54_set_leds(dev, 1,
+                                  !is_multicast_ether_addr(conf->bssid), 0);
+               if (ret)
+                       goto out;
+               memcpy(priv->bssid, conf->bssid, ETH_ALEN);
+               break;
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_ADHOC:
+               memcpy(priv->bssid, conf->bssid, ETH_ALEN);
+               ret = p54_set_freq(dev, dev->conf.channel->center_freq);
+               if (ret)
+                       goto out;
+               ret = p54_setup_mac(dev, priv->mac_mode, priv->bssid);
+               if (ret)
+                       goto out;
+               if (conf->changed & IEEE80211_IFCC_BEACON) {
+                       ret = p54_beacon_update(dev, vif);
+                       if (ret)
+                               goto out;
+                       ret = p54_set_edcf(dev);
+                       if (ret)
+                               goto out;
+               }
+       }
+out:
        mutex_unlock(&priv->conf_mutex);
-       return 0;
+       return ret;
 }
 
 static void p54_configure_filter(struct ieee80211_hw *dev,
@@ -1241,20 +1689,16 @@ 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, le16_to_cpu(priv->filter_type),
-                                NULL);
+                       p54_setup_mac(dev, priv->mac_mode, NULL);
                else
-                       p54_set_filter(dev, le16_to_cpu(priv->filter_type),
-                                priv->bssid);
+                       p54_setup_mac(dev, priv->mac_mode, priv->bssid);
        }
 
        if (changed_flags & FIF_PROMISC_IN_BSS) {
                if (*total_flags & FIF_PROMISC_IN_BSS)
-                       p54_set_filter(dev, le16_to_cpu(priv->filter_type) |
-                               0x8, NULL);
+                       p54_setup_mac(dev, priv->mac_mode | 0x8, NULL);
                else
-                       p54_set_filter(dev, le16_to_cpu(priv->filter_type) &
-                               ~0x8, priv->bssid);
+                       p54_setup_mac(dev, priv->mac_mode & ~0x8, priv->bssid);
        }
 }
 
@@ -1262,46 +1706,39 @@ static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue,
                       const struct ieee80211_tx_queue_params *params)
 {
        struct p54_common *priv = dev->priv;
-       struct p54_tx_control_vdcf *vdcf;
-
-       vdcf = (struct p54_tx_control_vdcf *)(((struct p54_control_hdr *)
-               ((void *)priv->cached_vdcf + priv->tx_hdr_len))->data);
+       int ret;
 
+       mutex_lock(&priv->conf_mutex);
        if ((params) && !(queue > 4)) {
-               P54_SET_QUEUE(vdcf->queue[queue], params->aifs,
+               P54_SET_QUEUE(priv->qos_params[queue], params->aifs,
                        params->cw_min, params->cw_max, params->txop);
        } else
-               return -EINVAL;
-
-       p54_set_vdcf(dev);
-
-       return 0;
+               ret = -EINVAL;
+       if (!ret)
+               ret = p54_set_edcf(dev);
+       mutex_unlock(&priv->conf_mutex);
+       return ret;
 }
 
 static int p54_init_xbow_synth(struct ieee80211_hw *dev)
 {
        struct p54_common *priv = dev->priv;
-       struct p54_control_hdr *hdr;
-       struct p54_tx_control_xbow_synth *xbow;
+       struct sk_buff *skb;
+       struct p54_xbow_synth *xbow;
 
-       hdr = kzalloc(sizeof(*hdr) + sizeof(*xbow) +
-                     priv->tx_hdr_len, GFP_KERNEL);
-       if (!hdr)
+       skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow) +
+                           sizeof(struct p54_hdr),
+                           P54_CONTROL_TYPE_XBOW_SYNTH_CFG,
+                           GFP_KERNEL);
+       if (!skb)
                return -ENOMEM;
 
-       hdr = (void *)hdr + priv->tx_hdr_len;
-       hdr->magic1 = cpu_to_le16(0x8001);
-       hdr->len = cpu_to_le16(sizeof(*xbow));
-       hdr->type = cpu_to_le16(P54_CONTROL_TYPE_XBOW_SYNTH_CFG);
-       p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*xbow));
-
-       xbow = (struct p54_tx_control_xbow_synth *) hdr->data;
+       xbow = (struct p54_xbow_synth *)skb_put(skb, sizeof(*xbow));
        xbow->magic1 = cpu_to_le16(0x1);
        xbow->magic2 = cpu_to_le16(0x2);
        xbow->freq = cpu_to_le16(5390);
-
-       priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*xbow), 1);
-
+       memset(xbow->padding, 0, sizeof(xbow->padding));
+       priv->tx(dev, skb, 1);
        return 0;
 }
 
@@ -1309,18 +1746,10 @@ static void p54_statistics_timer(unsigned long data)
 {
        struct ieee80211_hw *dev = (struct ieee80211_hw *) data;
        struct p54_common *priv = dev->priv;
-       struct p54_control_hdr *hdr;
-       struct p54_statistics *stats;
 
        BUG_ON(!priv->cached_stats);
 
-       hdr = (void *)priv->cached_stats + priv->tx_hdr_len;
-       hdr->magic1 = cpu_to_le16(0x8000);
-       hdr->len = cpu_to_le16(sizeof(*stats));
-       hdr->type = cpu_to_le16(P54_CONTROL_TYPE_STAT_READBACK);
-       p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*stats));
-
-       priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*stats), 0);
+       priv->tx(dev, priv->cached_stats, 0);
 }
 
 static int p54_get_stats(struct ieee80211_hw *dev,
@@ -1352,14 +1781,29 @@ static int p54_get_tx_stats(struct ieee80211_hw *dev,
        return 0;
 }
 
+static void p54_bss_info_changed(struct ieee80211_hw *dev,
+                                struct ieee80211_vif *vif,
+                                struct ieee80211_bss_conf *info,
+                                u32 changed)
+{
+       struct p54_common *priv = dev->priv;
+
+       if (changed & BSS_CHANGED_ERP_SLOT) {
+               priv->use_short_slot = info->use_short_slot;
+               p54_set_edcf(dev);
+       }
+}
+
 static const struct ieee80211_ops p54_ops = {
        .tx                     = p54_tx,
        .start                  = p54_start,
        .stop                   = p54_stop,
        .add_interface          = p54_add_interface,
        .remove_interface       = p54_remove_interface,
+       .set_tim                = p54_set_tim,
        .config                 = p54_config,
        .config_interface       = p54_config_interface,
+       .bss_info_changed       = p54_bss_info_changed,
        .configure_filter       = p54_configure_filter,
        .conf_tx                = p54_conf_tx,
        .get_stats              = p54_get_stats,
@@ -1378,24 +1822,34 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
        priv = dev->priv;
        priv->mode = NL80211_IFTYPE_UNSPECIFIED;
        skb_queue_head_init(&priv->tx_queue);
-       dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */
-                    IEEE80211_HW_RX_INCLUDES_FCS |
+       dev->flags = IEEE80211_HW_RX_INCLUDES_FCS |
                     IEEE80211_HW_SIGNAL_DBM |
                     IEEE80211_HW_NOISE_DBM;
 
-       dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+       dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION |
+                                         NL80211_IFTYPE_ADHOC |
+                                         NL80211_IFTYPE_AP);
 
        dev->channel_change_time = 1000;        /* TODO: find actual value */
-
-       priv->tx_stats[0].limit = 1;
-       priv->tx_stats[1].limit = 1;
-       priv->tx_stats[2].limit = 1;
-       priv->tx_stats[3].limit = 1;
-       priv->tx_stats[4].limit = 5;
+       priv->tx_stats[0].limit = 1;            /* Beacon queue */
+       priv->tx_stats[1].limit = 1;            /* Probe queue for HW scan */
+       priv->tx_stats[2].limit = 3;            /* queue for MLMEs */
+       priv->tx_stats[3].limit = 3;            /* Broadcast / MC queue */
+       priv->tx_stats[4].limit = 5;            /* Data */
        dev->queues = 1;
        priv->noise = -94;
-       dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 +
-                                sizeof(struct p54_tx_control_allocdata);
+       /*
+        * We support at most 8 tries no matter which rate they're at,
+        * we cannot support max_rates * max_rate_tries as we set it
+        * here, but setting it correctly to 4/2 or so would limit us
+        * artificially if the RC algorithm wants just two rates, so
+        * let's say 4/7, we'll redistribute it at TX time, see the
+        * comments there.
+        */
+       dev->max_rates = 4;
+       dev->max_rate_tries = 7;
+       dev->extra_tx_headroom = sizeof(struct p54_hdr) + 4 +
+                                sizeof(struct p54_tx_data);
 
        mutex_init(&priv->conf_mutex);
        init_completion(&priv->eeprom_comp);
@@ -1410,11 +1864,11 @@ EXPORT_SYMBOL_GPL(p54_init_common);
 void p54_free_common(struct ieee80211_hw *dev)
 {
        struct p54_common *priv = dev->priv;
-       kfree(priv->cached_stats);
+       del_timer(&priv->stats_timer);
+       kfree_skb(priv->cached_stats);
        kfree(priv->iq_autocal);
        kfree(priv->output_limit);
        kfree(priv->curve_data);
-       kfree(priv->cached_vdcf);
 }
 EXPORT_SYMBOL_GPL(p54_free_common);
 
index 2fa994cfcfed413cfdf08f9d6c043cec89b7536a..8c8793cb2d79744ab065ab9c957feb928615ac48 100644 (file)
@@ -7,8 +7,12 @@
  * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
  * Copyright (c) 2007, Christian Lamparter <chunkeey@web.de>
  *
- * Based on the islsm (softmac prism54) driver, which is:
- * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
+ * Based on:
+ * - the islsm (softmac prism54) driver, which is:
+ *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
+ *
+ * - LMAC API interface header file for STLC4560 (lmac_longbow.h)
+ *   Copyright (C) 2007 Conexant Systems, Inc.
  *
  * 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
@@ -19,9 +23,24 @@ struct bootrec {
        __le32 code;
        __le32 len;
        u32 data[10];
-       __le16 rx_mtu;
 } __attribute__((packed));
 
+#define PDR_SYNTH_FRONTEND_MASK                0x0007
+#define PDR_SYNTH_IQ_CAL_MASK          0x0018
+#define PDR_SYNTH_IQ_CAL_PA_DETECTOR   0x0000
+#define PDR_SYNTH_IQ_CAL_DISABLED      0x0008
+#define PDR_SYNTH_IQ_CAL_ZIF           0x0010
+#define PDR_SYNTH_FAA_SWITCH_MASK      0x0020
+#define PDR_SYNTH_FAA_SWITCH_ENABLED   0x0001
+#define PDR_SYNTH_24_GHZ_MASK          0x0040
+#define PDR_SYNTH_24_GHZ_DISABLED      0x0040
+#define PDR_SYNTH_5_GHZ_MASK           0x0080
+#define PDR_SYNTH_5_GHZ_DISABLED       0x0080
+#define PDR_SYNTH_RX_DIV_MASK          0x0100
+#define PDR_SYNTH_RX_DIV_SUPPORTED     0x0100
+#define PDR_SYNTH_TX_DIV_MASK          0x0200
+#define PDR_SYNTH_TX_DIV_SUPPORTED     0x0200
+
 struct bootrec_exp_if {
        __le16 role;
        __le16 if_id;
@@ -30,6 +49,13 @@ struct bootrec_exp_if {
        __le16 top_compat;
 } __attribute__((packed));
 
+#define BR_DESC_PRIV_CAP_WEP           BIT(0)
+#define BR_DESC_PRIV_CAP_TKIP          BIT(1)
+#define BR_DESC_PRIV_CAP_MICHAEL       BIT(2)
+#define BR_DESC_PRIV_CAP_CCX_CP                BIT(3)
+#define BR_DESC_PRIV_CAP_CCX_MIC       BIT(4)
+#define BR_DESC_PRIV_CAP_AESCCMP       BIT(5)
+
 struct bootrec_desc {
        __le16 modes;
        __le16 flags;
@@ -37,8 +63,15 @@ struct bootrec_desc {
        __le32 rx_end;
        u8 headroom;
        u8 tailroom;
-       u8 unimportant[6];
+       u8 tx_queues;
+       u8 tx_depth;
+       u8 privacy_caps;
+       u8 rx_keycache_size;
+       u8 time_size;
+       u8 padding;
        u8 rates[16];
+       u8 padding2[4];
+       __le16 rx_mtu;
 } __attribute__((packed));
 
 #define BR_CODE_MIN                    0x80000000
@@ -51,6 +84,34 @@ struct bootrec_desc {
 #define BR_CODE_END_OF_BRA             0xFF0000FF
 #define LEGACY_BR_CODE_END_OF_BRA      0xFFFFFFFF
 
+#define P54_HDR_FLAG_CONTROL           BIT(15)
+#define P54_HDR_FLAG_CONTROL_OPSET     (BIT(15) + BIT(0))
+
+#define P54_HDR_FLAG_DATA_ALIGN                BIT(14)
+#define P54_HDR_FLAG_DATA_OUT_PROMISC  BIT(0)
+#define P54_HDR_FLAG_DATA_OUT_TIMESTAMP BIT(1)
+#define P54_HDR_FLAG_DATA_OUT_SEQNR    BIT(2)
+#define P54_HDR_FLAG_DATA_OUT_BIT3     BIT(3)
+#define P54_HDR_FLAG_DATA_OUT_BURST    BIT(4)
+#define P54_HDR_FLAG_DATA_OUT_NOCANCEL BIT(5)
+#define P54_HDR_FLAG_DATA_OUT_CLEARTIM BIT(6)
+#define P54_HDR_FLAG_DATA_OUT_HITCHHIKE        BIT(7)
+#define P54_HDR_FLAG_DATA_OUT_COMPRESS BIT(8)
+#define P54_HDR_FLAG_DATA_OUT_CONCAT   BIT(9)
+#define P54_HDR_FLAG_DATA_OUT_PCS_ACCEPT BIT(10)
+#define P54_HDR_FLAG_DATA_OUT_WAITEOSP BIT(11)
+
+#define P54_HDR_FLAG_DATA_IN_FCS_GOOD  BIT(0)
+#define P54_HDR_FLAG_DATA_IN_MATCH_MAC BIT(1)
+#define P54_HDR_FLAG_DATA_IN_MCBC      BIT(2)
+#define P54_HDR_FLAG_DATA_IN_BEACON    BIT(3)
+#define P54_HDR_FLAG_DATA_IN_MATCH_BSS BIT(4)
+#define P54_HDR_FLAG_DATA_IN_BCAST_BSS BIT(5)
+#define P54_HDR_FLAG_DATA_IN_DATA      BIT(6)
+#define P54_HDR_FLAG_DATA_IN_TRUNCATED BIT(7)
+#define P54_HDR_FLAG_DATA_IN_BIT8      BIT(8)
+#define P54_HDR_FLAG_DATA_IN_TRANSPARENT BIT(9)
+
 /* PDA defines are Copyright (C) 2005 Nokia Corporation (taken from islsm_pda.h) */
 
 struct pda_entry {
@@ -165,6 +226,19 @@ struct pda_pa_curve_data {
 #define PDR_BASEBAND_REGISTERS                 0x8000
 #define PDR_PER_CHANNEL_BASEBAND_REGISTERS     0x8001
 
+/* PDR definitions for default country & country list */
+#define PDR_COUNTRY_CERT_CODE          0x80
+#define PDR_COUNTRY_CERT_CODE_REAL     0x00
+#define PDR_COUNTRY_CERT_CODE_PSEUDO   0x80
+#define PDR_COUNTRY_CERT_BAND          0x40
+#define PDR_COUNTRY_CERT_BAND_2GHZ     0x00
+#define PDR_COUNTRY_CERT_BAND_5GHZ     0x40
+#define PDR_COUNTRY_CERT_IODOOR                0x30
+#define PDR_COUNTRY_CERT_IODOOR_BOTH   0x00
+#define PDR_COUNTRY_CERT_IODOOR_INDOOR 0x20
+#define PDR_COUNTRY_CERT_IODOOR_OUTDOOR        0x30
+#define PDR_COUNTRY_CERT_INDEX         0x0F
+
 /* stored in skb->cb */
 struct memrecord {
        u32 start_addr;
@@ -177,36 +251,91 @@ struct p54_eeprom_lm86 {
        u8 data[0];
 } __attribute__ ((packed));
 
-struct p54_rx_hdr {
-       __le16 magic;
+enum p54_rx_decrypt_status {
+       P54_DECRYPT_NONE = 0,
+       P54_DECRYPT_OK,
+       P54_DECRYPT_NOKEY,
+       P54_DECRYPT_NOMICHAEL,
+       P54_DECRYPT_NOCKIPMIC,
+       P54_DECRYPT_FAIL_WEP,
+       P54_DECRYPT_FAIL_TKIP,
+       P54_DECRYPT_FAIL_MICAHEL,
+       P54_DECRYPT_FAIL_CKIPKP,
+       P54_DECRYPT_FAIL_CKIPMIC,
+       P54_DECRYPT_FAIL_AESCCMP
+};
+
+struct p54_rx_data {
+       __le16 flags;
        __le16 len;
        __le16 freq;
        u8 antenna;
        u8 rate;
        u8 rssi;
        u8 quality;
-       u16 unknown2;
+       u8 decrypt_status;
+       u8 rssi_raw;
        __le32 tsf32;
        __le32 unalloc0;
        u8 align[0];
 } __attribute__ ((packed));
 
-struct p54_frame_sent_hdr {
+enum p54_trap_type {
+       P54_TRAP_SCAN = 0,
+       P54_TRAP_TIMER,
+       P54_TRAP_BEACON_TX,
+       P54_TRAP_FAA_RADIO_ON,
+       P54_TRAP_FAA_RADIO_OFF,
+       P54_TRAP_RADAR,
+       P54_TRAP_NO_BEACON,
+       P54_TRAP_TBTT,
+       P54_TRAP_SCO_ENTER,
+       P54_TRAP_SCO_EXIT
+};
+
+struct p54_trap {
+       __le16 event;
+       __le16 frequency;
+} __attribute__ ((packed));
+
+enum p54_frame_sent_status {
+       P54_TX_OK = 0,
+       P54_TX_FAILED,
+       P54_TX_PSM,
+       P54_TX_PSM_CANCELLED
+};
+
+struct p54_frame_sent {
        u8 status;
-       u8 retries;
-       __le16 ack_rssi;
+       u8 tries;
+       u8 ack_rssi;
+       u8 quality;
        __le16 seq;
-       u16 rate;
+       u8 antenna;
+       u8 padding;
 } __attribute__ ((packed));
 
-struct p54_tx_control_allocdata {
+enum  p54_tx_data_crypt {
+       P54_CRYPTO_NONE = 0,
+       P54_CRYPTO_WEP,
+       P54_CRYPTO_TKIP,
+       P54_CRYPTO_TKIPMICHAEL,
+       P54_CRYPTO_CCX_WEPMIC,
+       P54_CRYPTO_CCX_KPMIC,
+       P54_CRYPTO_CCX_KP,
+       P54_CRYPTO_AESCCMP
+};
+
+struct p54_tx_data {
        u8 rateset[8];
-       u8 unalloc0[2];
+       u8 rts_rate_idx;
+       u8 crypt_offset;
        u8 key_type;
        u8 key_len;
        u8 key[16];
        u8 hw_queue;
-       u8 unalloc1[9];
+       u8 backlog;
+       __le16 durations[4];
        u8 tx_antenna;
        u8 output_power;
        u8 cts_rate;
@@ -214,8 +343,18 @@ struct p54_tx_control_allocdata {
        u8 align[0];
 } __attribute__ ((packed));
 
-struct p54_tx_control_filter {
-       __le16 filter_type;
+#define P54_FILTER_TYPE_NONE           0
+#define P54_FILTER_TYPE_STATION                BIT(0)
+#define P54_FILTER_TYPE_IBSS           BIT(1)
+#define P54_FILTER_TYPE_AP             BIT(2)
+#define P54_FILTER_TYPE_TRANSPARENT    BIT(3)
+#define P54_FILTER_TYPE_PROMISCUOUS    BIT(4)
+#define P54_FILTER_TYPE_HIBERNATE      BIT(5)
+#define P54_FILTER_TYPE_NOACK          BIT(6)
+#define P54_FILTER_TYPE_RX_DISABLED    BIT(7)
+
+struct p54_setup_mac {
+       __le16 mac_mode;
        u8 mac_addr[ETH_ALEN];
        u8 bssid[ETH_ALEN];
        u8 rx_antenna;
@@ -235,17 +374,29 @@ struct p54_tx_control_filter {
                        __le16 max_rx;
                        __le16 rxhw;
                        __le16 timer;
-                       __le16 unalloc0;
-                       __le32 unalloc1;
+                       __le16 truncate;
+                       __le32 basic_rate_mask;
+                       u8 sbss_offset;
+                       u8 mcast_window;
+                       u8 rx_rssi_threshold;
+                       u8 rx_ed_threshold;
+                       __le32 ref_clock;
+                       __le16 lpf_bandwidth;
+                       __le16 osc_start_delay;
                } v2 __attribute__ ((packed));
        } __attribute__ ((packed));
 } __attribute__ ((packed));
 
-#define P54_TX_CONTROL_FILTER_V1_LEN (sizeof(struct p54_tx_control_filter))
-#define P54_TX_CONTROL_FILTER_V2_LEN (sizeof(struct p54_tx_control_filter)-8)
+#define P54_SETUP_V1_LEN 40
+#define P54_SETUP_V2_LEN (sizeof(struct p54_setup_mac))
 
-struct p54_tx_control_channel {
-       __le16 flags;
+#define P54_SCAN_EXIT  BIT(0)
+#define P54_SCAN_TRAP  BIT(1)
+#define P54_SCAN_ACTIVE BIT(2)
+#define P54_SCAN_FILTER BIT(3)
+
+struct p54_scan {
+       __le16 mode;
        __le16 dwell;
        u8 padding1[20];
        struct pda_iq_autocal_entry iq_autocal;
@@ -268,38 +419,32 @@ struct p54_tx_control_channel {
 
                struct {
                        __le32 basic_rate_mask;
-                        u8 rts_rates[8];
+                       u8 rts_rates[8];
                        __le16 rssical_mul;
                        __le16 rssical_add;
                } v2 __attribute__ ((packed));
        } __attribute__ ((packed));
 } __attribute__ ((packed));
 
-#define P54_TX_CONTROL_CHANNEL_V1_LEN (sizeof(struct p54_tx_control_channel)-12)
-#define P54_TX_CONTROL_CHANNEL_V2_LEN (sizeof(struct p54_tx_control_channel))
+#define P54_SCAN_V1_LEN (sizeof(struct p54_scan)-12)
+#define P54_SCAN_V2_LEN (sizeof(struct p54_scan))
 
-struct p54_tx_control_led {
+struct p54_led {
        __le16 mode;
        __le16 led_temporary;
        __le16 led_permanent;
        __le16 duration;
 } __attribute__ ((packed));
 
-struct p54_tx_vdcf_queues {
-       __le16 aifs;
-       __le16 cwmin;
-       __le16 cwmax;
-       __le16 txop;
-} __attribute__ ((packed));
-
-struct p54_tx_control_vdcf {
-       u8 padding;
+struct p54_edcf {
+       u8 flags;
        u8 slottime;
-       u8 magic1;
-       u8 magic2;
-       struct p54_tx_vdcf_queues queue[8];
-       u8 pad2[4];
+       u8 sifs;
+       u8 eofpad;
+       struct p54_edcf_queue_param queue[8];
+       u8 mapping[4];
        __le16 frameburst;
+       __le16 round_trip_delay;
 } __attribute__ ((packed));
 
 struct p54_statistics {
@@ -312,14 +457,103 @@ struct p54_statistics {
        __le32 tsf32;
        __le32 airtime;
        __le32 noise;
-       __le32 unkn[10]; /* CCE / CCA / RADAR */
+       __le32 sample_noise[8];
+       __le32 sample_cca;
+       __le32 sample_tx;
 } __attribute__ ((packed));
 
-struct p54_tx_control_xbow_synth {
+struct p54_xbow_synth {
        __le16 magic1;
        __le16 magic2;
        __le16 freq;
        u32 padding[5];
 } __attribute__ ((packed));
 
+struct p54_timer {
+       __le32 interval;
+} __attribute__ ((packed));
+
+struct p54_keycache {
+       u8 entry;
+       u8 key_id;
+       u8 mac[ETH_ALEN];
+       u8 padding[2];
+       u8 key_type;
+       u8 key_len;
+       u8 key[24];
+} __attribute__ ((packed));
+
+struct p54_burst {
+       u8 flags;
+       u8 queue;
+       u8 backlog;
+       u8 pad;
+       __le16 durations[32];
+} __attribute__ ((packed));
+
+struct p54_psm_interval {
+       __le16 interval;
+       __le16 periods;
+} __attribute__ ((packed));
+
+#define P54_PSM                                BIT(0)
+#define P54_PSM_DTIM                   BIT(1)
+#define P54_PSM_MCBC                   BIT(2)
+#define P54_PSM_CHECKSUM               BIT(3)
+#define P54_PSM_SKIP_MORE_DATA         BIT(4)
+#define P54_PSM_BEACON_TIMEOUT         BIT(5)
+#define P54_PSM_HFOSLEEP               BIT(6)
+#define P54_PSM_AUTOSWITCH_SLEEP       BIT(7)
+#define P54_PSM_LPIT                   BIT(8)
+#define P54_PSM_BF_UCAST_SKIP          BIT(9)
+#define P54_PSM_BF_MCAST_SKIP          BIT(10)
+
+struct p54_psm {
+       __le16 mode;
+       __le16 aid;
+       struct p54_psm_interval intervals[4];
+       u8 beacon_rssi_skip_max;
+       u8 rssi_delta_threshold;
+       u8 nr;
+       u8 exclude[1];
+} __attribute__ ((packed));
+
+#define MC_FILTER_ADDRESS_NUM 4
+
+struct p54_group_address_table {
+       __le16 filter_enable;
+       __le16 num_address;
+       u8 mac_list[MC_FILTER_ADDRESS_NUM][ETH_ALEN];
+} __attribute__ ((packed));
+
+struct p54_txcancel {
+       __le32 req_id;
+} __attribute__ ((packed));
+
+struct p54_sta_unlock {
+       u8 addr[ETH_ALEN];
+       u16 padding;
+} __attribute__ ((packed));
+
+#define P54_TIM_CLEAR BIT(15)
+struct p54_tim {
+       u8 count;
+       u8 padding[3];
+       __le16 entry[8];
+} __attribute__ ((packed));
+
+struct p54_cce_quiet {
+       __le32 period;
+} __attribute__ ((packed));
+
+struct p54_bt_balancer {
+       __le16 prio_thresh;
+       __le16 acl_thresh;
+} __attribute__ ((packed));
+
+struct p54_arp_table {
+       __le16 filter_enable;
+       u8 ipv4_addr[4];
+} __attribute__ ((packed));
+
 #endif /* P54COMMON_H */
index 88b3cad8b65e0c72b18bcde9d02c2dc11f2f0b97..c4a868ae6d6b0efef665bdfa42184b35fd21e807 100644 (file)
@@ -28,6 +28,7 @@ MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
 MODULE_DESCRIPTION("Prism54 PCI wireless driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("prism54pci");
+MODULE_FIRMWARE("isl3886pci");
 
 static struct pci_device_id p54p_table[] __devinitdata = {
        /* Intersil PRISM Duette/Prism GT Wireless LAN adapter */
@@ -72,11 +73,13 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev)
        P54P_WRITE(ctrl_stat, reg);
        wmb();
 
-       err = request_firmware(&fw_entry, "isl3886", &priv->pdev->dev);
+       err = request_firmware(&fw_entry, "isl3886pci", &priv->pdev->dev);
        if (err) {
                printk(KERN_ERR "%s (p54pci): cannot find firmware "
-                      "(isl3886)\n", pci_name(priv->pdev));
-               return err;
+                      "(isl3886pci)\n", pci_name(priv->pdev));
+               err = request_firmware(&fw_entry, "isl3886", &priv->pdev->dev);
+               if (err)
+                       return err;
        }
 
        err = p54_parse_firmware(dev, fw_entry);
@@ -235,7 +238,7 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index,
 
        while (i != idx) {
                desc = &ring[i];
-               kfree(tx_buf[i]);
+               p54_free_skb(dev, tx_buf[i]);
                tx_buf[i] = NULL;
 
                pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
@@ -306,8 +309,8 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id)
        return reg ? IRQ_HANDLED : IRQ_NONE;
 }
 
-static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data,
-                   size_t len, int free_on_tx)
+static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
+                   int free_on_tx)
 {
        struct p54p_priv *priv = dev->priv;
        struct p54p_ring_control *ring_control = priv->ring_control;
@@ -322,18 +325,19 @@ static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data,
        idx = le32_to_cpu(ring_control->host_idx[1]);
        i = idx % ARRAY_SIZE(ring_control->tx_data);
 
-       mapping = pci_map_single(priv->pdev, data, len, PCI_DMA_TODEVICE);
+       mapping = pci_map_single(priv->pdev, skb->data, skb->len,
+                                PCI_DMA_TODEVICE);
        desc = &ring_control->tx_data[i];
        desc->host_addr = cpu_to_le32(mapping);
-       desc->device_addr = data->req_id;
-       desc->len = cpu_to_le16(len);
+       desc->device_addr = ((struct p54_hdr *)skb->data)->req_id;
+       desc->len = cpu_to_le16(skb->len);
        desc->flags = 0;
 
        wmb();
        ring_control->host_idx[1] = cpu_to_le32(idx + 1);
 
        if (free_on_tx)
-               priv->tx_buf_data[i] = data;
+               priv->tx_buf_data[i] = skb;
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -342,8 +346,10 @@ static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data,
 
        /* FIXME: unlikely to happen because the device usually runs out of
           memory before we fill the ring up, but we can make it impossible */
-       if (idx - device_idx > ARRAY_SIZE(ring_control->tx_data) - 2)
+       if (idx - device_idx > ARRAY_SIZE(ring_control->tx_data) - 2) {
+               p54_free_skb(dev, skb);
                printk(KERN_INFO "%s: tx overflow.\n", wiphy_name(dev->wiphy));
+       }
 }
 
 static void p54p_stop(struct ieee80211_hw *dev)
@@ -393,7 +399,7 @@ static void p54p_stop(struct ieee80211_hw *dev)
                                         le16_to_cpu(desc->len),
                                         PCI_DMA_TODEVICE);
 
-               kfree(priv->tx_buf_data[i]);
+               p54_free_skb(dev, priv->tx_buf_data[i]);
                priv->tx_buf_data[i] = NULL;
        }
 
@@ -405,7 +411,7 @@ static void p54p_stop(struct ieee80211_hw *dev)
                                         le16_to_cpu(desc->len),
                                         PCI_DMA_TODEVICE);
 
-               kfree(priv->tx_buf_mgmt[i]);
+               p54_free_skb(dev, priv->tx_buf_mgmt[i]);
                priv->tx_buf_mgmt[i] = NULL;
        }
 
@@ -481,7 +487,6 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
        struct ieee80211_hw *dev;
        unsigned long mem_addr, mem_len;
        int err;
-       DECLARE_MAC_BUF(mac);
 
        err = pci_enable_device(pdev);
        if (err) {
index 75d749bccb0d13e17104b67e348c3723bbb1032b..21ba526a45bf9435a96e92baf6276bc5137cae41 100644 (file)
@@ -28,6 +28,8 @@ MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
 MODULE_DESCRIPTION("Prism54 USB wireless driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("prism54usb");
+MODULE_FIRMWARE("isl3886usb");
+MODULE_FIRMWARE("isl3887usb");
 
 static struct usb_device_id p54u_table[] __devinitdata = {
        /* Version 1 devices (pci chip + net2280) */
@@ -135,6 +137,16 @@ static void p54u_rx_cb(struct urb *urb)
        usb_submit_urb(urb, GFP_ATOMIC);
 }
 
+static void p54u_tx_reuse_skb_cb(struct urb *urb)
+{
+       struct sk_buff *skb = urb->context;
+       struct p54u_priv *priv = (struct p54u_priv *)((struct ieee80211_hw *)
+               usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)))->priv;
+
+       skb_pull(skb, priv->common.tx_hdr_len);
+       usb_free_urb(urb);
+}
+
 static void p54u_tx_cb(struct urb *urb)
 {
        usb_free_urb(urb);
@@ -146,6 +158,16 @@ static void p54u_tx_free_cb(struct urb *urb)
        usb_free_urb(urb);
 }
 
+static void p54u_tx_free_skb_cb(struct urb *urb)
+{
+       struct sk_buff *skb = urb->context;
+       struct ieee80211_hw *dev = (struct ieee80211_hw *)
+               usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+
+       p54_free_skb(dev, skb);
+       usb_free_urb(urb);
+}
+
 static int p54u_init_urbs(struct ieee80211_hw *dev)
 {
        struct p54u_priv *priv = dev->priv;
@@ -192,8 +214,8 @@ static void p54u_free_urbs(struct ieee80211_hw *dev)
        }
 }
 
-static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data,
-                        size_t len, int free_on_tx)
+static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb,
+                        int free_on_tx)
 {
        struct p54u_priv *priv = dev->priv;
        struct urb *addr_urb, *data_urb;
@@ -209,11 +231,14 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data,
        }
 
        usb_fill_bulk_urb(addr_urb, priv->udev,
-               usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), &data->req_id,
-               sizeof(data->req_id), p54u_tx_cb, dev);
+                         usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
+                         &((struct p54_hdr *)skb->data)->req_id, 4,
+                         p54u_tx_cb, dev);
        usb_fill_bulk_urb(data_urb, priv->udev,
-               usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), data, len,
-               free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
+                         usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
+                         skb->data, skb->len,
+                         free_on_tx ? p54u_tx_free_skb_cb :
+                                      p54u_tx_reuse_skb_cb, skb);
 
        usb_submit_urb(addr_urb, GFP_ATOMIC);
        usb_submit_urb(data_urb, GFP_ATOMIC);
@@ -232,31 +257,35 @@ static __le32 p54u_lm87_chksum(const u32 *data, size_t length)
        return cpu_to_le32(chk);
 }
 
-static void p54u_tx_lm87(struct ieee80211_hw *dev,
-                        struct p54_control_hdr *data,
-                        size_t len, int free_on_tx)
+static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb,
+                        int free_on_tx)
 {
        struct p54u_priv *priv = dev->priv;
        struct urb *data_urb;
-       struct lm87_tx_hdr *hdr = (void *)data - sizeof(*hdr);
+       struct lm87_tx_hdr *hdr;
+       __le32 checksum;
+       __le32 addr = ((struct p54_hdr *)skb->data)->req_id;
 
        data_urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!data_urb)
                return;
 
-       hdr->chksum = p54u_lm87_chksum((u32 *)data, len);
-       hdr->device_addr = data->req_id;
+       checksum = p54u_lm87_chksum((u32 *)skb->data, skb->len);
+       hdr = (struct lm87_tx_hdr *)skb_push(skb, sizeof(*hdr));
+       hdr->chksum = checksum;
+       hdr->device_addr = addr;
 
        usb_fill_bulk_urb(data_urb, priv->udev,
-               usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr,
-               len + sizeof(*hdr), free_on_tx ? p54u_tx_free_cb : p54u_tx_cb,
-               dev);
+                         usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
+                         skb->data, skb->len,
+                         free_on_tx ? p54u_tx_free_skb_cb :
+                                      p54u_tx_reuse_skb_cb, skb);
 
        usb_submit_urb(data_urb, GFP_ATOMIC);
 }
 
-static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data,
-                           size_t len, int free_on_tx)
+static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb,
+                           int free_on_tx)
 {
        struct p54u_priv *priv = dev->priv;
        struct urb *int_urb, *data_urb;
@@ -284,11 +313,10 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *da
        reg->addr = cpu_to_le32(P54U_DEV_BASE);
        reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
 
-       len += sizeof(*data);
-       hdr = (void *)data - sizeof(*hdr);
+       hdr = (void *)skb_push(skb, sizeof(*hdr));
        memset(hdr, 0, sizeof(*hdr));
-       hdr->device_addr = data->req_id;
-       hdr->len = cpu_to_le16(len);
+       hdr->device_addr = ((struct p54_hdr *)skb->data)->req_id;
+       hdr->len = cpu_to_le16(skb->len + sizeof(struct p54_hdr));
 
        usb_fill_bulk_urb(int_urb, priv->udev,
                usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
@@ -296,8 +324,10 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *da
        usb_submit_urb(int_urb, GFP_ATOMIC);
 
        usb_fill_bulk_urb(data_urb, priv->udev,
-               usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, len + sizeof(*hdr),
-               free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
+                         usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
+                         skb->data, skb->len,
+                         free_on_tx ? p54u_tx_free_skb_cb :
+                                      p54u_tx_reuse_skb_cb, skb);
        usb_submit_urb(data_urb, GFP_ATOMIC);
 }
 
@@ -387,10 +417,13 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
                goto err_reset;
        }
 
-       err = request_firmware(&fw_entry, "isl3887usb_bare", &priv->udev->dev);
+       err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev);
        if (err) {
-               printk(KERN_ERR "p54usb: cannot find firmware (isl3887usb_bare)!\n");
-               goto err_req_fw_failed;
+               printk(KERN_ERR "p54usb: cannot find firmware (isl3887usb)\n");
+               err = request_firmware(&fw_entry, "isl3887usb_bare",
+                       &priv->udev->dev);
+               if (err)
+                       goto err_req_fw_failed;
        }
 
        err = p54_parse_firmware(dev, fw_entry);
@@ -525,11 +558,15 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
                return -ENOMEM;
        }
 
-       err = request_firmware(&fw_entry, "isl3890usb", &priv->udev->dev);
+       err = request_firmware(&fw_entry, "isl3886usb", &priv->udev->dev);
        if (err) {
-               printk(KERN_ERR "p54usb: cannot find firmware (isl3890usb)!\n");
-               kfree(buf);
-               return err;
+               printk(KERN_ERR "p54usb: cannot find firmware (isl3886usb)\n");
+               err = request_firmware(&fw_entry, "isl3890usb",
+                       &priv->udev->dev);
+               if (err) {
+                       kfree(buf);
+                       return err;
+                       }
        }
 
        err = p54_parse_firmware(dev, fw_entry);
@@ -786,7 +823,6 @@ static int __devinit p54u_probe(struct usb_interface *intf,
        struct p54u_priv *priv;
        int err;
        unsigned int i, recognized_pipes;
-       DECLARE_MAC_BUF(mac);
 
        dev = p54_init_common(sizeof(*priv));
        if (!dev) {
index 16e68f4b654a94370433cd928c23405f4a5be950..57a150a22de5c6544bee00f7799e5b2caf9164e6 100644 (file)
@@ -2028,12 +2028,11 @@ static void
 format_event(islpci_private *priv, char *dest, const char *str,
             const struct obj_mlme *mlme, u16 *length, int error)
 {
-       DECLARE_MAC_BUF(mac);
        int n = snprintf(dest, IW_CUSTOM_MAX,
-                        "%s %s %s %s (%2.2X)",
+                        "%s %s %pM %s (%2.2X)",
                         str,
                         ((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"),
-                        print_mac(mac, mlme->address),
+                        mlme->address,
                         (error ? (mlme->code ? " : REJECTED " : " : ACCEPTED ")
                          : ""), mlme->code);
        BUG_ON(n > IW_CUSTOM_MAX);
@@ -2113,7 +2112,6 @@ prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
 {
        struct list_head *ptr;
        struct islpci_bss_wpa_ie *bss = NULL;
-       DECLARE_MAC_BUF(mac);
 
        if (wpa_ie_len > MAX_WPA_IE_LEN)
                wpa_ie_len = MAX_WPA_IE_LEN;
@@ -2154,7 +2152,7 @@ prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
                bss->last_update = jiffies;
        } else {
                printk(KERN_DEBUG "Failed to add BSS WPA entry for "
-                      "%s\n", print_mac(mac, bssid));
+                      "%pM\n", bssid);
        }
 
        /* expire old entries from WPA list */
@@ -2219,7 +2217,6 @@ prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr,
 {
        struct ieee80211_beacon_phdr *hdr;
        u8 *pos, *end;
-       DECLARE_MAC_BUF(mac);
 
        if (!priv->wpa)
                return;
@@ -2230,7 +2227,7 @@ prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr,
        while (pos < end) {
                if (pos + 2 + pos[1] > end) {
                        printk(KERN_DEBUG "Parsing Beacon/ProbeResp failed "
-                              "for %s\n", print_mac(mac, addr));
+                              "for %pM\n", addr);
                        return;
                }
                if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 &&
@@ -2269,7 +2266,6 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
        size_t len = 0; /* u16, better? */
        u8 *payload = NULL, *pos = NULL;
        int ret;
-       DECLARE_MAC_BUF(mac);
 
        /* I think all trapable objects are listed here.
         * Some oids have a EX version. The difference is that they are emitted
@@ -2358,8 +2354,8 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
                        break;
 
                memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
-               printk(KERN_DEBUG "Authenticate from: address:\t%s\n",
-                      print_mac(mac, mlmeex->address));
+               printk(KERN_DEBUG "Authenticate from: address:\t%pM\n",
+                      mlmeex->address);
                confirm->id = -1; /* or mlmeex->id ? */
                confirm->state = 0; /* not used */
                confirm->code = 0;
@@ -2404,8 +2400,8 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
                wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie);
 
                if (!wpa_ie_len) {
-                       printk(KERN_DEBUG "No WPA IE found from address:\t%s\n",
-                              print_mac(mac, mlmeex->address));
+                       printk(KERN_DEBUG "No WPA IE found from address:\t%pM\n",
+                              mlmeex->address);
                        kfree(confirm);
                        break;
                }
@@ -2441,8 +2437,8 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
                wpa_ie_len = prism54_wpa_bss_ie_get(priv, mlmeex->address, wpa_ie);
 
                if (!wpa_ie_len) {
-                       printk(KERN_DEBUG "No WPA IE found from address:\t%s\n",
-                              print_mac(mac, mlmeex->address));
+                       printk(KERN_DEBUG "No WPA IE found from address:\t%pM\n",
+                              mlmeex->address);
                        kfree(confirm);
                        break;
                }
index 1404a57175207f71d39ac28b12ad78651610d0c1..81b71f07f5ad7b14a87aaa75027717bb49431543 100644 (file)
@@ -414,7 +414,6 @@ static int ray_config(struct pcmcia_device *link)
     memreq_t mem;
     struct net_device *dev = (struct net_device *)link->priv;
     ray_dev_t *local = netdev_priv(dev);
-    DECLARE_MAC_BUF(mac);
 
     DEBUG(1, "ray_config(0x%p)\n", link);
 
@@ -485,8 +484,8 @@ static int ray_config(struct pcmcia_device *link)
     strcpy(local->node.dev_name, dev->name);
     link->dev_node = &local->node;
 
-    printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %s\n",
-       dev->name, dev->irq, print_mac(mac, dev->dev_addr));
+    printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %pM\n",
+       dev->name, dev->irq, dev->dev_addr);
 
     return 0;
 
@@ -2285,7 +2284,6 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned i
 
     skb->protocol = eth_type_trans(skb,dev);
     netif_rx(skb);
-    dev->last_rx = jiffies;
     local->stats.rx_packets++;
     local->stats.rx_bytes += total_len;
 
@@ -2595,7 +2593,6 @@ static int ray_cs_proc_show(struct seq_file *m, void *v)
     UCHAR *p;
     struct freq_hop_element *pfh;
     UCHAR c[33];
-    DECLARE_MAC_BUF(mac);
 
     link = this_device;
     if (!link)
@@ -2623,8 +2620,7 @@ static int ray_cs_proc_show(struct seq_file *m, void *v)
                    nettype[local->sparm.b5.a_network_type], c);
 
     p = local->bss_id;
-    seq_printf(m, "BSSID                = %s\n",
-                   print_mac(mac, p));
+    seq_printf(m, "BSSID                = %pM\n", p);
 
     seq_printf(m, "Country code         = %d\n",
                    local->sparm.b5.a_curr_country_code);
index 2b414899dfa08107f8c2faba4be42e0aa2ffde79..607ce9f61b5400fa0e43d0bd675bfd0674dec406 100644 (file)
 #include <linux/usb.h>
 #include <linux/usb/cdc.h>
 #include <linux/wireless.h>
+#include <linux/ieee80211.h>
 #include <linux/if_arp.h>
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
 #include <net/iw_handler.h>
-#include <net/ieee80211.h>
 #include <linux/usb/usbnet.h>
 #include <linux/usb/rndis_host.h>
 
@@ -1104,7 +1104,7 @@ static int rndis_iw_get_range(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
        struct iw_range *range = (struct iw_range *)extra;
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
        int len, ret, i, j, num, has_80211g_rates;
        u8 rates[8];
@@ -1210,7 +1210,7 @@ static int rndis_iw_get_range(struct net_device *dev,
 static int rndis_iw_get_name(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 
        strcpy(wrqu->name, priv->name);
@@ -1223,7 +1223,7 @@ static int rndis_iw_set_essid(struct net_device *dev,
 {
        struct ndis_80211_ssid ssid;
        int length = wrqu->essid.length;
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
 
        devdbg(usbdev, "SIOCSIWESSID: [flags:%d,len:%d] '%.32s'",
                wrqu->essid.flags, wrqu->essid.length, essid);
@@ -1250,7 +1250,7 @@ static int rndis_iw_get_essid(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *essid)
 {
        struct ndis_80211_ssid ssid;
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        int ret;
 
        ret = get_essid(usbdev, &ssid);
@@ -1273,15 +1273,14 @@ static int rndis_iw_get_essid(struct net_device *dev,
 static int rndis_iw_get_bssid(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        unsigned char bssid[ETH_ALEN];
        int ret;
-       DECLARE_MAC_BUF(mac);
 
        ret = get_bssid(usbdev, bssid);
 
        if (ret == 0)
-               devdbg(usbdev, "SIOCGIWAP: %s", print_mac(mac, bssid));
+               devdbg(usbdev, "SIOCGIWAP: %pM", bssid);
        else
                devdbg(usbdev, "SIOCGIWAP: <not associated>");
 
@@ -1295,12 +1294,11 @@ static int rndis_iw_get_bssid(struct net_device *dev,
 static int rndis_iw_set_bssid(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        u8 *bssid = (u8 *)wrqu->ap_addr.sa_data;
-       DECLARE_MAC_BUF(mac);
        int ret;
 
-       devdbg(usbdev, "SIOCSIWAP: %s", print_mac(mac, bssid));
+       devdbg(usbdev, "SIOCSIWAP: %pM", bssid);
 
        ret = rndis_set_oid(usbdev, OID_802_11_BSSID, bssid, ETH_ALEN);
 
@@ -1318,7 +1316,7 @@ static int rndis_iw_set_auth(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
        struct iw_param *p = &wrqu->param;
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
        int ret = -ENOTSUPP;
 
@@ -1399,7 +1397,7 @@ static int rndis_iw_get_auth(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
        struct iw_param *p = &wrqu->param;
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 
        switch (p->flags & IW_AUTH_INDEX) {
@@ -1431,7 +1429,7 @@ static int rndis_iw_get_mode(struct net_device *dev,
                                struct iw_request_info *info,
                                union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 
        switch (priv->infra_mode) {
@@ -1454,7 +1452,7 @@ static int rndis_iw_get_mode(struct net_device *dev,
 static int rndis_iw_set_mode(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        int mode;
 
        devdbg(usbdev, "SIOCSIWMODE: %08x", wrqu->mode);
@@ -1479,7 +1477,7 @@ static int rndis_iw_set_mode(struct net_device *dev,
 static int rndis_iw_set_encode(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
        int ret, index, key_len;
        u8 *key;
@@ -1542,7 +1540,7 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
        struct ndis_80211_key ndis_key;
        int keyidx, ret;
@@ -1627,7 +1625,7 @@ 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 usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        union iwreq_data evt;
        int ret = -EINVAL;
        __le32 tmp;
@@ -1652,19 +1650,18 @@ static char *rndis_translate_scan(struct net_device *dev,
                                  struct ndis_80211_bssid_ex *bssid)
 {
 #ifdef DEBUG
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
 #endif
-       struct ieee80211_info_element *ie;
+       u8 *ie;
        char *current_val;
        int bssid_len, ie_len, i;
        u32 beacon, atim;
        struct iw_event iwe;
        unsigned char sbuf[32];
-       DECLARE_MAC_BUF(mac);
 
        bssid_len = le32_to_cpu(bssid->length);
 
-       devdbg(usbdev, "BSSID %s", print_mac(mac, bssid->mac));
+       devdbg(usbdev, "BSSID %pM", bssid->mac);
        iwe.cmd = SIOCGIWAP;
        iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
        memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN);
@@ -1753,20 +1750,20 @@ static char *rndis_translate_scan(struct net_device *dev,
        ie_len = min(bssid_len - (int)sizeof(*bssid),
                                        (int)le32_to_cpu(bssid->ie_length));
        ie_len -= sizeof(struct ndis_80211_fixed_ies);
-       while (ie_len >= sizeof(*ie) && sizeof(*ie) + ie->len <= ie_len) {
-               if ((ie->id == MFIE_TYPE_GENERIC && ie->len >= 4 &&
-                               memcmp(ie->data, "\x00\x50\xf2\x01", 4) == 0) ||
-                               ie->id == MFIE_TYPE_RSN) {
+       while (ie_len >= 2 && 2 + ie[1] <= ie_len) {
+               if ((ie[0] == WLAN_EID_GENERIC && ie[1] >= 4 &&
+                    memcmp(ie + 2, "\x00\x50\xf2\x01", 4) == 0) ||
+                   ie[0] == WLAN_EID_RSN) {
                        devdbg(usbdev, "IE: WPA%d",
-                                       (ie->id == MFIE_TYPE_RSN) ? 2 : 1);
+                                       (ie[0] == WLAN_EID_RSN) ? 2 : 1);
                        iwe.cmd = IWEVGENIE;
-                       iwe.u.data.length = min(ie->len + 2, MAX_WPA_IE_LEN);
-                       cev = iwe_stream_add_point(info, cev, end_buf, &iwe,
-                                                               (u8 *)ie);
+                       /* arbitrary cut-off at 64 */
+                       iwe.u.data.length = min(ie[1] + 2, 64);
+                       cev = iwe_stream_add_point(info, cev, end_buf, &iwe, ie);
                }
 
-               ie_len -= sizeof(*ie) + ie->len;
-               ie = (struct ieee80211_info_element *)&ie->data[ie->len];
+               ie_len -= 2 + ie[1];
+               ie += 2 + ie[1];
        }
 
        return cev;
@@ -1776,7 +1773,7 @@ static char *rndis_translate_scan(struct net_device *dev,
 static int rndis_iw_get_scan(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        void *buf = NULL;
        char *cev = extra;
        struct ndis_80211_bssid_list_ex *bssid_list;
@@ -1822,7 +1819,7 @@ out:
 static int rndis_iw_set_genie(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
        int ret = 0;
 
@@ -1856,7 +1853,7 @@ static int rndis_iw_set_genie(struct net_device *dev,
 static int rndis_iw_get_genie(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 
        devdbg(usbdev, "SIOCGIWGENIE");
@@ -1879,7 +1876,7 @@ static int rndis_iw_get_genie(struct net_device *dev,
 static int rndis_iw_set_rts(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        __le32 tmp;
        devdbg(usbdev, "SIOCSIWRTS");
 
@@ -1892,7 +1889,7 @@ static int rndis_iw_set_rts(struct net_device *dev,
 static int rndis_iw_get_rts(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        __le32 tmp;
        int len, ret;
 
@@ -1913,7 +1910,7 @@ static int rndis_iw_get_rts(struct net_device *dev,
 static int rndis_iw_set_frag(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        __le32 tmp;
 
        devdbg(usbdev, "SIOCSIWFRAG");
@@ -1927,7 +1924,7 @@ static int rndis_iw_set_frag(struct net_device *dev,
 static int rndis_iw_get_frag(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        __le32 tmp;
        int len, ret;
 
@@ -1947,7 +1944,7 @@ static int rndis_iw_get_frag(struct net_device *dev,
 static int rndis_iw_set_nick(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 
        devdbg(usbdev, "SIOCSIWNICK");
@@ -1964,7 +1961,7 @@ static int rndis_iw_set_nick(struct net_device *dev,
 static int rndis_iw_get_nick(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 
        wrqu->data.flags = 1;
@@ -1980,7 +1977,7 @@ static int rndis_iw_get_nick(struct net_device *dev,
 static int rndis_iw_set_freq(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct ndis_80211_conf config;
        unsigned int dsconfig;
        int len, ret;
@@ -2011,7 +2008,7 @@ static int rndis_iw_set_freq(struct net_device *dev,
 static int rndis_iw_get_freq(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct ndis_80211_conf config;
        int len, ret;
 
@@ -2028,7 +2025,7 @@ static int rndis_iw_get_freq(struct net_device *dev,
 static int rndis_iw_get_txpower(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
        __le32 tx_power;
        int ret = 0, len;
@@ -2062,7 +2059,7 @@ static int rndis_iw_get_txpower(struct net_device *dev,
 static int rndis_iw_set_txpower(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
        __le32 tx_power = 0;
        int ret = 0;
@@ -2114,7 +2111,7 @@ static int rndis_iw_set_txpower(struct net_device *dev,
 static int rndis_iw_get_rate(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        __le32 tmp;
        int ret, len;
 
@@ -2132,7 +2129,7 @@ static int rndis_iw_get_rate(struct net_device *dev,
 static int rndis_iw_set_mlme(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
        struct iw_mlme *mlme = (struct iw_mlme *)extra;
        unsigned char bssid[ETH_ALEN];
@@ -2157,7 +2154,7 @@ static int rndis_iw_set_mlme(struct net_device *dev,
 
 static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
        unsigned long flags;
 
@@ -2287,7 +2284,7 @@ get_bssid:
 
 static void rndis_wext_set_multicast_list(struct net_device *dev)
 {
-       struct usbnet *usbdev = dev->priv;
+       struct usbnet *usbdev = netdev_priv(dev);
        struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
 
        if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
index 08cb9eec16a6bca16c3e5dc30c467db1e600a3af..42bd38ac7a1db249b3a309d3ec6d89550e3f9c6b 100644 (file)
@@ -188,43 +188,34 @@ static void rt2400pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
 }
 
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
-#define CSR_OFFSET(__word)     ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
-
-static void rt2400pci_read_csr(struct rt2x00_dev *rt2x00dev,
-                              const unsigned int word, u32 *data)
-{
-       rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data);
-}
-
-static void rt2400pci_write_csr(struct rt2x00_dev *rt2x00dev,
-                               const unsigned int word, u32 data)
-{
-       rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data);
-}
-
 static const struct rt2x00debug rt2400pci_rt2x00debug = {
        .owner  = THIS_MODULE,
        .csr    = {
-               .read           = rt2400pci_read_csr,
-               .write          = rt2400pci_write_csr,
+               .read           = rt2x00pci_register_read,
+               .write          = rt2x00pci_register_write,
+               .flags          = RT2X00DEBUGFS_OFFSET,
+               .word_base      = CSR_REG_BASE,
                .word_size      = sizeof(u32),
                .word_count     = CSR_REG_SIZE / sizeof(u32),
        },
        .eeprom = {
                .read           = rt2x00_eeprom_read,
                .write          = rt2x00_eeprom_write,
+               .word_base      = EEPROM_BASE,
                .word_size      = sizeof(u16),
                .word_count     = EEPROM_SIZE / sizeof(u16),
        },
        .bbp    = {
                .read           = rt2400pci_bbp_read,
                .write          = rt2400pci_bbp_write,
+               .word_base      = BBP_BASE,
                .word_size      = sizeof(u8),
                .word_count     = BBP_SIZE / sizeof(u8),
        },
        .rf     = {
                .read           = rt2x00_rf_read,
                .write          = rt2400pci_rf_write,
+               .word_base      = RF_BASE,
                .word_size      = sizeof(u32),
                .word_count     = RF_SIZE / sizeof(u32),
        },
@@ -396,12 +387,74 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
        rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110));
        rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
+
+       rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
+
+       rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
+       rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
+       rt2x00pci_register_write(rt2x00dev, CSR11, reg);
+
+       rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
+       rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
+       rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
+       rt2x00pci_register_write(rt2x00dev, CSR18, reg);
+
+       rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
+       rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
+       rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
+       rt2x00pci_register_write(rt2x00dev, CSR19, reg);
 }
 
-static void rt2400pci_config_phymode(struct rt2x00_dev *rt2x00dev,
-                                    const int basic_rate_mask)
+static void rt2400pci_config_ant(struct rt2x00_dev *rt2x00dev,
+                                struct antenna_setup *ant)
 {
-       rt2x00pci_register_write(rt2x00dev, ARCSR1, basic_rate_mask);
+       u8 r1;
+       u8 r4;
+
+       /*
+        * We should never come here because rt2x00lib is supposed
+        * to catch this and send us the correct antenna explicitely.
+        */
+       BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
+              ant->tx == ANTENNA_SW_DIVERSITY);
+
+       rt2400pci_bbp_read(rt2x00dev, 4, &r4);
+       rt2400pci_bbp_read(rt2x00dev, 1, &r1);
+
+       /*
+        * Configure the TX antenna.
+        */
+       switch (ant->tx) {
+       case ANTENNA_HW_DIVERSITY:
+               rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 1);
+               break;
+       case ANTENNA_A:
+               rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 0);
+               break;
+       case ANTENNA_B:
+       default:
+               rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2);
+               break;
+       }
+
+       /*
+        * Configure the RX antenna.
+        */
+       switch (ant->rx) {
+       case ANTENNA_HW_DIVERSITY:
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+               break;
+       case ANTENNA_A:
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 0);
+               break;
+       case ANTENNA_B:
+       default:
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+               break;
+       }
+
+       rt2400pci_bbp_write(rt2x00dev, 4, r4);
+       rt2400pci_bbp_write(rt2x00dev, 1, r1);
 }
 
 static void rt2400pci_config_channel(struct rt2x00_dev *rt2x00dev,
@@ -460,56 +513,17 @@ static void rt2400pci_config_txpower(struct rt2x00_dev *rt2x00dev, int txpower)
        rt2400pci_bbp_write(rt2x00dev, 3, TXPOWER_TO_DEV(txpower));
 }
 
-static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,
-                                    struct antenna_setup *ant)
+static void rt2400pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
+                                        struct rt2x00lib_conf *libconf)
 {
-       u8 r1;
-       u8 r4;
-
-       /*
-        * We should never come here because rt2x00lib is supposed
-        * to catch this and send us the correct antenna explicitely.
-        */
-       BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
-              ant->tx == ANTENNA_SW_DIVERSITY);
-
-       rt2400pci_bbp_read(rt2x00dev, 4, &r4);
-       rt2400pci_bbp_read(rt2x00dev, 1, &r1);
-
-       /*
-        * Configure the TX antenna.
-        */
-       switch (ant->tx) {
-       case ANTENNA_HW_DIVERSITY:
-               rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 1);
-               break;
-       case ANTENNA_A:
-               rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 0);
-               break;
-       case ANTENNA_B:
-       default:
-               rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2);
-               break;
-       }
-
-       /*
-        * Configure the RX antenna.
-        */
-       switch (ant->rx) {
-       case ANTENNA_HW_DIVERSITY:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-               break;
-       case ANTENNA_A:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 0);
-               break;
-       case ANTENNA_B:
-       default:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
-               break;
-       }
+       u32 reg;
 
-       rt2400pci_bbp_write(rt2x00dev, 4, r4);
-       rt2400pci_bbp_write(rt2x00dev, 1, r1);
+       rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
+       rt2x00_set_field32(&reg, CSR11_LONG_RETRY,
+                          libconf->conf->long_frame_max_tx_count);
+       rt2x00_set_field32(&reg, CSR11_SHORT_RETRY,
+                          libconf->conf->short_frame_max_tx_count);
+       rt2x00pci_register_write(rt2x00dev, CSR11, reg);
 }
 
 static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev,
@@ -517,20 +531,6 @@ static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
-       rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
-       rt2x00_set_field32(&reg, CSR11_SLOT_TIME, libconf->slot_time);
-       rt2x00pci_register_write(rt2x00dev, CSR11, reg);
-
-       rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
-       rt2x00_set_field32(&reg, CSR18_SIFS, libconf->sifs);
-       rt2x00_set_field32(&reg, CSR18_PIFS, libconf->pifs);
-       rt2x00pci_register_write(rt2x00dev, CSR18, reg);
-
-       rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
-       rt2x00_set_field32(&reg, CSR19_DIFS, libconf->difs);
-       rt2x00_set_field32(&reg, CSR19_EIFS, libconf->eifs);
-       rt2x00pci_register_write(rt2x00dev, CSR19, reg);
-
        rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
        rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
        rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
@@ -548,16 +548,14 @@ static void rt2400pci_config(struct rt2x00_dev *rt2x00dev,
                             struct rt2x00lib_conf *libconf,
                             const unsigned int flags)
 {
-       if (flags & CONFIG_UPDATE_PHYMODE)
-               rt2400pci_config_phymode(rt2x00dev, libconf->basic_rates);
-       if (flags & CONFIG_UPDATE_CHANNEL)
+       if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
                rt2400pci_config_channel(rt2x00dev, &libconf->rf);
-       if (flags & CONFIG_UPDATE_TXPOWER)
+       if (flags & IEEE80211_CONF_CHANGE_POWER)
                rt2400pci_config_txpower(rt2x00dev,
                                         libconf->conf->power_level);
-       if (flags & CONFIG_UPDATE_ANTENNA)
-               rt2400pci_config_antenna(rt2x00dev, &libconf->ant);
-       if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
+       if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
+               rt2400pci_config_retry_limit(rt2x00dev, libconf);
+       if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
                rt2400pci_config_duration(rt2x00dev, libconf);
 }
 
@@ -1313,10 +1311,8 @@ static int rt2400pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
         */
        mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
        if (!is_valid_ether_addr(mac)) {
-               DECLARE_MAC_BUF(macbuf);
-
                random_ether_addr(mac);
-               EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac));
+               EEPROM(rt2x00dev, "MAC: %pM\n", mac);
        }
 
        rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
@@ -1504,20 +1500,6 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
 /*
  * IEEE80211 stack callback functions.
  */
-static int rt2400pci_set_retry_limit(struct ieee80211_hw *hw,
-                                    u32 short_retry, u32 long_retry)
-{
-       struct rt2x00_dev *rt2x00dev = hw->priv;
-       u32 reg;
-
-       rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
-       rt2x00_set_field32(&reg, CSR11_LONG_RETRY, long_retry);
-       rt2x00_set_field32(&reg, CSR11_SHORT_RETRY, short_retry);
-       rt2x00pci_register_write(rt2x00dev, CSR11, reg);
-
-       return 0;
-}
-
 static int rt2400pci_conf_tx(struct ieee80211_hw *hw, u16 queue,
                             const struct ieee80211_tx_queue_params *params)
 {
@@ -1576,7 +1558,6 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
        .config_interface       = rt2x00mac_config_interface,
        .configure_filter       = rt2x00mac_configure_filter,
        .get_stats              = rt2x00mac_get_stats,
-       .set_retry_limit        = rt2400pci_set_retry_limit,
        .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt2400pci_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
@@ -1604,6 +1585,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
        .config_filter          = rt2400pci_config_filter,
        .config_intf            = rt2400pci_config_intf,
        .config_erp             = rt2400pci_config_erp,
+       .config_ant             = rt2400pci_config_ant,
        .config                 = rt2400pci_config,
 };
 
index bbff381ce3963d11e28b9b261c5c44ab88d3da5b..9aefda4ab3c263c4163543fff32a7853b8139ec8 100644 (file)
@@ -46,7 +46,9 @@
 #define CSR_REG_SIZE                   0x014c
 #define EEPROM_BASE                    0x0000
 #define EEPROM_SIZE                    0x0100
+#define BBP_BASE                       0x0000
 #define BBP_SIZE                       0x0020
+#define RF_BASE                                0x0000
 #define RF_SIZE                                0x0010
 
 /*
index ef42cc04a2d736428d112bdc28caa4af58aeeca4..928452f30c25d53fdff254a6a2f5a740822ed22b 100644 (file)
@@ -188,43 +188,34 @@ static void rt2500pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
 }
 
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
-#define CSR_OFFSET(__word)     ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
-
-static void rt2500pci_read_csr(struct rt2x00_dev *rt2x00dev,
-                              const unsigned int word, u32 *data)
-{
-       rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data);
-}
-
-static void rt2500pci_write_csr(struct rt2x00_dev *rt2x00dev,
-                               const unsigned int word, u32 data)
-{
-       rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data);
-}
-
 static const struct rt2x00debug rt2500pci_rt2x00debug = {
        .owner  = THIS_MODULE,
        .csr    = {
-               .read           = rt2500pci_read_csr,
-               .write          = rt2500pci_write_csr,
+               .read           = rt2x00pci_register_read,
+               .write          = rt2x00pci_register_write,
+               .flags          = RT2X00DEBUGFS_OFFSET,
+               .word_base      = CSR_REG_BASE,
                .word_size      = sizeof(u32),
                .word_count     = CSR_REG_SIZE / sizeof(u32),
        },
        .eeprom = {
                .read           = rt2x00_eeprom_read,
                .write          = rt2x00_eeprom_write,
+               .word_base      = EEPROM_BASE,
                .word_size      = sizeof(u16),
                .word_count     = EEPROM_SIZE / sizeof(u16),
        },
        .bbp    = {
                .read           = rt2500pci_bbp_read,
                .write          = rt2500pci_bbp_write,
+               .word_base      = BBP_BASE,
                .word_size      = sizeof(u8),
                .word_count     = BBP_SIZE / sizeof(u8),
        },
        .rf     = {
                .read           = rt2x00_rf_read,
                .write          = rt2500pci_rf_write,
+               .word_base      = RF_BASE,
                .word_size      = sizeof(u32),
                .word_count     = RF_SIZE / sizeof(u32),
        },
@@ -402,12 +393,94 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
        rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110));
        rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
+
+       rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
+
+       rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
+       rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
+       rt2x00pci_register_write(rt2x00dev, CSR11, reg);
+
+       rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
+       rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
+       rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
+       rt2x00pci_register_write(rt2x00dev, CSR18, reg);
+
+       rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
+       rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
+       rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
+       rt2x00pci_register_write(rt2x00dev, CSR19, reg);
 }
 
-static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev,
-                                    const int basic_rate_mask)
+static void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev,
+                                struct antenna_setup *ant)
 {
-       rt2x00pci_register_write(rt2x00dev, ARCSR1, basic_rate_mask);
+       u32 reg;
+       u8 r14;
+       u8 r2;
+
+       /*
+        * We should never come here because rt2x00lib is supposed
+        * to catch this and send us the correct antenna explicitely.
+        */
+       BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
+              ant->tx == ANTENNA_SW_DIVERSITY);
+
+       rt2x00pci_register_read(rt2x00dev, BBPCSR1, &reg);
+       rt2500pci_bbp_read(rt2x00dev, 14, &r14);
+       rt2500pci_bbp_read(rt2x00dev, 2, &r2);
+
+       /*
+        * Configure the TX antenna.
+        */
+       switch (ant->tx) {
+       case ANTENNA_A:
+               rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 0);
+               rt2x00_set_field32(&reg, BBPCSR1_CCK, 0);
+               rt2x00_set_field32(&reg, BBPCSR1_OFDM, 0);
+               break;
+       case ANTENNA_B:
+       default:
+               rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
+               rt2x00_set_field32(&reg, BBPCSR1_CCK, 2);
+               rt2x00_set_field32(&reg, BBPCSR1_OFDM, 2);
+               break;
+       }
+
+       /*
+        * Configure the RX antenna.
+        */
+       switch (ant->rx) {
+       case ANTENNA_A:
+               rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0);
+               break;
+       case ANTENNA_B:
+       default:
+               rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
+               break;
+       }
+
+       /*
+        * RT2525E and RT5222 need to flip TX I/Q
+        */
+       if (rt2x00_rf(&rt2x00dev->chip, RF2525E) ||
+           rt2x00_rf(&rt2x00dev->chip, RF5222)) {
+               rt2x00_set_field8(&r2, BBP_R2_TX_IQ_FLIP, 1);
+               rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 1);
+               rt2x00_set_field32(&reg, BBPCSR1_OFDM_FLIP, 1);
+
+               /*
+                * RT2525E does not need RX I/Q Flip.
+                */
+               if (rt2x00_rf(&rt2x00dev->chip, RF2525E))
+                       rt2x00_set_field8(&r14, BBP_R14_RX_IQ_FLIP, 0);
+       } else {
+               rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 0);
+               rt2x00_set_field32(&reg, BBPCSR1_OFDM_FLIP, 0);
+       }
+
+       rt2x00pci_register_write(rt2x00dev, BBPCSR1, reg);
+       rt2500pci_bbp_write(rt2x00dev, 14, r14);
+       rt2500pci_bbp_write(rt2x00dev, 2, r2);
 }
 
 static void rt2500pci_config_channel(struct rt2x00_dev *rt2x00dev,
@@ -489,76 +562,17 @@ static void rt2500pci_config_txpower(struct rt2x00_dev *rt2x00dev,
        rt2500pci_rf_write(rt2x00dev, 3, rf3);
 }
 
-static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,
-                                    struct antenna_setup *ant)
+static void rt2500pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
+                                        struct rt2x00lib_conf *libconf)
 {
        u32 reg;
-       u8 r14;
-       u8 r2;
 
-       /*
-        * We should never come here because rt2x00lib is supposed
-        * to catch this and send us the correct antenna explicitely.
-        */
-       BUG_ON(ant->rx == ANTENNA_SW_DIVERSITY ||
-              ant->tx == ANTENNA_SW_DIVERSITY);
-
-       rt2x00pci_register_read(rt2x00dev, BBPCSR1, &reg);
-       rt2500pci_bbp_read(rt2x00dev, 14, &r14);
-       rt2500pci_bbp_read(rt2x00dev, 2, &r2);
-
-       /*
-        * Configure the TX antenna.
-        */
-       switch (ant->tx) {
-       case ANTENNA_A:
-               rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 0);
-               rt2x00_set_field32(&reg, BBPCSR1_CCK, 0);
-               rt2x00_set_field32(&reg, BBPCSR1_OFDM, 0);
-               break;
-       case ANTENNA_B:
-       default:
-               rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
-               rt2x00_set_field32(&reg, BBPCSR1_CCK, 2);
-               rt2x00_set_field32(&reg, BBPCSR1_OFDM, 2);
-               break;
-       }
-
-       /*
-        * Configure the RX antenna.
-        */
-       switch (ant->rx) {
-       case ANTENNA_A:
-               rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0);
-               break;
-       case ANTENNA_B:
-       default:
-               rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
-               break;
-       }
-
-       /*
-        * RT2525E and RT5222 need to flip TX I/Q
-        */
-       if (rt2x00_rf(&rt2x00dev->chip, RF2525E) ||
-           rt2x00_rf(&rt2x00dev->chip, RF5222)) {
-               rt2x00_set_field8(&r2, BBP_R2_TX_IQ_FLIP, 1);
-               rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 1);
-               rt2x00_set_field32(&reg, BBPCSR1_OFDM_FLIP, 1);
-
-               /*
-                * RT2525E does not need RX I/Q Flip.
-                */
-               if (rt2x00_rf(&rt2x00dev->chip, RF2525E))
-                       rt2x00_set_field8(&r14, BBP_R14_RX_IQ_FLIP, 0);
-       } else {
-               rt2x00_set_field32(&reg, BBPCSR1_CCK_FLIP, 0);
-               rt2x00_set_field32(&reg, BBPCSR1_OFDM_FLIP, 0);
-       }
-
-       rt2x00pci_register_write(rt2x00dev, BBPCSR1, reg);
-       rt2500pci_bbp_write(rt2x00dev, 14, r14);
-       rt2500pci_bbp_write(rt2x00dev, 2, r2);
+       rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
+       rt2x00_set_field32(&reg, CSR11_LONG_RETRY,
+                          libconf->conf->long_frame_max_tx_count);
+       rt2x00_set_field32(&reg, CSR11_SHORT_RETRY,
+                          libconf->conf->short_frame_max_tx_count);
+       rt2x00pci_register_write(rt2x00dev, CSR11, reg);
 }
 
 static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev,
@@ -566,20 +580,6 @@ static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev,
 {
        u32 reg;
 
-       rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
-       rt2x00_set_field32(&reg, CSR11_SLOT_TIME, libconf->slot_time);
-       rt2x00pci_register_write(rt2x00dev, CSR11, reg);
-
-       rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
-       rt2x00_set_field32(&reg, CSR18_SIFS, libconf->sifs);
-       rt2x00_set_field32(&reg, CSR18_PIFS, libconf->pifs);
-       rt2x00pci_register_write(rt2x00dev, CSR18, reg);
-
-       rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
-       rt2x00_set_field32(&reg, CSR19_DIFS, libconf->difs);
-       rt2x00_set_field32(&reg, CSR19_EIFS, libconf->eifs);
-       rt2x00pci_register_write(rt2x00dev, CSR19, reg);
-
        rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
        rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
        rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
@@ -597,17 +597,16 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev,
                             struct rt2x00lib_conf *libconf,
                             const unsigned int flags)
 {
-       if (flags & CONFIG_UPDATE_PHYMODE)
-               rt2500pci_config_phymode(rt2x00dev, libconf->basic_rates);
-       if (flags & CONFIG_UPDATE_CHANNEL)
+       if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
                rt2500pci_config_channel(rt2x00dev, &libconf->rf,
                                         libconf->conf->power_level);
-       if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL))
+       if ((flags & IEEE80211_CONF_CHANGE_POWER) &&
+           !(flags & IEEE80211_CONF_CHANGE_CHANNEL))
                rt2500pci_config_txpower(rt2x00dev,
                                         libconf->conf->power_level);
-       if (flags & CONFIG_UPDATE_ANTENNA)
-               rt2500pci_config_antenna(rt2x00dev, &libconf->ant);
-       if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
+       if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
+               rt2500pci_config_retry_limit(rt2x00dev, libconf);
+       if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
                rt2500pci_config_duration(rt2x00dev, libconf);
 }
 
@@ -1451,11 +1450,8 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
         */
        mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
        if (!is_valid_ether_addr(mac)) {
-               DECLARE_MAC_BUF(macbuf);
-
                random_ether_addr(mac);
-               EEPROM(rt2x00dev, "MAC: %s\n",
-                      print_mac(macbuf, mac));
+               EEPROM(rt2x00dev, "MAC: %pM\n", mac);
        }
 
        rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
@@ -1830,20 +1826,6 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
 /*
  * IEEE80211 stack callback functions.
  */
-static int rt2500pci_set_retry_limit(struct ieee80211_hw *hw,
-                                    u32 short_retry, u32 long_retry)
-{
-       struct rt2x00_dev *rt2x00dev = hw->priv;
-       u32 reg;
-
-       rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
-       rt2x00_set_field32(&reg, CSR11_LONG_RETRY, long_retry);
-       rt2x00_set_field32(&reg, CSR11_SHORT_RETRY, short_retry);
-       rt2x00pci_register_write(rt2x00dev, CSR11, reg);
-
-       return 0;
-}
-
 static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -1877,7 +1859,6 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
        .config_interface       = rt2x00mac_config_interface,
        .configure_filter       = rt2x00mac_configure_filter,
        .get_stats              = rt2x00mac_get_stats,
-       .set_retry_limit        = rt2500pci_set_retry_limit,
        .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt2x00mac_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
@@ -1905,6 +1886,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
        .config_filter          = rt2500pci_config_filter,
        .config_intf            = rt2500pci_config_intf,
        .config_erp             = rt2500pci_config_erp,
+       .config_ant             = rt2500pci_config_ant,
        .config                 = rt2500pci_config,
 };
 
index 8c26bef6cf49cc23d0eecafe635e20f93b89f052..e135247f7f89d6aae25fefc4bdb7673e54bfc706 100644 (file)
@@ -57,7 +57,9 @@
 #define CSR_REG_SIZE                   0x0174
 #define EEPROM_BASE                    0x0000
 #define EEPROM_SIZE                    0x0200
+#define BBP_BASE                       0x0000
 #define BBP_SIZE                       0x0040
+#define RF_BASE                                0x0000
 #define RF_SIZE                                0x0014
 
 /*
index d3bf7bba611ac02111b05df14a523148648796e5..639d5a2f84e241de460aba6babe686d71355b899 100644 (file)
@@ -245,43 +245,48 @@ rf_write:
 }
 
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
-#define CSR_OFFSET(__word)     ( CSR_REG_BASE + ((__word) * sizeof(u16)) )
-
-static void rt2500usb_read_csr(struct rt2x00_dev *rt2x00dev,
-                              const unsigned int word, u32 *data)
+static void _rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
+                                    const unsigned int offset,
+                                    u32 *value)
 {
-       rt2500usb_register_read(rt2x00dev, CSR_OFFSET(word), (u16 *) data);
+       rt2500usb_register_read(rt2x00dev, offset, (u16 *)value);
 }
 
-static void rt2500usb_write_csr(struct rt2x00_dev *rt2x00dev,
-                               const unsigned int word, u32 data)
+static void _rt2500usb_register_write(struct rt2x00_dev *rt2x00dev,
+                                     const unsigned int offset,
+                                     u32 value)
 {
-       rt2500usb_register_write(rt2x00dev, CSR_OFFSET(word), data);
+       rt2500usb_register_write(rt2x00dev, offset, value);
 }
 
 static const struct rt2x00debug rt2500usb_rt2x00debug = {
        .owner  = THIS_MODULE,
        .csr    = {
-               .read           = rt2500usb_read_csr,
-               .write          = rt2500usb_write_csr,
+               .read           = _rt2500usb_register_read,
+               .write          = _rt2500usb_register_write,
+               .flags          = RT2X00DEBUGFS_OFFSET,
+               .word_base      = CSR_REG_BASE,
                .word_size      = sizeof(u16),
                .word_count     = CSR_REG_SIZE / sizeof(u16),
        },
        .eeprom = {
                .read           = rt2x00_eeprom_read,
                .write          = rt2x00_eeprom_write,
+               .word_base      = EEPROM_BASE,
                .word_size      = sizeof(u16),
                .word_count     = EEPROM_SIZE / sizeof(u16),
        },
        .bbp    = {
                .read           = rt2500usb_bbp_read,
                .write          = rt2500usb_bbp_write,
+               .word_base      = BBP_BASE,
                .word_size      = sizeof(u8),
                .word_count     = BBP_SIZE / sizeof(u8),
        },
        .rf     = {
                .read           = rt2x00_rf_read,
                .write          = rt2500usb_rf_write,
+               .word_base      = RF_BASE,
                .word_size      = sizeof(u32),
                .word_count     = RF_SIZE / sizeof(u32),
        },
@@ -423,57 +428,16 @@ static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field16(&reg, TXRX_CSR10_AUTORESPOND_PREAMBLE,
                           !!erp->short_preamble);
        rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg);
-}
-
-static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev,
-                                    const int basic_rate_mask)
-{
-       rt2500usb_register_write(rt2x00dev, TXRX_CSR11, basic_rate_mask);
-}
 
-static void rt2500usb_config_channel(struct rt2x00_dev *rt2x00dev,
-                                    struct rf_channel *rf, const int txpower)
-{
-       /*
-        * Set TXpower.
-        */
-       rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
+       rt2500usb_register_write(rt2x00dev, TXRX_CSR11, erp->basic_rates);
 
-       /*
-        * For RT2525E we should first set the channel to half band higher.
-        */
-       if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) {
-               static const u32 vals[] = {
-                       0x000008aa, 0x000008ae, 0x000008ae, 0x000008b2,
-                       0x000008b2, 0x000008b6, 0x000008b6, 0x000008ba,
-                       0x000008ba, 0x000008be, 0x000008b7, 0x00000902,
-                       0x00000902, 0x00000906
-               };
-
-               rt2500usb_rf_write(rt2x00dev, 2, vals[rf->channel - 1]);
-               if (rf->rf4)
-                       rt2500usb_rf_write(rt2x00dev, 4, rf->rf4);
-       }
-
-       rt2500usb_rf_write(rt2x00dev, 1, rf->rf1);
-       rt2500usb_rf_write(rt2x00dev, 2, rf->rf2);
-       rt2500usb_rf_write(rt2x00dev, 3, rf->rf3);
-       if (rf->rf4)
-               rt2500usb_rf_write(rt2x00dev, 4, rf->rf4);
-}
-
-static void rt2500usb_config_txpower(struct rt2x00_dev *rt2x00dev,
-                                    const int txpower)
-{
-       u32 rf3;
-
-       rt2x00_rf_read(rt2x00dev, 3, &rf3);
-       rt2x00_set_field32(&rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
-       rt2500usb_rf_write(rt2x00dev, 3, rf3);
+       rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time);
+       rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs);
+       rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs);
 }
 
-static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
-                                    struct antenna_setup *ant)
+static void rt2500usb_config_ant(struct rt2x00_dev *rt2x00dev,
+                                struct antenna_setup *ant)
 {
        u8 r2;
        u8 r14;
@@ -555,15 +519,52 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
        rt2500usb_register_write(rt2x00dev, PHY_CSR6, csr6);
 }
 
+static void rt2500usb_config_channel(struct rt2x00_dev *rt2x00dev,
+                                    struct rf_channel *rf, const int txpower)
+{
+       /*
+        * Set TXpower.
+        */
+       rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
+
+       /*
+        * For RT2525E we should first set the channel to half band higher.
+        */
+       if (rt2x00_rf(&rt2x00dev->chip, RF2525E)) {
+               static const u32 vals[] = {
+                       0x000008aa, 0x000008ae, 0x000008ae, 0x000008b2,
+                       0x000008b2, 0x000008b6, 0x000008b6, 0x000008ba,
+                       0x000008ba, 0x000008be, 0x000008b7, 0x00000902,
+                       0x00000902, 0x00000906
+               };
+
+               rt2500usb_rf_write(rt2x00dev, 2, vals[rf->channel - 1]);
+               if (rf->rf4)
+                       rt2500usb_rf_write(rt2x00dev, 4, rf->rf4);
+       }
+
+       rt2500usb_rf_write(rt2x00dev, 1, rf->rf1);
+       rt2500usb_rf_write(rt2x00dev, 2, rf->rf2);
+       rt2500usb_rf_write(rt2x00dev, 3, rf->rf3);
+       if (rf->rf4)
+               rt2500usb_rf_write(rt2x00dev, 4, rf->rf4);
+}
+
+static void rt2500usb_config_txpower(struct rt2x00_dev *rt2x00dev,
+                                    const int txpower)
+{
+       u32 rf3;
+
+       rt2x00_rf_read(rt2x00dev, 3, &rf3);
+       rt2x00_set_field32(&rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
+       rt2500usb_rf_write(rt2x00dev, 3, rf3);
+}
+
 static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev,
                                      struct rt2x00lib_conf *libconf)
 {
        u16 reg;
 
-       rt2500usb_register_write(rt2x00dev, MAC_CSR10, libconf->slot_time);
-       rt2500usb_register_write(rt2x00dev, MAC_CSR11, libconf->sifs);
-       rt2500usb_register_write(rt2x00dev, MAC_CSR12, libconf->eifs);
-
        rt2500usb_register_read(rt2x00dev, TXRX_CSR18, &reg);
        rt2x00_set_field16(&reg, TXRX_CSR18_INTERVAL,
                           libconf->conf->beacon_int * 4);
@@ -574,17 +575,14 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev,
                             struct rt2x00lib_conf *libconf,
                             const unsigned int flags)
 {
-       if (flags & CONFIG_UPDATE_PHYMODE)
-               rt2500usb_config_phymode(rt2x00dev, libconf->basic_rates);
-       if (flags & CONFIG_UPDATE_CHANNEL)
+       if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
                rt2500usb_config_channel(rt2x00dev, &libconf->rf,
                                         libconf->conf->power_level);
-       if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL))
+       if ((flags & IEEE80211_CONF_CHANGE_POWER) &&
+           !(flags & IEEE80211_CONF_CHANGE_CHANNEL))
                rt2500usb_config_txpower(rt2x00dev,
                                         libconf->conf->power_level);
-       if (flags & CONFIG_UPDATE_ANTENNA)
-               rt2500usb_config_antenna(rt2x00dev, &libconf->ant);
-       if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
+       if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
                rt2500usb_config_duration(rt2x00dev, libconf);
 }
 
@@ -1319,10 +1317,8 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
         */
        mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
        if (!is_valid_ether_addr(mac)) {
-               DECLARE_MAC_BUF(macbuf);
-
                random_ether_addr(mac);
-               EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac));
+               EEPROM(rt2x00dev, "MAC: %pM\n", mac);
        }
 
        rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
@@ -1796,6 +1792,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
        .config_filter          = rt2500usb_config_filter,
        .config_intf            = rt2500usb_config_intf,
        .config_erp             = rt2500usb_config_erp,
+       .config_ant             = rt2500usb_config_ant,
        .config                 = rt2500usb_config,
 };
 
index 89e5ed24e4f7906a95ae0feaacc992e022840e34..dbb5d689e23dd6dc9f13382149e32ab5b2cace87 100644 (file)
@@ -57,7 +57,9 @@
 #define CSR_REG_SIZE                   0x0100
 #define EEPROM_BASE                    0x0000
 #define EEPROM_SIZE                    0x006a
+#define BBP_BASE                       0x0000
 #define BBP_SIZE                       0x0060
+#define RF_BASE                                0x0000
 #define RF_SIZE                                0x0014
 
 /*
index 1359a3768404b89b70e3908f2f297a46d9f30745..f85eedbbad683692eb0ae675d2e612c72ff38c7a 100644 (file)
@@ -44,7 +44,7 @@
 /*
  * Module information.
  */
-#define DRV_VERSION    "2.2.1"
+#define DRV_VERSION    "2.2.2"
 #define DRV_PROJECT    "http://rt2x00.serialmonkey.com"
 
 /*
@@ -347,13 +347,6 @@ struct rt2x00_intf {
         */
        spinlock_t lock;
 
-       /*
-        * BSS configuration. Copied from the structure
-        * passed to us through the bss_info_changed()
-        * callback funtion.
-        */
-       struct ieee80211_bss_conf conf;
-
        /*
         * MAC of the device.
         */
@@ -433,18 +426,6 @@ struct rt2x00lib_conf {
 
        struct rf_channel rf;
        struct channel_info channel;
-
-       struct antenna_setup ant;
-
-       enum ieee80211_band band;
-
-       u32 basic_rates;
-       u32 slot_time;
-
-       short sifs;
-       short pifs;
-       short difs;
-       short eifs;
 };
 
 /*
@@ -456,6 +437,15 @@ struct rt2x00lib_erp {
 
        int ack_timeout;
        int ack_consume_time;
+
+       u64 basic_rates;
+
+       int slot_time;
+
+       short sifs;
+       short pifs;
+       short difs;
+       short eifs;
 };
 
 /*
@@ -589,16 +579,11 @@ struct rt2x00lib_ops {
 
        void (*config_erp) (struct rt2x00_dev *rt2x00dev,
                            struct rt2x00lib_erp *erp);
+       void (*config_ant) (struct rt2x00_dev *rt2x00dev,
+                           struct antenna_setup *ant);
        void (*config) (struct rt2x00_dev *rt2x00dev,
                        struct rt2x00lib_conf *libconf,
-                       const unsigned int flags);
-#define CONFIG_UPDATE_PHYMODE          ( 1 << 1 )
-#define CONFIG_UPDATE_CHANNEL          ( 1 << 2 )
-#define CONFIG_UPDATE_TXPOWER          ( 1 << 3 )
-#define CONFIG_UPDATE_ANTENNA          ( 1 << 4 )
-#define CONFIG_UPDATE_SLOT_TIME        ( 1 << 5 )
-#define CONFIG_UPDATE_BEACON_INT       ( 1 << 6 )
-#define CONFIG_UPDATE_ALL              0xffff
+                       const unsigned int changed_flags);
 };
 
 /*
@@ -997,7 +982,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
                            struct ieee80211_if_init_conf *conf);
 void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
                                struct ieee80211_if_init_conf *conf);
-int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
+int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed);
 int rt2x00mac_config_interface(struct ieee80211_hw *hw,
                               struct ieee80211_vif *vif,
                               struct ieee80211_if_conf *conf);
index 4d5e87b015a079f065acd0f4215ec91a94f37d0e..3e4eee3ab7d2be27c55ceced5d5eaab0d8c19cf2 100644 (file)
@@ -86,13 +86,14 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
        erp.short_preamble = bss_conf->use_short_preamble;
        erp.cts_protection = bss_conf->use_cts_prot;
 
-       erp.ack_timeout = PLCP + get_duration(ACK_SIZE, 10);
-       erp.ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10);
+       erp.slot_time = bss_conf->use_short_slot ? SHORT_SLOT_TIME : SLOT_TIME;
+       erp.sifs = SIFS;
+       erp.pifs = bss_conf->use_short_slot ? SHORT_PIFS : PIFS;
+       erp.difs = bss_conf->use_short_slot ? SHORT_DIFS : DIFS;
+       erp.eifs = bss_conf->use_short_slot ? SHORT_EIFS : EIFS;
 
-       if (rt2x00dev->hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME)
-               erp.ack_timeout += SHORT_DIFS;
-       else
-               erp.ack_timeout += DIFS;
+       erp.ack_timeout = PLCP + erp.difs + get_duration(ACK_SIZE, 10);
+       erp.ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10);
 
        if (bss_conf->use_short_preamble) {
                erp.ack_timeout += SHORT_PREAMBLE;
@@ -102,16 +103,18 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
                erp.ack_consume_time += PREAMBLE;
        }
 
+       erp.basic_rates = bss_conf->basic_rates;
+
        rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp);
 }
 
 void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
                              enum antenna rx, enum antenna tx)
 {
-       struct rt2x00lib_conf libconf;
+       struct antenna_setup ant;
 
-       libconf.ant.rx = rx;
-       libconf.ant.tx = tx;
+       ant.rx = rx;
+       ant.tx = tx;
 
        if (rx == rt2x00dev->link.ant.active.rx &&
            tx == rt2x00dev->link.ant.active.tx)
@@ -129,119 +132,28 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
         * The latter is required since we need to recalibrate the
         * noise-sensitivity ratio for the new setup.
         */
-       rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA);
+       rt2x00dev->ops->lib->config_ant(rt2x00dev, &ant);
+
        rt2x00lib_reset_link_tuner(rt2x00dev);
        rt2x00_reset_link_ant_rssi(&rt2x00dev->link);
 
-       rt2x00dev->link.ant.active.rx = libconf.ant.rx;
-       rt2x00dev->link.ant.active.tx = libconf.ant.tx;
+       memcpy(&rt2x00dev->link.ant.active, &ant, sizeof(ant));
 
        if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
                rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
 }
 
-static u32 rt2x00lib_get_basic_rates(struct ieee80211_supported_band *band)
-{
-       const struct rt2x00_rate *rate;
-       unsigned int i;
-       u32 mask = 0;
-
-       for (i = 0; i < band->n_bitrates; i++) {
-               rate = rt2x00_get_rate(band->bitrates[i].hw_value);
-               if (rate->flags & DEV_RATE_BASIC)
-                       mask |= rate->ratemask;
-       }
-
-       return mask;
-}
-
 void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
-                     struct ieee80211_conf *conf, const int force_config)
+                     struct ieee80211_conf *conf,
+                     unsigned int ieee80211_flags)
 {
        struct rt2x00lib_conf libconf;
-       struct ieee80211_supported_band *band;
-       struct antenna_setup *default_ant = &rt2x00dev->default_ant;
-       struct antenna_setup *active_ant = &rt2x00dev->link.ant.active;
-       int flags = 0;
-       int short_slot_time;
-
-       /*
-        * In some situations we want to force all configurations
-        * to be reloaded (When resuming for instance).
-        */
-       if (force_config) {
-               flags = CONFIG_UPDATE_ALL;
-               goto config;
-       }
-
-       /*
-        * Check which configuration options have been
-        * updated and should be send to the device.
-        */
-       if (rt2x00dev->rx_status.band != conf->channel->band)
-               flags |= CONFIG_UPDATE_PHYMODE;
-       if (rt2x00dev->rx_status.freq != conf->channel->center_freq)
-               flags |= CONFIG_UPDATE_CHANNEL;
-       if (rt2x00dev->tx_power != conf->power_level)
-               flags |= CONFIG_UPDATE_TXPOWER;
-
-       /*
-        * Determining changes in the antenna setups request several checks:
-        * antenna_sel_{r,t}x = 0
-        *    -> Does active_{r,t}x match default_{r,t}x
-        *    -> Is default_{r,t}x SW_DIVERSITY
-        * antenna_sel_{r,t}x = 1/2
-        *    -> Does active_{r,t}x match antenna_sel_{r,t}x
-        * The reason for not updating the antenna while SW diversity
-        * should be used is simple: Software diversity means that
-        * we should switch between the antenna's based on the
-        * quality. This means that the current antenna is good enough
-        * to work with untill the link tuner decides that an antenna
-        * switch should be performed.
-        */
-       if (!conf->antenna_sel_rx &&
-           default_ant->rx != ANTENNA_SW_DIVERSITY &&
-           default_ant->rx != active_ant->rx)
-               flags |= CONFIG_UPDATE_ANTENNA;
-       else if (conf->antenna_sel_rx &&
-                conf->antenna_sel_rx != active_ant->rx)
-               flags |= CONFIG_UPDATE_ANTENNA;
-       else if (active_ant->rx == ANTENNA_SW_DIVERSITY)
-               flags |= CONFIG_UPDATE_ANTENNA;
-
-       if (!conf->antenna_sel_tx &&
-           default_ant->tx != ANTENNA_SW_DIVERSITY &&
-           default_ant->tx != active_ant->tx)
-               flags |= CONFIG_UPDATE_ANTENNA;
-       else if (conf->antenna_sel_tx &&
-                conf->antenna_sel_tx != active_ant->tx)
-               flags |= CONFIG_UPDATE_ANTENNA;
-       else if (active_ant->tx == ANTENNA_SW_DIVERSITY)
-               flags |= CONFIG_UPDATE_ANTENNA;
 
-       /*
-        * The following configuration options are never
-        * stored anywhere and will always be updated.
-        */
-       flags |= CONFIG_UPDATE_SLOT_TIME;
-       flags |= CONFIG_UPDATE_BEACON_INT;
-
-       /*
-        * We have determined what options should be updated,
-        * now precalculate device configuration values depending
-        * on what configuration options need to be updated.
-        */
-config:
        memset(&libconf, 0, sizeof(libconf));
 
-       if (flags & CONFIG_UPDATE_PHYMODE) {
-               band = &rt2x00dev->bands[conf->channel->band];
-
-               libconf.band = conf->channel->band;
-               libconf.basic_rates = rt2x00lib_get_basic_rates(band);
-       }
+       libconf.conf = conf;
 
-       if (flags & CONFIG_UPDATE_CHANNEL) {
+       if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) {
                memcpy(&libconf.rf,
                       &rt2x00dev->spec.channels[conf->channel->hw_value],
                       sizeof(libconf.rf));
@@ -251,61 +163,21 @@ config:
                       sizeof(libconf.channel));
        }
 
-       if (flags & CONFIG_UPDATE_ANTENNA) {
-               if (conf->antenna_sel_rx)
-                       libconf.ant.rx = conf->antenna_sel_rx;
-               else if (default_ant->rx != ANTENNA_SW_DIVERSITY)
-                       libconf.ant.rx = default_ant->rx;
-               else if (active_ant->rx == ANTENNA_SW_DIVERSITY)
-                       libconf.ant.rx = ANTENNA_B;
-               else
-                       libconf.ant.rx = active_ant->rx;
-
-               if (conf->antenna_sel_tx)
-                       libconf.ant.tx = conf->antenna_sel_tx;
-               else if (default_ant->tx != ANTENNA_SW_DIVERSITY)
-                       libconf.ant.tx = default_ant->tx;
-               else if (active_ant->tx == ANTENNA_SW_DIVERSITY)
-                       libconf.ant.tx = ANTENNA_B;
-               else
-                       libconf.ant.tx = active_ant->tx;
-       }
-
-       if (flags & CONFIG_UPDATE_SLOT_TIME) {
-               short_slot_time = conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME;
-
-               libconf.slot_time =
-                   short_slot_time ? SHORT_SLOT_TIME : SLOT_TIME;
-               libconf.sifs = SIFS;
-               libconf.pifs = short_slot_time ? SHORT_PIFS : PIFS;
-               libconf.difs = short_slot_time ? SHORT_DIFS : DIFS;
-               libconf.eifs = short_slot_time ? SHORT_EIFS : EIFS;
-       }
-
-       libconf.conf = conf;
-
        /*
         * Start configuration.
         */
-       rt2x00dev->ops->lib->config(rt2x00dev, &libconf, flags);
+       rt2x00dev->ops->lib->config(rt2x00dev, &libconf, ieee80211_flags);
 
        /*
         * Some configuration changes affect the link quality
         * which means we need to reset the link tuner.
         */
-       if (flags & (CONFIG_UPDATE_CHANNEL | CONFIG_UPDATE_ANTENNA))
+       if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL)
                rt2x00lib_reset_link_tuner(rt2x00dev);
 
-       if (flags & CONFIG_UPDATE_PHYMODE) {
-               rt2x00dev->curr_band = conf->channel->band;
-               rt2x00dev->rx_status.band = conf->channel->band;
-       }
-
-       rt2x00dev->rx_status.freq = conf->channel->center_freq;
+       rt2x00dev->curr_band = conf->channel->band;
        rt2x00dev->tx_power = conf->power_level;
 
-       if (flags & CONFIG_UPDATE_ANTENNA) {
-               rt2x00dev->link.ant.active.rx = libconf.ant.rx;
-               rt2x00dev->link.ant.active.tx = libconf.ant.tx;
-       }
+       rt2x00dev->rx_status.band = conf->channel->band;
+       rt2x00dev->rx_status.freq = conf->channel->center_freq;
 }
index 5cf4c859e39d741ec6dfe4595523065ee25e5125..54dd10060bf1a56a8b318ee5e135463b796cc358 100644 (file)
@@ -285,7 +285,7 @@ exit:
 }
 
 static unsigned int rt2x00debug_poll_queue_dump(struct file *file,
-                                               poll_table *wait)
+                                               poll_table *wait)
 {
        struct rt2x00debug_intf *intf = file->private_data;
 
@@ -377,7 +377,7 @@ static ssize_t rt2x00debug_read_crypto_stats(struct file *file,
        if (*offset)
                return 0;
 
-       data = kzalloc((1 + CIPHER_MAX)* MAX_LINE_LENGTH, GFP_KERNEL);
+       data = kzalloc((1 + CIPHER_MAX) * MAX_LINE_LENGTH, GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
@@ -424,16 +424,21 @@ static ssize_t rt2x00debug_read_##__name(struct file *file,       \
        const struct rt2x00debug *debug = intf->debug;          \
        char line[16];                                          \
        size_t size;                                            \
+       unsigned int index = intf->offset_##__name;             \
        __type value;                                           \
                                                                \
        if (*offset)                                            \
                return 0;                                       \
                                                                \
-       if (intf->offset_##__name >= debug->__name.word_count)  \
+       if (index >= debug->__name.word_count)                  \
                return -EINVAL;                                 \
                                                                \
-       debug->__name.read(intf->rt2x00dev,                     \
-                          intf->offset_##__name, &value);      \
+       if (debug->__name.flags & RT2X00DEBUGFS_OFFSET)         \
+               index *= debug->__name.word_size;               \
+                                                               \
+       index += debug->__name.word_base;                       \
+                                                               \
+       debug->__name.read(intf->rt2x00dev, index, &value);     \
                                                                \
        size = sprintf(line, __format, value);                  \
                                                                \
@@ -454,12 +459,13 @@ static ssize_t rt2x00debug_write_##__name(struct file *file,      \
        const struct rt2x00debug *debug = intf->debug;          \
        char line[16];                                          \
        size_t size;                                            \
+       unsigned int index = intf->offset_##__name;             \
        __type value;                                           \
                                                                \
        if (*offset)                                            \
                return 0;                                       \
                                                                \
-       if (intf->offset_##__name >= debug->__name.word_count)  \
+       if (index >= debug->__name.word_count)                  \
                return -EINVAL;                                 \
                                                                \
        if (copy_from_user(line, buf, length))                  \
@@ -468,8 +474,12 @@ static ssize_t rt2x00debug_write_##__name(struct file *file,       \
        size = strlen(line);                                    \
        value = simple_strtoul(line, NULL, 0);                  \
                                                                \
-       debug->__name.write(intf->rt2x00dev,                    \
-                           intf->offset_##__name, value);      \
+       if (debug->__name.flags & RT2X00DEBUGFS_OFFSET)         \
+               index *= debug->__name.word_size;               \
+                                                               \
+       index += debug->__name.word_base;                       \
+                                                               \
+       debug->__name.write(intf->rt2x00dev, index, value);     \
                                                                \
        *offset += size;                                        \
        return size;                                            \
@@ -587,29 +597,29 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
        intf->driver_folder =
            debugfs_create_dir(intf->rt2x00dev->ops->name,
                               rt2x00dev->hw->wiphy->debugfsdir);
-       if (IS_ERR(intf->driver_folder))
+       if (IS_ERR(intf->driver_folder) || !intf->driver_folder)
                goto exit;
 
        intf->driver_entry =
            rt2x00debug_create_file_driver("driver", intf, &intf->driver_blob);
-       if (IS_ERR(intf->driver_entry))
+       if (IS_ERR(intf->driver_entry) || !intf->driver_entry)
                goto exit;
 
        intf->chipset_entry =
            rt2x00debug_create_file_chipset("chipset",
                                            intf, &intf->chipset_blob);
-       if (IS_ERR(intf->chipset_entry))
+       if (IS_ERR(intf->chipset_entry) || !intf->chipset_entry)
                goto exit;
 
        intf->dev_flags = debugfs_create_file("dev_flags", S_IRUSR,
                                              intf->driver_folder, intf,
                                              &rt2x00debug_fop_dev_flags);
-       if (IS_ERR(intf->dev_flags))
+       if (IS_ERR(intf->dev_flags) || !intf->dev_flags)
                goto exit;
 
        intf->register_folder =
            debugfs_create_dir("register", intf->driver_folder);
-       if (IS_ERR(intf->register_folder))
+       if (IS_ERR(intf->register_folder) || !intf->register_folder)
                goto exit;
 
 #define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name)    \
@@ -619,7 +629,8 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
                               S_IRUSR | S_IWUSR,               \
                               (__intf)->register_folder,       \
                               &(__intf)->offset_##__name);     \
-       if (IS_ERR((__intf)->__name##_off_entry))               \
+       if (IS_ERR((__intf)->__name##_off_entry)                \
+                       || !(__intf)->__name##_off_entry)       \
                goto exit;                                      \
                                                                \
        (__intf)->__name##_val_entry =                          \
@@ -627,7 +638,8 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
                                S_IRUSR | S_IWUSR,              \
                                (__intf)->register_folder,      \
                                (__intf), &rt2x00debug_fop_##__name);\
-       if (IS_ERR((__intf)->__name##_val_entry))               \
+       if (IS_ERR((__intf)->__name##_val_entry)                \
+                       || !(__intf)->__name##_val_entry)       \
                goto exit;                                      \
 })
 
@@ -640,13 +652,14 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
 
        intf->queue_folder =
            debugfs_create_dir("queue", intf->driver_folder);
-       if (IS_ERR(intf->queue_folder))
+       if (IS_ERR(intf->queue_folder) || !intf->queue_folder)
                goto exit;
 
        intf->queue_frame_dump_entry =
            debugfs_create_file("dump", S_IRUSR, intf->queue_folder,
                                intf, &rt2x00debug_fop_queue_dump);
-       if (IS_ERR(intf->queue_frame_dump_entry))
+       if (IS_ERR(intf->queue_frame_dump_entry)
+               || !intf->queue_frame_dump_entry)
                goto exit;
 
        skb_queue_head_init(&intf->frame_dump_skbqueue);
index c4ce895aa1c70776100b66536fe54064d2368125..a92104dfee9a6836d90b7ee2270b3c407fc873e8 100644 (file)
 
 struct rt2x00_dev;
 
+/**
+ * enum rt2x00debugfs_entry_flags: Flags for debugfs registry entry
+ *
+ * @RT2X00DEBUGFS_OFFSET: rt2x00lib should pass the register offset
+ *     as argument when using the callback function read()/write()
+ */
+enum rt2x00debugfs_entry_flags {
+       RT2X00DEBUGFS_OFFSET    = (1 << 0),
+};
+
 #define RT2X00DEBUGFS_REGISTER_ENTRY(__name, __type)           \
 struct reg##__name {                                           \
        void (*read)(struct rt2x00_dev *rt2x00dev,              \
@@ -35,6 +45,9 @@ struct reg##__name {                                          \
        void (*write)(struct rt2x00_dev *rt2x00dev,             \
                      const unsigned int word, __type data);    \
                                                                \
+       unsigned int flags;                                     \
+                                                               \
+       unsigned int word_base;                                 \
        unsigned int word_size;                                 \
        unsigned int word_count;                                \
 } __name
index 86840e3585e82e7825072641f112a679434e4c0a..477a944167c47f1d9370d4843bf7c01f12ccc5ae 100644 (file)
@@ -249,11 +249,9 @@ static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev)
        rt2x00dev->link.ant.flags &= ~ANTENNA_RX_DIVERSITY;
        rt2x00dev->link.ant.flags &= ~ANTENNA_TX_DIVERSITY;
 
-       if (rt2x00dev->hw->conf.antenna_sel_rx == 0 &&
-           rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
+       if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
                rt2x00dev->link.ant.flags |= ANTENNA_RX_DIVERSITY;
-       if (rt2x00dev->hw->conf.antenna_sel_tx == 0 &&
-           rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
+       if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
                rt2x00dev->link.ant.flags |= ANTENNA_TX_DIVERSITY;
 
        if (!(rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) &&
@@ -419,7 +417,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
         */
        spin_lock(&intf->lock);
 
-       memcpy(&conf, &intf->conf, sizeof(conf));
+       memcpy(&conf, &vif->bss_conf, sizeof(conf));
        delayed_flags = intf->delayed_flags;
        intf->delayed_flags = 0;
 
@@ -500,7 +498,9 @@ void rt2x00lib_txdone(struct queue_entry *entry,
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
        enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
+       u8 rate_idx, rate_flags;
 
        /*
         * Unmap the skb.
@@ -530,14 +530,18 @@ void rt2x00lib_txdone(struct queue_entry *entry,
        rt2x00dev->link.qual.tx_failed +=
            test_bit(TXDONE_FAILURE, &txdesc->flags);
 
+       rate_idx = skbdesc->tx_rate_idx;
+       rate_flags = skbdesc->tx_rate_flags;
+
        /*
         * Initialize TX status
         */
        memset(&tx_info->status, 0, sizeof(tx_info->status));
        tx_info->status.ack_signal = 0;
-       tx_info->status.excessive_retries =
-           test_bit(TXDONE_EXCESSIVE_RETRY, &txdesc->flags);
-       tx_info->status.retry_count = txdesc->retry;
+       tx_info->status.rates[0].idx = rate_idx;
+       tx_info->status.rates[0].flags = rate_flags;
+       tx_info->status.rates[0].count = txdesc->retry + 1;
+       tx_info->status.rates[1].idx = -1; /* terminate */
 
        if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
                if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
@@ -546,7 +550,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
                        rt2x00dev->low_level_stats.dot11ACKFailureCount++;
        }
 
-       if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
+       if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
                if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
                        rt2x00dev->low_level_stats.dot11RTSSuccessCount++;
                else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
@@ -1052,10 +1056,16 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
         */
        rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf);
 
-       rt2x00dev->hw->wiphy->interface_modes =
-           BIT(NL80211_IFTYPE_AP) |
-           BIT(NL80211_IFTYPE_STATION) |
-           BIT(NL80211_IFTYPE_ADHOC);
+       /*
+        * Determine which operating modes are supported, all modes
+        * which require beaconing, depend on the availability of
+        * beacon entries.
+        */
+       rt2x00dev->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+       if (rt2x00dev->ops->bcn->entry_num > 0)
+               rt2x00dev->hw->wiphy->interface_modes |=
+                   BIT(NL80211_IFTYPE_ADHOC) |
+                   BIT(NL80211_IFTYPE_AP);
 
        /*
         * Let the driver probe the device to detect the capabilities.
@@ -1247,7 +1257,7 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
        /*
         * Reconfigure device.
         */
-       retval = rt2x00mac_config(rt2x00dev->hw, &rt2x00dev->hw->conf);
+       retval = rt2x00mac_config(rt2x00dev->hw, ~0);
        if (retval)
                goto exit;
 
index 797eb619aa0af918d9591fc56a9b4281448720b0..9f214f89ba6d7afcc04047ddcdec54131d9c887f 100644 (file)
@@ -96,7 +96,8 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
 void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
                              enum antenna rx, enum antenna tx);
 void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
-                     struct ieee80211_conf *conf, const int force_config);
+                     struct ieee80211_conf *conf,
+                     const unsigned int changed_flags);
 
 /**
  * DOC: Queue handlers
index 2c6cc5c374ff3be765b681e07d17fede815a3d22..8fc2315c59637d427cd8397c83dbeb4e5d71937c 100644 (file)
@@ -39,7 +39,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
        unsigned int data_length;
        int retval = 0;
 
-       if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
+       if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
                data_length = sizeof(struct ieee80211_cts);
        else
                data_length = sizeof(struct ieee80211_rts);
@@ -64,11 +64,11 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
         */
        memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb));
        rts_info = IEEE80211_SKB_CB(skb);
-       rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS;
-       rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT;
+       rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_RTS_CTS;
+       rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_CTS_PROTECT;
        rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS;
 
-       if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
+       if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
                rts_info->flags |= IEEE80211_TX_CTL_NO_ACK;
        else
                rts_info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
@@ -84,7 +84,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
                data_length += rt2x00crypto_tx_overhead(tx_info);
 #endif /* CONFIG_RT2X00_LIB_CRYPTO */
 
-       if (tx_info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
+       if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
                ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif,
                                        frag_skb->data, data_length, tx_info,
                                        (struct ieee80211_cts *)(skb->data));
@@ -146,8 +146,8 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
         * inside the hardware.
         */
        frame_control = le16_to_cpu(ieee80211hdr->frame_control);
-       if ((tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS |
-                              IEEE80211_TX_CTL_USE_CTS_PROTECT)) &&
+       if ((tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS |
+                                               IEEE80211_TX_RC_USE_CTS_PROTECT)) &&
            !rt2x00dev->ops->hw->set_rts_threshold) {
                if (rt2x00queue_available(queue) <= 1)
                        goto exit_fail;
@@ -335,9 +335,10 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface);
 
-int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
+       struct ieee80211_conf *conf = &hw->conf;
        int radio_on;
        int status;
 
@@ -369,7 +370,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
                 * When we've just turned on the radio, we want to reprogram
                 * everything to ensure a consistent state
                 */
-               rt2x00lib_config(rt2x00dev, conf, !radio_on);
+               rt2x00lib_config(rt2x00dev, conf, changed);
 
                /* Turn RX back on */
                rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
@@ -633,7 +634,6 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
        }
 
        spin_lock(&intf->lock);
-       memcpy(&intf->conf, bss_conf, sizeof(*bss_conf));
        if (delayed) {
                intf->delayed_flags |= delayed;
                schedule_work(&rt2x00dev->intf_work);
index adf2876ed8ab77de00d5c3676b781d4c62edeabf..62449da577e525dfc3617eb0c34b3c12d576e5ef 100644 (file)
@@ -222,8 +222,7 @@ static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev)
 {
        struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev);
 
-       rt2x00dev->csr.base = ioremap(pci_resource_start(pci_dev, 0),
-                                     pci_resource_len(pci_dev, 0));
+       rt2x00dev->csr.base = pci_ioremap_bar(pci_dev, 0);
        if (!rt2x00dev->csr.base)
                goto exit;
 
index 80bf97c03e2d159395f46d9933db3be0275948c8..a83f45f784f28274fa7664e8bcb1d303a27357a0 100644 (file)
@@ -58,7 +58,7 @@
  * Register access.
  */
 static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
-                                          const unsigned long offset,
+                                          const unsigned int offset,
                                           u32 *value)
 {
        *value = readl(rt2x00dev->csr.base + offset);
@@ -66,14 +66,14 @@ static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
 
 static inline void
 rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev,
-                            const unsigned long offset,
+                            const unsigned int offset,
                             void *value, const u16 length)
 {
        memcpy_fromio(value, rt2x00dev->csr.base + offset, length);
 }
 
 static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev,
-                                           const unsigned long offset,
+                                           const unsigned int offset,
                                            u32 value)
 {
        writel(value, rt2x00dev->csr.base + offset);
@@ -81,7 +81,7 @@ static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev,
 
 static inline void
 rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
-                             const unsigned long offset,
+                             const unsigned int offset,
                              const void *value, const u16 length)
 {
        memcpy_toio(rt2x00dev->csr.base + offset, value, length);
index 451d410ecdae4fae126ab835bdadd5647a4f13b8..e9f4261054bc905daf474357519cb0be5ea78361 100644 (file)
@@ -230,8 +230,15 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
        /*
         * Determine retry information.
         */
-       txdesc->retry_limit = tx_info->control.retry_limit;
-       if (tx_info->flags & IEEE80211_TX_CTL_LONG_RETRY_LIMIT)
+       txdesc->retry_limit = tx_info->control.rates[0].count - 1;
+       /*
+        * XXX: If at this point we knew whether the HW is going to use
+        *      the RETRY_MODE bit or the retry_limit (currently all
+        *      use the RETRY_MODE bit) we could do something like b43
+        *      does, set the RETRY_MODE bit when the RC algorithm is
+        *      requesting more than the long retry limit.
+        */
+       if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
                __set_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags);
 
        /*
@@ -371,10 +378,12 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
 
 int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
 {
+       struct ieee80211_tx_info *tx_info;
        struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
        struct txentry_desc txdesc;
        struct skb_frame_desc *skbdesc;
        unsigned int iv_len = 0;
+       u8 rate_idx, rate_flags;
 
        if (unlikely(rt2x00queue_full(queue)))
                return -EINVAL;
@@ -399,13 +408,18 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
                iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
 
        /*
-        * All information is retreived from the skb->cb array,
+        * All information is retrieved from the skb->cb array,
         * now we should claim ownership of the driver part of that
-        * array.
+        * array, preserving the bitrate index and flags.
         */
+       tx_info = IEEE80211_SKB_CB(skb);
+       rate_idx = tx_info->control.rates[0].idx;
+       rate_flags = tx_info->control.rates[0].flags;
        skbdesc = get_skb_frame_desc(entry->skb);
        memset(skbdesc, 0, sizeof(*skbdesc));
        skbdesc->entry = entry;
+       skbdesc->tx_rate_idx = rate_idx;
+       skbdesc->tx_rate_flags = rate_flags;
 
        /*
         * When hardware encryption is supported, and this frame
@@ -556,7 +570,7 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
                queue->length++;
        } else if (index == Q_INDEX_DONE) {
                queue->length--;
-               queue->count ++;
+               queue->count++;
        }
 
        spin_unlock_irqrestore(&queue->lock, irqflags);
index 9dbf04f0f04c1ceeae6ac10f0789aec9eb649a95..4d3c7246f9aed105892204164e72ac315aa8aa0e 100644 (file)
@@ -104,6 +104,8 @@ enum skb_frame_desc_flags {
  *
  * @flags: Frame flags, see &enum skb_frame_desc_flags.
  * @desc_len: Length of the frame descriptor.
+ * @tx_rate_idx: the index of the TX rate, used for TX status reporting
+ * @tx_rate_flags: the TX rate flags, used for TX status reporting
  * @desc: Pointer to descriptor part of the frame.
  *     Note that this pointer could point to something outside
  *     of the scope of the skb->data pointer.
@@ -113,9 +115,12 @@ enum skb_frame_desc_flags {
  * @entry: The entry to which this sk buffer belongs.
  */
 struct skb_frame_desc {
-       unsigned int flags;
+       u8 flags;
+
+       u8 desc_len;
+       u8 tx_rate_idx;
+       u8 tx_rate_flags;
 
-       unsigned int desc_len;
        void *desc;
 
        __le32 iv;
index a461620b489f0350536bb06148e2813c609ea77f..3f272793412a6d8bc47f093af8ca5d5c40d01bfe 100644 (file)
@@ -228,43 +228,34 @@ static void rt61pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
 }
 
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
-#define CSR_OFFSET(__word)     ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
-
-static void rt61pci_read_csr(struct rt2x00_dev *rt2x00dev,
-                            const unsigned int word, u32 *data)
-{
-       rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data);
-}
-
-static void rt61pci_write_csr(struct rt2x00_dev *rt2x00dev,
-                             const unsigned int word, u32 data)
-{
-       rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data);
-}
-
 static const struct rt2x00debug rt61pci_rt2x00debug = {
        .owner  = THIS_MODULE,
        .csr    = {
-               .read           = rt61pci_read_csr,
-               .write          = rt61pci_write_csr,
+               .read           = rt2x00pci_register_read,
+               .write          = rt2x00pci_register_write,
+               .flags          = RT2X00DEBUGFS_OFFSET,
+               .word_base      = CSR_REG_BASE,
                .word_size      = sizeof(u32),
                .word_count     = CSR_REG_SIZE / sizeof(u32),
        },
        .eeprom = {
                .read           = rt2x00_eeprom_read,
                .write          = rt2x00_eeprom_write,
+               .word_base      = EEPROM_BASE,
                .word_size      = sizeof(u16),
                .word_count     = EEPROM_SIZE / sizeof(u16),
        },
        .bbp    = {
                .read           = rt61pci_bbp_read,
                .write          = rt61pci_bbp_write,
+               .word_base      = BBP_BASE,
                .word_size      = sizeof(u8),
                .word_count     = BBP_SIZE / sizeof(u8),
        },
        .rf     = {
                .read           = rt2x00_rf_read,
                .write          = rt61pci_rf_write,
+               .word_base      = RF_BASE,
                .word_size      = sizeof(u32),
                .word_count     = RF_SIZE / sizeof(u32),
        },
@@ -643,95 +634,18 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
                           !!erp->short_preamble);
        rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
-}
-
-
-static void rt61pci_config_lna_gain(struct rt2x00_dev *rt2x00dev,
-                                   struct rt2x00lib_conf *libconf)
-{
-       u16 eeprom;
-       short lna_gain = 0;
-
-       if (libconf->band == IEEE80211_BAND_2GHZ) {
-               if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
-                       lna_gain += 14;
-
-               rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
-               lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1);
-       } else {
-               if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
-                       lna_gain += 14;
-
-               rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom);
-               lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1);
-       }
-
-       rt2x00dev->lna_gain = lna_gain;
-}
-
-static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev,
-                                  const int basic_rate_mask)
-{
-       rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, basic_rate_mask);
-}
-
-static void rt61pci_config_channel(struct rt2x00_dev *rt2x00dev,
-                                  struct rf_channel *rf, const int txpower)
-{
-       u8 r3;
-       u8 r94;
-       u8 smart;
-
-       rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
-       rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
-
-       smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-                 rt2x00_rf(&rt2x00dev->chip, RF2527));
-
-       rt61pci_bbp_read(rt2x00dev, 3, &r3);
-       rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
-       rt61pci_bbp_write(rt2x00dev, 3, r3);
-
-       r94 = 6;
-       if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94))
-               r94 += txpower - MAX_TXPOWER;
-       else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94))
-               r94 += txpower;
-       rt61pci_bbp_write(rt2x00dev, 94, r94);
-
-       rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
-       rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
-       rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
-       rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
-
-       udelay(200);
-
-       rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
-       rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
-       rt61pci_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
-       rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
-
-       udelay(200);
-
-       rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
-       rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
-       rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
-       rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
 
-       msleep(1);
-}
+       rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
 
-static void rt61pci_config_txpower(struct rt2x00_dev *rt2x00dev,
-                                  const int txpower)
-{
-       struct rf_channel rf;
-
-       rt2x00_rf_read(rt2x00dev, 1, &rf.rf1);
-       rt2x00_rf_read(rt2x00dev, 2, &rf.rf2);
-       rt2x00_rf_read(rt2x00dev, 3, &rf.rf3);
-       rt2x00_rf_read(rt2x00dev, 4, &rf.rf4);
+       rt2x00pci_register_read(rt2x00dev, MAC_CSR9, &reg);
+       rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
+       rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg);
 
-       rt61pci_config_channel(rt2x00dev, &rf, txpower);
+       rt2x00pci_register_read(rt2x00dev, MAC_CSR8, &reg);
+       rt2x00_set_field32(&reg, MAC_CSR8_SIFS, erp->sifs);
+       rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
+       rt2x00_set_field32(&reg, MAC_CSR8_EIFS, erp->eifs);
+       rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg);
 }
 
 static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
@@ -906,8 +820,8 @@ static const struct antenna_sel antenna_sel_bg[] = {
        { 98,  { 0x48, 0x48 } },
 };
 
-static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
-                                  struct antenna_setup *ant)
+static void rt61pci_config_ant(struct rt2x00_dev *rt2x00dev,
+                              struct antenna_setup *ant)
 {
        const struct antenna_sel *sel;
        unsigned int lna;
@@ -954,20 +868,105 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
        }
 }
 
-static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev,
+static void rt61pci_config_lna_gain(struct rt2x00_dev *rt2x00dev,
+                                   struct rt2x00lib_conf *libconf)
+{
+       u16 eeprom;
+       short lna_gain = 0;
+
+       if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) {
+               if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
+                       lna_gain += 14;
+
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
+               lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1);
+       } else {
+               if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
+                       lna_gain += 14;
+
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom);
+               lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1);
+       }
+
+       rt2x00dev->lna_gain = lna_gain;
+}
+
+static void rt61pci_config_channel(struct rt2x00_dev *rt2x00dev,
+                                  struct rf_channel *rf, const int txpower)
+{
+       u8 r3;
+       u8 r94;
+       u8 smart;
+
+       rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
+       rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
+
+       smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
+                 rt2x00_rf(&rt2x00dev->chip, RF2527));
+
+       rt61pci_bbp_read(rt2x00dev, 3, &r3);
+       rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
+       rt61pci_bbp_write(rt2x00dev, 3, r3);
+
+       r94 = 6;
+       if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94))
+               r94 += txpower - MAX_TXPOWER;
+       else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94))
+               r94 += txpower;
+       rt61pci_bbp_write(rt2x00dev, 94, r94);
+
+       rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
+       rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
+       rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+       rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
+
+       udelay(200);
+
+       rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
+       rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
+       rt61pci_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
+       rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
+
+       udelay(200);
+
+       rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
+       rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
+       rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+       rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
+
+       msleep(1);
+}
+
+static void rt61pci_config_txpower(struct rt2x00_dev *rt2x00dev,
+                                  const int txpower)
+{
+       struct rf_channel rf;
+
+       rt2x00_rf_read(rt2x00dev, 1, &rf.rf1);
+       rt2x00_rf_read(rt2x00dev, 2, &rf.rf2);
+       rt2x00_rf_read(rt2x00dev, 3, &rf.rf3);
+       rt2x00_rf_read(rt2x00dev, 4, &rf.rf4);
+
+       rt61pci_config_channel(rt2x00dev, &rf, txpower);
+}
+
+static void rt61pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
                                    struct rt2x00lib_conf *libconf)
 {
        u32 reg;
 
-       rt2x00pci_register_read(rt2x00dev, MAC_CSR9, &reg);
-       rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, libconf->slot_time);
-       rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg);
+       rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg);
+       rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT,
+                          libconf->conf->long_frame_max_tx_count);
+       rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT,
+                          libconf->conf->short_frame_max_tx_count);
+       rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
+}
 
-       rt2x00pci_register_read(rt2x00dev, MAC_CSR8, &reg);
-       rt2x00_set_field32(&reg, MAC_CSR8_SIFS, libconf->sifs);
-       rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
-       rt2x00_set_field32(&reg, MAC_CSR8_EIFS, libconf->eifs);
-       rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg);
+static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev,
+                                   struct rt2x00lib_conf *libconf)
+{
+       u32 reg;
 
        rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
@@ -990,16 +989,15 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
        /* Always recalculate LNA gain before changing configuration */
        rt61pci_config_lna_gain(rt2x00dev, libconf);
 
-       if (flags & CONFIG_UPDATE_PHYMODE)
-               rt61pci_config_phymode(rt2x00dev, libconf->basic_rates);
-       if (flags & CONFIG_UPDATE_CHANNEL)
+       if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
                rt61pci_config_channel(rt2x00dev, &libconf->rf,
                                       libconf->conf->power_level);
-       if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL))
+       if ((flags & IEEE80211_CONF_CHANGE_POWER) &&
+           !(flags & IEEE80211_CONF_CHANGE_CHANNEL))
                rt61pci_config_txpower(rt2x00dev, libconf->conf->power_level);
-       if (flags & CONFIG_UPDATE_ANTENNA)
-               rt61pci_config_antenna(rt2x00dev, &libconf->ant);
-       if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
+       if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
+               rt61pci_config_retry_limit(rt2x00dev, libconf);
+       if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
                rt61pci_config_duration(rt2x00dev, libconf);
 }
 
@@ -1934,7 +1932,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
 }
 
 static void rt61pci_fill_rxdone(struct queue_entry *entry,
-                               struct rxdone_entry_desc *rxdesc)
+                               struct rxdone_entry_desc *rxdesc)
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct queue_entry_priv_pci *entry_priv = entry->priv_data;
@@ -2175,10 +2173,8 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
         */
        mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
        if (!is_valid_ether_addr(mac)) {
-               DECLARE_MAC_BUF(macbuf);
-
                random_ether_addr(mac);
-               EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac));
+               EEPROM(rt2x00dev, "MAC: %pM\n", mac);
        }
 
        rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
@@ -2630,20 +2626,6 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
 /*
  * IEEE80211 stack callback functions.
  */
-static int rt61pci_set_retry_limit(struct ieee80211_hw *hw,
-                                  u32 short_retry, u32 long_retry)
-{
-       struct rt2x00_dev *rt2x00dev = hw->priv;
-       u32 reg;
-
-       rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT, long_retry);
-       rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT, short_retry);
-       rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
-
-       return 0;
-}
-
 static int rt61pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
                           const struct ieee80211_tx_queue_params *params)
 {
@@ -2726,7 +2708,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
        .configure_filter       = rt2x00mac_configure_filter,
        .set_key                = rt2x00mac_set_key,
        .get_stats              = rt2x00mac_get_stats,
-       .set_retry_limit        = rt61pci_set_retry_limit,
        .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt61pci_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
@@ -2758,6 +2739,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
        .config_filter          = rt61pci_config_filter,
        .config_intf            = rt61pci_config_intf,
        .config_erp             = rt61pci_config_erp,
+       .config_ant             = rt61pci_config_ant,
        .config                 = rt61pci_config,
 };
 
index 8ec1451308ccea2700ce05e03f0be2229a3c2779..65fe3332364aa8cb414793ec0f0a057e40038252 100644 (file)
@@ -48,7 +48,9 @@
 #define CSR_REG_SIZE                   0x04b0
 #define EEPROM_BASE                    0x0000
 #define EEPROM_SIZE                    0x0100
+#define BBP_BASE                       0x0000
 #define BBP_SIZE                       0x0080
+#define RF_BASE                                0x0000
 #define RF_SIZE                                0x0014
 
 /*
index 934f8e03c5aae99fa9f6175d0c509d48fc245a48..767e3c98184c2a8e62f8047471af21be5a31d78a 100644 (file)
@@ -249,43 +249,34 @@ rf_write:
 }
 
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
-#define CSR_OFFSET(__word)     ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
-
-static void rt73usb_read_csr(struct rt2x00_dev *rt2x00dev,
-                            const unsigned int word, u32 *data)
-{
-       rt73usb_register_read(rt2x00dev, CSR_OFFSET(word), data);
-}
-
-static void rt73usb_write_csr(struct rt2x00_dev *rt2x00dev,
-                             const unsigned int word, u32 data)
-{
-       rt73usb_register_write(rt2x00dev, CSR_OFFSET(word), data);
-}
-
 static const struct rt2x00debug rt73usb_rt2x00debug = {
        .owner  = THIS_MODULE,
        .csr    = {
-               .read           = rt73usb_read_csr,
-               .write          = rt73usb_write_csr,
+               .read           = rt73usb_register_read,
+               .write          = rt73usb_register_write,
+               .flags          = RT2X00DEBUGFS_OFFSET,
+               .word_base      = CSR_REG_BASE,
                .word_size      = sizeof(u32),
                .word_count     = CSR_REG_SIZE / sizeof(u32),
        },
        .eeprom = {
                .read           = rt2x00_eeprom_read,
                .write          = rt2x00_eeprom_write,
+               .word_base      = EEPROM_BASE,
                .word_size      = sizeof(u16),
                .word_count     = EEPROM_SIZE / sizeof(u16),
        },
        .bbp    = {
                .read           = rt73usb_bbp_read,
                .write          = rt73usb_bbp_write,
+               .word_base      = BBP_BASE,
                .word_size      = sizeof(u8),
                .word_count     = BBP_SIZE / sizeof(u8),
        },
        .rf     = {
                .read           = rt2x00_rf_read,
                .write          = rt73usb_rf_write,
+               .word_base      = RF_BASE,
                .word_size      = sizeof(u32),
                .word_count     = RF_SIZE / sizeof(u32),
        },
@@ -669,87 +660,18 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
                           !!erp->short_preamble);
        rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
-}
-
-static void rt73usb_config_lna_gain(struct rt2x00_dev *rt2x00dev,
-                                   struct rt2x00lib_conf *libconf)
-{
-       u16 eeprom;
-       short lna_gain = 0;
-
-       if (libconf->band == IEEE80211_BAND_2GHZ) {
-               if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
-                       lna_gain += 14;
-
-               rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
-               lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1);
-       } else {
-               rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom);
-               lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1);
-       }
-
-       rt2x00dev->lna_gain = lna_gain;
-}
-
-static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev,
-                                  const int basic_rate_mask)
-{
-       rt73usb_register_write(rt2x00dev, TXRX_CSR5, basic_rate_mask);
-}
-
-static void rt73usb_config_channel(struct rt2x00_dev *rt2x00dev,
-                                  struct rf_channel *rf, const int txpower)
-{
-       u8 r3;
-       u8 r94;
-       u8 smart;
-
-       rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
-       rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
-
-       smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-                 rt2x00_rf(&rt2x00dev->chip, RF2527));
-
-       rt73usb_bbp_read(rt2x00dev, 3, &r3);
-       rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
-       rt73usb_bbp_write(rt2x00dev, 3, r3);
-
-       r94 = 6;
-       if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94))
-               r94 += txpower - MAX_TXPOWER;
-       else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94))
-               r94 += txpower;
-       rt73usb_bbp_write(rt2x00dev, 94, r94);
-
-       rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
-       rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
-       rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
-       rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
-
-       rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
-       rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
-       rt73usb_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
-       rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
-
-       rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
-       rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
-       rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
-       rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
 
-       udelay(10);
-}
-
-static void rt73usb_config_txpower(struct rt2x00_dev *rt2x00dev,
-                                  const int txpower)
-{
-       struct rf_channel rf;
+       rt73usb_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
 
-       rt2x00_rf_read(rt2x00dev, 1, &rf.rf1);
-       rt2x00_rf_read(rt2x00dev, 2, &rf.rf2);
-       rt2x00_rf_read(rt2x00dev, 3, &rf.rf3);
-       rt2x00_rf_read(rt2x00dev, 4, &rf.rf4);
+       rt73usb_register_read(rt2x00dev, MAC_CSR9, &reg);
+       rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
+       rt73usb_register_write(rt2x00dev, MAC_CSR9, reg);
 
-       rt73usb_config_channel(rt2x00dev, &rf, txpower);
+       rt73usb_register_read(rt2x00dev, MAC_CSR8, &reg);
+       rt2x00_set_field32(&reg, MAC_CSR8_SIFS, erp->sifs);
+       rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
+       rt2x00_set_field32(&reg, MAC_CSR8_EIFS, erp->eifs);
+       rt73usb_register_write(rt2x00dev, MAC_CSR8, reg);
 }
 
 static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
@@ -869,8 +791,8 @@ static const struct antenna_sel antenna_sel_bg[] = {
        { 98,  { 0x48, 0x48 } },
 };
 
-static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
-                                  struct antenna_setup *ant)
+static void rt73usb_config_ant(struct rt2x00_dev *rt2x00dev,
+                              struct antenna_setup *ant)
 {
        const struct antenna_sel *sel;
        unsigned int lna;
@@ -912,20 +834,98 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
                rt73usb_config_antenna_2x(rt2x00dev, ant);
 }
 
-static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
+static void rt73usb_config_lna_gain(struct rt2x00_dev *rt2x00dev,
                                    struct rt2x00lib_conf *libconf)
+{
+       u16 eeprom;
+       short lna_gain = 0;
+
+       if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) {
+               if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
+                       lna_gain += 14;
+
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
+               lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1);
+       } else {
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom);
+               lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1);
+       }
+
+       rt2x00dev->lna_gain = lna_gain;
+}
+
+static void rt73usb_config_channel(struct rt2x00_dev *rt2x00dev,
+                                  struct rf_channel *rf, const int txpower)
+{
+       u8 r3;
+       u8 r94;
+       u8 smart;
+
+       rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
+       rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
+
+       smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
+                 rt2x00_rf(&rt2x00dev->chip, RF2527));
+
+       rt73usb_bbp_read(rt2x00dev, 3, &r3);
+       rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
+       rt73usb_bbp_write(rt2x00dev, 3, r3);
+
+       r94 = 6;
+       if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94))
+               r94 += txpower - MAX_TXPOWER;
+       else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94))
+               r94 += txpower;
+       rt73usb_bbp_write(rt2x00dev, 94, r94);
+
+       rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
+       rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
+       rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+       rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
+
+       rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
+       rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
+       rt73usb_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
+       rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
+
+       rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
+       rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
+       rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+       rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
+
+       udelay(10);
+}
+
+static void rt73usb_config_txpower(struct rt2x00_dev *rt2x00dev,
+                                  const int txpower)
+{
+       struct rf_channel rf;
+
+       rt2x00_rf_read(rt2x00dev, 1, &rf.rf1);
+       rt2x00_rf_read(rt2x00dev, 2, &rf.rf2);
+       rt2x00_rf_read(rt2x00dev, 3, &rf.rf3);
+       rt2x00_rf_read(rt2x00dev, 4, &rf.rf4);
+
+       rt73usb_config_channel(rt2x00dev, &rf, txpower);
+}
+
+static void rt73usb_config_retry_limit(struct rt2x00_dev *rt2x00dev,
+                                      struct rt2x00lib_conf *libconf)
 {
        u32 reg;
 
-       rt73usb_register_read(rt2x00dev, MAC_CSR9, &reg);
-       rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, libconf->slot_time);
-       rt73usb_register_write(rt2x00dev, MAC_CSR9, reg);
+       rt73usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
+       rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT,
+                          libconf->conf->long_frame_max_tx_count);
+       rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT,
+                          libconf->conf->short_frame_max_tx_count);
+       rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
+}
 
-       rt73usb_register_read(rt2x00dev, MAC_CSR8, &reg);
-       rt2x00_set_field32(&reg, MAC_CSR8_SIFS, libconf->sifs);
-       rt2x00_set_field32(&reg, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3);
-       rt2x00_set_field32(&reg, MAC_CSR8_EIFS, libconf->eifs);
-       rt73usb_register_write(rt2x00dev, MAC_CSR8, reg);
+static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
+                                   struct rt2x00lib_conf *libconf)
+{
+       u32 reg;
 
        rt73usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
@@ -948,16 +948,15 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
        /* Always recalculate LNA gain before changing configuration */
        rt73usb_config_lna_gain(rt2x00dev, libconf);
 
-       if (flags & CONFIG_UPDATE_PHYMODE)
-               rt73usb_config_phymode(rt2x00dev, libconf->basic_rates);
-       if (flags & CONFIG_UPDATE_CHANNEL)
+       if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
                rt73usb_config_channel(rt2x00dev, &libconf->rf,
                                       libconf->conf->power_level);
-       if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL))
+       if ((flags & IEEE80211_CONF_CHANGE_POWER) &&
+           !(flags & IEEE80211_CONF_CHANGE_CHANNEL))
                rt73usb_config_txpower(rt2x00dev, libconf->conf->power_level);
-       if (flags & CONFIG_UPDATE_ANTENNA)
-               rt73usb_config_antenna(rt2x00dev, &libconf->ant);
-       if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
+       if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
+               rt73usb_config_retry_limit(rt2x00dev, libconf);
+       if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
                rt73usb_config_duration(rt2x00dev, libconf);
 }
 
@@ -1685,7 +1684,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
 }
 
 static void rt73usb_fill_rxdone(struct queue_entry *entry,
-                               struct rxdone_entry_desc *rxdesc)
+                               struct rxdone_entry_desc *rxdesc)
 {
        struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
        struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
@@ -1781,10 +1780,8 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
         */
        mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
        if (!is_valid_ether_addr(mac)) {
-               DECLARE_MAC_BUF(macbuf);
-
                random_ether_addr(mac);
-               EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac));
+               EEPROM(rt2x00dev, "MAC: %pM\n", mac);
        }
 
        rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
@@ -2211,20 +2208,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 /*
  * IEEE80211 stack callback functions.
  */
-static int rt73usb_set_retry_limit(struct ieee80211_hw *hw,
-                                  u32 short_retry, u32 long_retry)
-{
-       struct rt2x00_dev *rt2x00dev = hw->priv;
-       u32 reg;
-
-       rt73usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR4_LONG_RETRY_LIMIT, long_retry);
-       rt2x00_set_field32(&reg, TXRX_CSR4_SHORT_RETRY_LIMIT, short_retry);
-       rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
-
-       return 0;
-}
-
 static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
                           const struct ieee80211_tx_queue_params *params)
 {
@@ -2317,7 +2300,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
        .configure_filter       = rt2x00mac_configure_filter,
        .set_key                = rt2x00mac_set_key,
        .get_stats              = rt2x00mac_get_stats,
-       .set_retry_limit        = rt73usb_set_retry_limit,
        .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt73usb_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
@@ -2348,6 +2330,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
        .config_filter          = rt73usb_config_filter,
        .config_intf            = rt73usb_config_intf,
        .config_erp             = rt73usb_config_erp,
+       .config_ant             = rt73usb_config_ant,
        .config                 = rt73usb_config,
 };
 
index 868386c457f65c39c4e15d11ef92cefbebb534a4..46e1405eb0e21ae7d643e5b6d17a011101199d30 100644 (file)
@@ -48,7 +48,9 @@
 #define CSR_REG_SIZE                   0x04b0
 #define EEPROM_BASE                    0x0000
 #define EEPROM_SIZE                    0x0100
+#define BBP_BASE                       0x0000
 #define BBP_SIZE                       0x0080
+#define RF_BASE                                0x0000
 #define RF_SIZE                                0x0014
 
 /*
index df7e78ee8a88451cfe6a00111e93327bcd8f996c..6c226c024dd9c5eac4b37c9ceb84f62ba9ad104e 100644 (file)
@@ -182,15 +182,13 @@ static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
                                 skb->len, PCI_DMA_TODEVICE);
 
                info = IEEE80211_SKB_CB(skb);
-               memset(&info->status, 0, sizeof(info->status));
+               ieee80211_tx_info_clear_status(info);
 
-               if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
-                       if (flags & RTL818X_TX_DESC_FLAG_TX_OK)
-                               info->flags |= IEEE80211_TX_STAT_ACK;
-                       else
-                               info->status.excessive_retries = 1;
-               }
-               info->status.retry_count = flags & 0xFF;
+               if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+                   (flags & RTL818X_TX_DESC_FLAG_TX_OK))
+                       info->flags |= IEEE80211_TX_STAT_ACK;
+
+               info->status.rates[0].count = (flags & 0xFF) + 1;
 
                ieee80211_tx_status_irqsafe(dev, skb);
                if (ring->entries - skb_queue_len(&ring->queue) == 2)
@@ -243,6 +241,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        unsigned int idx, prio;
        dma_addr_t mapping;
        u32 tx_flags;
+       u8 rc_flags;
        u16 plcp_len = 0;
        __le16 rts_duration = 0;
 
@@ -261,15 +260,16 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
                tx_flags |= RTL818X_TX_DESC_FLAG_DMA |
                            RTL818X_TX_DESC_FLAG_NO_ENC;
 
-       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
+       rc_flags = info->control.rates[0].flags;
+       if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
                tx_flags |= RTL818X_TX_DESC_FLAG_RTS;
                tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
-       } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
+       } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
                tx_flags |= RTL818X_TX_DESC_FLAG_CTS;
                tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
        }
 
-       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
+       if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS)
                rts_duration = ieee80211_rts_duration(dev, priv->vif, skb->len,
                                                      info);
 
@@ -292,9 +292,9 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        entry->plcp_len = cpu_to_le16(plcp_len);
        entry->tx_buf = cpu_to_le32(mapping);
        entry->frame_len = cpu_to_le32(skb->len);
-       entry->flags2 = info->control.retries[0].rate_idx >= 0 ?
+       entry->flags2 = info->control.rates[1].idx >= 0 ?
                ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0;
-       entry->retry_limit = info->control.retry_limit;
+       entry->retry_limit = info->control.rates[0].count;
        entry->flags = cpu_to_le32(tx_flags);
        __skb_queue_tail(&ring->queue, skb);
        if (ring->entries - skb_queue_len(&ring->queue) < 2)
@@ -692,9 +692,10 @@ static void rtl8180_remove_interface(struct ieee80211_hw *dev,
        priv->vif = NULL;
 }
 
-static int rtl8180_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
+static int rtl8180_config(struct ieee80211_hw *dev, u32 changed)
 {
        struct rtl8180_priv *priv = dev->priv;
+       struct ieee80211_conf *conf = &dev->conf;
 
        priv->rf->set_chan(dev, conf);
 
@@ -806,7 +807,6 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
        const char *chip_name, *rf_name = NULL;
        u32 reg;
        u16 eeprom_val;
-       DECLARE_MAC_BUF(mac);
 
        err = pci_enable_device(pdev);
        if (err) {
@@ -855,7 +855,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
        priv = dev->priv;
        priv->pdev = pdev;
 
-       dev->max_altrates = 1;
+       dev->max_rates = 2;
        SET_IEEE80211_DEV(dev, &pdev->dev);
        pci_set_drvdata(pdev, dev);
 
@@ -1002,8 +1002,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
                goto err_iounmap;
        }
 
-       printk(KERN_INFO "%s: hwaddr %s, %s + %s\n",
-              wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
+       printk(KERN_INFO "%s: hwaddr %pM, %s + %s\n",
+              wiphy_name(dev->wiphy), dev->wiphy->perm_addr,
               chip_name, priv->rf->name);
 
        return 0;
index e82bb4d289e834e2a2117a463d1a96697534a47d..33725d0978b32309e39b62ca195c8f5403903674 100644 (file)
@@ -100,7 +100,6 @@ struct rtl8187_priv {
        struct usb_device *udev;
        u32 rx_conf;
        u16 txpwr_base;
-       u16 seqno;
        u8 asic_rev;
        u8 is_rtl8187b;
        enum {
index 69eb0132593b72cc2a5d995788a28d2744fcecce..e1399d0b55d3c8e5abf6120cea6052e7c7522ede 100644 (file)
@@ -155,21 +155,19 @@ void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
        rtl818x_iowrite8(priv, &priv->map->PHY[2], (data >> 16) & 0xFF);
        rtl818x_iowrite8(priv, &priv->map->PHY[1], (data >> 8) & 0xFF);
        rtl818x_iowrite8(priv, &priv->map->PHY[0], data & 0xFF);
-
-       msleep(1);
 }
 
 static void rtl8187_tx_cb(struct urb *urb)
 {
        struct sk_buff *skb = (struct sk_buff *)urb->context;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_hw *hw = info->driver_data[0];
+       struct ieee80211_hw *hw = info->rate_driver_data[0];
        struct rtl8187_priv *priv = hw->priv;
 
-       usb_free_urb(info->driver_data[1]);
+       usb_free_urb(info->rate_driver_data[1]);
        skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) :
                                          sizeof(struct rtl8187_tx_hdr));
-       memset(&info->status, 0, sizeof(info->status));
+       ieee80211_tx_info_clear_status(info);
        info->flags |= IEEE80211_TX_STAT_ACK;
        ieee80211_tx_status_irqsafe(hw, skb);
 }
@@ -178,7 +176,6 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
        struct rtl8187_priv *priv = dev->priv;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
        unsigned int ep;
        void *buf;
        struct urb *urb;
@@ -198,12 +195,12 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24;
        if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control))
                flags |= RTL818X_TX_DESC_FLAG_MOREFRAG;
-       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
+       if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
                flags |= RTL818X_TX_DESC_FLAG_RTS;
                flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
                rts_dur = ieee80211_rts_duration(dev, priv->vif,
                                                 skb->len, info);
-       } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
+       } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
                flags |= RTL818X_TX_DESC_FLAG_CTS;
                flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
        }
@@ -214,7 +211,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
                hdr->flags = cpu_to_le32(flags);
                hdr->len = 0;
                hdr->rts_duration = rts_dur;
-               hdr->retry = cpu_to_le32(info->control.retry_limit << 8);
+               hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8);
                buf = hdr;
 
                ep = 2;
@@ -232,7 +229,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
                memset(hdr, 0, sizeof(*hdr));
                hdr->flags = cpu_to_le32(flags);
                hdr->rts_duration = rts_dur;
-               hdr->retry = cpu_to_le32(info->control.retry_limit << 8);
+               hdr->retry = cpu_to_le32((info->control.rates[0].count - 1) << 8);
                hdr->tx_duration =
                        ieee80211_generic_frame_duration(dev, priv->vif,
                                                         skb->len, txrate);
@@ -244,22 +241,8 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
                        ep = epmap[skb_get_queue_mapping(skb)];
        }
 
-       /* FIXME: The sequence that follows is needed for this driver to
-        * work with mac80211 since "mac80211: fix TX sequence numbers".
-        * As with the temporary code in rt2x00, changes will be needed
-        * to get proper sequence numbers on beacons. In addition, this
-        * patch places the sequence number in the hardware state, which
-        * limits us to a single virtual state.
-        */
-       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-               if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
-                       priv->seqno += 0x10;
-               ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-               ieee80211hdr->seq_ctrl |= cpu_to_le16(priv->seqno);
-       }
-
-       info->driver_data[0] = dev;
-       info->driver_data[1] = urb;
+       info->rate_driver_data[0] = dev;
+       info->rate_driver_data[1] = urb;
 
        usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep),
                          buf, skb->len, rtl8187_tx_cb, skb);
@@ -687,7 +670,7 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488);
        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
-       msleep(1100);
+       msleep(100);
 
        priv->rf->init(dev);
 
@@ -876,9 +859,10 @@ static void rtl8187_remove_interface(struct ieee80211_hw *dev,
        mutex_unlock(&priv->conf_mutex);
 }
 
-static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
+static int rtl8187_config(struct ieee80211_hw *dev, u32 changed)
 {
        struct rtl8187_priv *priv = dev->priv;
+       struct ieee80211_conf *conf = &dev->conf;
        u32 reg;
 
        mutex_lock(&priv->conf_mutex);
@@ -889,27 +873,10 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
         */
        rtl818x_iowrite32(priv, &priv->map->TX_CONF,
                          reg | RTL818X_TX_CONF_LOOPBACK_MAC);
-       msleep(10);
        priv->rf->set_chan(dev, conf);
        msleep(10);
        rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
 
-       if (!priv->is_rtl8187b) {
-               rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
-
-               if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
-                       rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
-                       rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
-                       rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14);
-                       rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73);
-               } else {
-                       rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
-                       rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
-                       rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24);
-                       rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
-               }
-       }
-
        rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
        rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100);
        rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
@@ -944,6 +911,72 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev,
        return 0;
 }
 
+static void rtl8187_conf_erp(struct rtl8187_priv *priv, bool use_short_slot,
+                            bool use_short_preamble)
+{
+       if (priv->is_rtl8187b) {
+               u8 difs, eifs, slot_time;
+               u16 ack_timeout;
+
+               if (use_short_slot) {
+                       slot_time = 0x9;
+                       difs = 0x1c;
+                       eifs = 0x53;
+               } else {
+                       slot_time = 0x14;
+                       difs = 0x32;
+                       eifs = 0x5b;
+               }
+               rtl818x_iowrite8(priv, &priv->map->SIFS, 0xa);
+               rtl818x_iowrite8(priv, &priv->map->SLOT, slot_time);
+               rtl818x_iowrite8(priv, &priv->map->DIFS, difs);
+
+               /*
+                * BRSR+1 on 8187B is in fact EIFS register
+                * Value in units of 4 us
+                */
+               rtl818x_iowrite8(priv, (u8 *)&priv->map->BRSR + 1, eifs);
+
+               /*
+                * For 8187B, CARRIER_SENSE_COUNTER is in fact ack timeout
+                * register. In units of 4 us like eifs register
+                * ack_timeout = ack duration + plcp + difs + preamble
+                */
+               ack_timeout = 112 + 48 + difs;
+               if (use_short_preamble)
+                       ack_timeout += 72;
+               else
+                       ack_timeout += 144;
+               rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER,
+                                DIV_ROUND_UP(ack_timeout, 4));
+       } else {
+               rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
+               if (use_short_slot) {
+                       rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
+                       rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
+                       rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x14);
+                       rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73);
+               } else {
+                       rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
+                       rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
+                       rtl818x_iowrite8(priv, &priv->map->EIFS, 91 - 0x24);
+                       rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
+               }
+       }
+}
+
+static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
+                                    struct ieee80211_vif *vif,
+                                    struct ieee80211_bss_conf *info,
+                                    u32 changed)
+{
+       struct rtl8187_priv *priv = dev->priv;
+
+       if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE))
+               rtl8187_conf_erp(priv, info->use_short_slot,
+                                info->use_short_preamble);
+}
+
 static void rtl8187_configure_filter(struct ieee80211_hw *dev,
                                     unsigned int changed_flags,
                                     unsigned int *total_flags,
@@ -984,6 +1017,7 @@ static const struct ieee80211_ops rtl8187_ops = {
        .remove_interface       = rtl8187_remove_interface,
        .config                 = rtl8187_config,
        .config_interface       = rtl8187_config_interface,
+       .bss_info_changed       = rtl8187_bss_info_changed,
        .configure_filter       = rtl8187_configure_filter,
 };
 
@@ -1029,7 +1063,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
        const char *chip_name;
        u16 txpwr, reg;
        int err, i;
-       DECLARE_MAC_BUF(mac);
 
        dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8187_ops);
        if (!dev) {
@@ -1190,6 +1223,10 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
                dev->max_signal = 65;
        }
 
+       /*
+        * XXX: Once this driver supports anything that requires
+        *      beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ.
+        */
        dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
 
        if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b)
@@ -1212,8 +1249,8 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
        }
        mutex_init(&priv->conf_mutex);
 
-       printk(KERN_INFO "%s: hwaddr %s, %s V%d + %s\n",
-              wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
+       printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s\n",
+              wiphy_name(dev->wiphy), dev->wiphy->perm_addr,
               chip_name, priv->asic_rev, priv->rf->name);
 
        return 0;
index 1bae8990341096913c6800c19df076ac4f7e208a..69030be62b366fc99f85b980485a08f1e59fca57 100644 (file)
@@ -64,7 +64,6 @@ static void rtl8225_write_bitbang(struct ieee80211_hw *dev, u8 addr, u16 data)
 
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
-       msleep(2);
 }
 
 static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data)
@@ -98,7 +97,6 @@ static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data)
 
        rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
        rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
-       msleep(2);
 }
 
 static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
@@ -333,21 +331,21 @@ static void rtl8225_rf_init(struct ieee80211_hw *dev)
        struct rtl8187_priv *priv = dev->priv;
        int i;
 
-       rtl8225_write(dev, 0x0, 0x067); msleep(1);
-       rtl8225_write(dev, 0x1, 0xFE0); msleep(1);
-       rtl8225_write(dev, 0x2, 0x44D); msleep(1);
-       rtl8225_write(dev, 0x3, 0x441); msleep(1);
-       rtl8225_write(dev, 0x4, 0x486); msleep(1);
-       rtl8225_write(dev, 0x5, 0xBC0); msleep(1);
-       rtl8225_write(dev, 0x6, 0xAE6); msleep(1);
-       rtl8225_write(dev, 0x7, 0x82A); msleep(1);
-       rtl8225_write(dev, 0x8, 0x01F); msleep(1);
-       rtl8225_write(dev, 0x9, 0x334); msleep(1);
-       rtl8225_write(dev, 0xA, 0xFD4); msleep(1);
-       rtl8225_write(dev, 0xB, 0x391); msleep(1);
-       rtl8225_write(dev, 0xC, 0x050); msleep(1);
-       rtl8225_write(dev, 0xD, 0x6DB); msleep(1);
-       rtl8225_write(dev, 0xE, 0x029); msleep(1);
+       rtl8225_write(dev, 0x0, 0x067);
+       rtl8225_write(dev, 0x1, 0xFE0);
+       rtl8225_write(dev, 0x2, 0x44D);
+       rtl8225_write(dev, 0x3, 0x441);
+       rtl8225_write(dev, 0x4, 0x486);
+       rtl8225_write(dev, 0x5, 0xBC0);
+       rtl8225_write(dev, 0x6, 0xAE6);
+       rtl8225_write(dev, 0x7, 0x82A);
+       rtl8225_write(dev, 0x8, 0x01F);
+       rtl8225_write(dev, 0x9, 0x334);
+       rtl8225_write(dev, 0xA, 0xFD4);
+       rtl8225_write(dev, 0xB, 0x391);
+       rtl8225_write(dev, 0xC, 0x050);
+       rtl8225_write(dev, 0xD, 0x6DB);
+       rtl8225_write(dev, 0xE, 0x029);
        rtl8225_write(dev, 0xF, 0x914); msleep(100);
 
        rtl8225_write(dev, 0x2, 0xC4D); msleep(200);
@@ -375,91 +373,89 @@ static void rtl8225_rf_init(struct ieee80211_hw *dev)
 
        for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
                rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
-               msleep(1);
                rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
-               msleep(1);
        }
 
        msleep(1);
 
-       rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x02, 0x42); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x11, 0x06); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x00, 0x01);
+       rtl8225_write_phy_ofdm(dev, 0x01, 0x02);
+       rtl8225_write_phy_ofdm(dev, 0x02, 0x42);
+       rtl8225_write_phy_ofdm(dev, 0x03, 0x00);
+       rtl8225_write_phy_ofdm(dev, 0x04, 0x00);
+       rtl8225_write_phy_ofdm(dev, 0x05, 0x00);
+       rtl8225_write_phy_ofdm(dev, 0x06, 0x40);
+       rtl8225_write_phy_ofdm(dev, 0x07, 0x00);
+       rtl8225_write_phy_ofdm(dev, 0x08, 0x40);
+       rtl8225_write_phy_ofdm(dev, 0x09, 0xfe);
+       rtl8225_write_phy_ofdm(dev, 0x0a, 0x09);
+       rtl8225_write_phy_ofdm(dev, 0x0b, 0x80);
+       rtl8225_write_phy_ofdm(dev, 0x0c, 0x01);
+       rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3);
+       rtl8225_write_phy_ofdm(dev, 0x0f, 0x38);
+       rtl8225_write_phy_ofdm(dev, 0x10, 0x84);
+       rtl8225_write_phy_ofdm(dev, 0x11, 0x06);
+       rtl8225_write_phy_ofdm(dev, 0x12, 0x20);
+       rtl8225_write_phy_ofdm(dev, 0x13, 0x20);
+       rtl8225_write_phy_ofdm(dev, 0x14, 0x00);
+       rtl8225_write_phy_ofdm(dev, 0x15, 0x40);
+       rtl8225_write_phy_ofdm(dev, 0x16, 0x00);
+       rtl8225_write_phy_ofdm(dev, 0x17, 0x40);
+       rtl8225_write_phy_ofdm(dev, 0x18, 0xef);
+       rtl8225_write_phy_ofdm(dev, 0x19, 0x19);
+       rtl8225_write_phy_ofdm(dev, 0x1a, 0x20);
+       rtl8225_write_phy_ofdm(dev, 0x1b, 0x76);
+       rtl8225_write_phy_ofdm(dev, 0x1c, 0x04);
+       rtl8225_write_phy_ofdm(dev, 0x1e, 0x95);
+       rtl8225_write_phy_ofdm(dev, 0x1f, 0x75);
+       rtl8225_write_phy_ofdm(dev, 0x20, 0x1f);
+       rtl8225_write_phy_ofdm(dev, 0x21, 0x27);
+       rtl8225_write_phy_ofdm(dev, 0x22, 0x16);
+       rtl8225_write_phy_ofdm(dev, 0x24, 0x46);
+       rtl8225_write_phy_ofdm(dev, 0x25, 0x20);
+       rtl8225_write_phy_ofdm(dev, 0x26, 0x90);
+       rtl8225_write_phy_ofdm(dev, 0x27, 0x88);
 
        rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[2 * 4]);
        rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[2 * 4 + 2]);
        rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[2 * 4 + 3]);
        rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[2 * 4 + 1]);
 
-       rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x00, 0x98);
+       rtl8225_write_phy_cck(dev, 0x03, 0x20);
+       rtl8225_write_phy_cck(dev, 0x04, 0x7e);
+       rtl8225_write_phy_cck(dev, 0x05, 0x12);
+       rtl8225_write_phy_cck(dev, 0x06, 0xfc);
+       rtl8225_write_phy_cck(dev, 0x07, 0x78);
+       rtl8225_write_phy_cck(dev, 0x08, 0x2e);
+       rtl8225_write_phy_cck(dev, 0x10, 0x9b);
+       rtl8225_write_phy_cck(dev, 0x11, 0x88);
+       rtl8225_write_phy_cck(dev, 0x12, 0x47);
        rtl8225_write_phy_cck(dev, 0x13, 0xd0);
        rtl8225_write_phy_cck(dev, 0x19, 0x00);
        rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
        rtl8225_write_phy_cck(dev, 0x1b, 0x08);
        rtl8225_write_phy_cck(dev, 0x40, 0x86);
-       rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x44, 0x1f); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x45, 0x1e); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x46, 0x1a); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x47, 0x15); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x48, 0x10); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x49, 0x0a); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x4a, 0x05); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x4b, 0x02); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x41, 0x8d);
+       rtl8225_write_phy_cck(dev, 0x42, 0x15);
+       rtl8225_write_phy_cck(dev, 0x43, 0x18);
+       rtl8225_write_phy_cck(dev, 0x44, 0x1f);
+       rtl8225_write_phy_cck(dev, 0x45, 0x1e);
+       rtl8225_write_phy_cck(dev, 0x46, 0x1a);
+       rtl8225_write_phy_cck(dev, 0x47, 0x15);
+       rtl8225_write_phy_cck(dev, 0x48, 0x10);
+       rtl8225_write_phy_cck(dev, 0x49, 0x0a);
+       rtl8225_write_phy_cck(dev, 0x4a, 0x05);
+       rtl8225_write_phy_cck(dev, 0x4b, 0x02);
+       rtl8225_write_phy_cck(dev, 0x4c, 0x05);
 
        rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D);
 
        rtl8225_rf_set_tx_power(dev, 1);
 
        /* RX antenna default to A */
-       rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);      /* B: 0xDB */
-       rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);     /* B: 0x10 */
+       rtl8225_write_phy_cck(dev, 0x10, 0x9b);                 /* B: 0xDB */
+       rtl8225_write_phy_ofdm(dev, 0x26, 0x90);                /* B: 0x10 */
 
        rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);   /* B: 0x00 */
        msleep(1);
@@ -629,7 +625,7 @@ static void rtl8225z2_b_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
                rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
 
        rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
-                        rtl8225z2_tx_gain_cck_ofdm[cck_power]);
+                        rtl8225z2_tx_gain_cck_ofdm[cck_power] << 1);
        msleep(1);
 
        rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
@@ -687,22 +683,23 @@ static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
        struct rtl8187_priv *priv = dev->priv;
        int i;
 
-       rtl8225_write(dev, 0x0, 0x2BF); msleep(1);
-       rtl8225_write(dev, 0x1, 0xEE0); msleep(1);
-       rtl8225_write(dev, 0x2, 0x44D); msleep(1);
-       rtl8225_write(dev, 0x3, 0x441); msleep(1);
-       rtl8225_write(dev, 0x4, 0x8C3); msleep(1);
-       rtl8225_write(dev, 0x5, 0xC72); msleep(1);
-       rtl8225_write(dev, 0x6, 0x0E6); msleep(1);
-       rtl8225_write(dev, 0x7, 0x82A); msleep(1);
-       rtl8225_write(dev, 0x8, 0x03F); msleep(1);
-       rtl8225_write(dev, 0x9, 0x335); msleep(1);
-       rtl8225_write(dev, 0xa, 0x9D4); msleep(1);
-       rtl8225_write(dev, 0xb, 0x7BB); msleep(1);
-       rtl8225_write(dev, 0xc, 0x850); msleep(1);
-       rtl8225_write(dev, 0xd, 0xCDF); msleep(1);
-       rtl8225_write(dev, 0xe, 0x02B); msleep(1);
-       rtl8225_write(dev, 0xf, 0x114); msleep(100);
+       rtl8225_write(dev, 0x0, 0x2BF);
+       rtl8225_write(dev, 0x1, 0xEE0);
+       rtl8225_write(dev, 0x2, 0x44D);
+       rtl8225_write(dev, 0x3, 0x441);
+       rtl8225_write(dev, 0x4, 0x8C3);
+       rtl8225_write(dev, 0x5, 0xC72);
+       rtl8225_write(dev, 0x6, 0x0E6);
+       rtl8225_write(dev, 0x7, 0x82A);
+       rtl8225_write(dev, 0x8, 0x03F);
+       rtl8225_write(dev, 0x9, 0x335);
+       rtl8225_write(dev, 0xa, 0x9D4);
+       rtl8225_write(dev, 0xb, 0x7BB);
+       rtl8225_write(dev, 0xc, 0x850);
+       rtl8225_write(dev, 0xd, 0xCDF);
+       rtl8225_write(dev, 0xe, 0x02B);
+       rtl8225_write(dev, 0xf, 0x114);
+       msleep(100);
 
        rtl8225_write(dev, 0x0, 0x1B7);
 
@@ -736,94 +733,92 @@ static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
 
        for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
                rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
-               msleep(1);
                rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
-               msleep(1);
        }
 
        msleep(1);
 
-       rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x02, 0x42); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x0a, 0x08); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x00, 0x01);
+       rtl8225_write_phy_ofdm(dev, 0x01, 0x02);
+       rtl8225_write_phy_ofdm(dev, 0x02, 0x42);
+       rtl8225_write_phy_ofdm(dev, 0x03, 0x00);
+       rtl8225_write_phy_ofdm(dev, 0x04, 0x00);
+       rtl8225_write_phy_ofdm(dev, 0x05, 0x00);
+       rtl8225_write_phy_ofdm(dev, 0x06, 0x40);
+       rtl8225_write_phy_ofdm(dev, 0x07, 0x00);
+       rtl8225_write_phy_ofdm(dev, 0x08, 0x40);
+       rtl8225_write_phy_ofdm(dev, 0x09, 0xfe);
+       rtl8225_write_phy_ofdm(dev, 0x0a, 0x08);
+       rtl8225_write_phy_ofdm(dev, 0x0b, 0x80);
+       rtl8225_write_phy_ofdm(dev, 0x0c, 0x01);
        rtl8225_write_phy_ofdm(dev, 0x0d, 0x43);
-       rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x11, 0x07); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x1b, 0x15); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x21, 0x17); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x23, 0x80); msleep(1); //FIXME: not needed?
-       rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x25, 0x00); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3);
+       rtl8225_write_phy_ofdm(dev, 0x0f, 0x38);
+       rtl8225_write_phy_ofdm(dev, 0x10, 0x84);
+       rtl8225_write_phy_ofdm(dev, 0x11, 0x07);
+       rtl8225_write_phy_ofdm(dev, 0x12, 0x20);
+       rtl8225_write_phy_ofdm(dev, 0x13, 0x20);
+       rtl8225_write_phy_ofdm(dev, 0x14, 0x00);
+       rtl8225_write_phy_ofdm(dev, 0x15, 0x40);
+       rtl8225_write_phy_ofdm(dev, 0x16, 0x00);
+       rtl8225_write_phy_ofdm(dev, 0x17, 0x40);
+       rtl8225_write_phy_ofdm(dev, 0x18, 0xef);
+       rtl8225_write_phy_ofdm(dev, 0x19, 0x19);
+       rtl8225_write_phy_ofdm(dev, 0x1a, 0x20);
+       rtl8225_write_phy_ofdm(dev, 0x1b, 0x15);
+       rtl8225_write_phy_ofdm(dev, 0x1c, 0x04);
+       rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5);
+       rtl8225_write_phy_ofdm(dev, 0x1e, 0x95);
+       rtl8225_write_phy_ofdm(dev, 0x1f, 0x75);
+       rtl8225_write_phy_ofdm(dev, 0x20, 0x1f);
+       rtl8225_write_phy_ofdm(dev, 0x21, 0x17);
+       rtl8225_write_phy_ofdm(dev, 0x22, 0x16);
+       rtl8225_write_phy_ofdm(dev, 0x23, 0x80);
+       rtl8225_write_phy_ofdm(dev, 0x24, 0x46);
+       rtl8225_write_phy_ofdm(dev, 0x25, 0x00);
+       rtl8225_write_phy_ofdm(dev, 0x26, 0x90);
+       rtl8225_write_phy_ofdm(dev, 0x27, 0x88);
 
        rtl8225_write_phy_ofdm(dev, 0x0b, rtl8225z2_gain_bg[4 * 3]);
        rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225z2_gain_bg[4 * 3 + 1]);
        rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225z2_gain_bg[4 * 3 + 2]);
        rtl8225_write_phy_ofdm(dev, 0x21, 0x37);
 
-       rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x00, 0x98);
+       rtl8225_write_phy_cck(dev, 0x03, 0x20);
+       rtl8225_write_phy_cck(dev, 0x04, 0x7e);
+       rtl8225_write_phy_cck(dev, 0x05, 0x12);
+       rtl8225_write_phy_cck(dev, 0x06, 0xfc);
+       rtl8225_write_phy_cck(dev, 0x07, 0x78);
+       rtl8225_write_phy_cck(dev, 0x08, 0x2e);
+       rtl8225_write_phy_cck(dev, 0x10, 0x9b);
+       rtl8225_write_phy_cck(dev, 0x11, 0x88);
+       rtl8225_write_phy_cck(dev, 0x12, 0x47);
        rtl8225_write_phy_cck(dev, 0x13, 0xd0);
        rtl8225_write_phy_cck(dev, 0x19, 0x00);
        rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
        rtl8225_write_phy_cck(dev, 0x1b, 0x08);
        rtl8225_write_phy_cck(dev, 0x40, 0x86);
-       rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x44, 0x36); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x45, 0x35); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x46, 0x2e); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x47, 0x25); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x48, 0x1c); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x49, 0x12); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x4a, 0x09); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x4b, 0x04); msleep(1);
-       rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x41, 0x8d);
+       rtl8225_write_phy_cck(dev, 0x42, 0x15);
+       rtl8225_write_phy_cck(dev, 0x43, 0x18);
+       rtl8225_write_phy_cck(dev, 0x44, 0x36);
+       rtl8225_write_phy_cck(dev, 0x45, 0x35);
+       rtl8225_write_phy_cck(dev, 0x46, 0x2e);
+       rtl8225_write_phy_cck(dev, 0x47, 0x25);
+       rtl8225_write_phy_cck(dev, 0x48, 0x1c);
+       rtl8225_write_phy_cck(dev, 0x49, 0x12);
+       rtl8225_write_phy_cck(dev, 0x4a, 0x09);
+       rtl8225_write_phy_cck(dev, 0x4b, 0x04);
+       rtl8225_write_phy_cck(dev, 0x4c, 0x05);
 
        rtl818x_iowrite8(priv, (u8 *)0xFF5B, 0x0D); msleep(1);
 
        rtl8225z2_rf_set_tx_power(dev, 1);
 
        /* RX antenna default to A */
-       rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);      /* B: 0xDB */
-       rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);     /* B: 0x10 */
+       rtl8225_write_phy_cck(dev, 0x10, 0x9b);                 /* B: 0xDB */
+       rtl8225_write_phy_ofdm(dev, 0x26, 0x90);                /* B: 0x10 */
 
        rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);   /* B: 0x00 */
        msleep(1);
@@ -835,40 +830,38 @@ static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev)
        struct rtl8187_priv *priv = dev->priv;
        int i;
 
-       rtl8225_write(dev, 0x0, 0x0B7); msleep(1);
-       rtl8225_write(dev, 0x1, 0xEE0); msleep(1);
-       rtl8225_write(dev, 0x2, 0x44D); msleep(1);
-       rtl8225_write(dev, 0x3, 0x441); msleep(1);
-       rtl8225_write(dev, 0x4, 0x8C3); msleep(1);
-       rtl8225_write(dev, 0x5, 0xC72); msleep(1);
-       rtl8225_write(dev, 0x6, 0x0E6); msleep(1);
-       rtl8225_write(dev, 0x7, 0x82A); msleep(1);
-       rtl8225_write(dev, 0x8, 0x03F); msleep(1);
-       rtl8225_write(dev, 0x9, 0x335); msleep(1);
-       rtl8225_write(dev, 0xa, 0x9D4); msleep(1);
-       rtl8225_write(dev, 0xb, 0x7BB); msleep(1);
-       rtl8225_write(dev, 0xc, 0x850); msleep(1);
-       rtl8225_write(dev, 0xd, 0xCDF); msleep(1);
-       rtl8225_write(dev, 0xe, 0x02B); msleep(1);
-       rtl8225_write(dev, 0xf, 0x114); msleep(1);
-
-       rtl8225_write(dev, 0x0, 0x1B7); msleep(1);
+       rtl8225_write(dev, 0x0, 0x0B7);
+       rtl8225_write(dev, 0x1, 0xEE0);
+       rtl8225_write(dev, 0x2, 0x44D);
+       rtl8225_write(dev, 0x3, 0x441);
+       rtl8225_write(dev, 0x4, 0x8C3);
+       rtl8225_write(dev, 0x5, 0xC72);
+       rtl8225_write(dev, 0x6, 0x0E6);
+       rtl8225_write(dev, 0x7, 0x82A);
+       rtl8225_write(dev, 0x8, 0x03F);
+       rtl8225_write(dev, 0x9, 0x335);
+       rtl8225_write(dev, 0xa, 0x9D4);
+       rtl8225_write(dev, 0xb, 0x7BB);
+       rtl8225_write(dev, 0xc, 0x850);
+       rtl8225_write(dev, 0xd, 0xCDF);
+       rtl8225_write(dev, 0xe, 0x02B);
+       rtl8225_write(dev, 0xf, 0x114);
+
+       rtl8225_write(dev, 0x0, 0x1B7);
 
        for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
-               rtl8225_write(dev, 0x1, i + 1); msleep(1);
-               rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); msleep(1);
+               rtl8225_write(dev, 0x1, i + 1);
+               rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
        }
 
-       rtl8225_write(dev, 0x3, 0x080); msleep(1);
-       rtl8225_write(dev, 0x5, 0x004); msleep(1);
-       rtl8225_write(dev, 0x0, 0x0B7); msleep(1);
-       msleep(3000);
+       rtl8225_write(dev, 0x3, 0x080);
+       rtl8225_write(dev, 0x5, 0x004);
+       rtl8225_write(dev, 0x0, 0x0B7);
 
-       rtl8225_write(dev, 0x2, 0xC4D); msleep(1);
-       msleep(2000);
+       rtl8225_write(dev, 0x2, 0xC4D);
 
-       rtl8225_write(dev, 0x2, 0x44D); msleep(1);
-       rtl8225_write(dev, 0x0, 0x2BF); msleep(1);
+       rtl8225_write(dev, 0x2, 0x44D);
+       rtl8225_write(dev, 0x0, 0x2BF);
 
        rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 0x03);
        rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 0x07);
@@ -885,24 +878,16 @@ static void rtl8225z2_b_rf_init(struct ieee80211_hw *dev)
        for (i = 0; i < ARRAY_SIZE(rtl8225z2_ofdm); i++)
                rtl8225_write_phy_ofdm(dev, i, rtl8225z2_ofdm[i]);
 
-       rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
-       rtl818x_iowrite8(priv, &priv->map->SLOT, 9);
-       rtl818x_iowrite8(priv, (u8 *)0xFFF0, 28);
-       rtl818x_iowrite8(priv, (u8 *)0xFFF4, 28);
-       rtl818x_iowrite8(priv, (u8 *)0xFFF8, 28);
-       rtl818x_iowrite8(priv, (u8 *)0xFFFC, 28);
-       rtl818x_iowrite8(priv, (u8 *)0xFF2D, 0x5B);
-       rtl818x_iowrite8(priv, (u8 *)0xFF79, 0x5B);
        rtl818x_iowrite32(priv, (__le32 *)0xFFF0, (7 << 12) | (3 << 8) | 28);
        rtl818x_iowrite32(priv, (__le32 *)0xFFF4, (7 << 12) | (3 << 8) | 28);
        rtl818x_iowrite32(priv, (__le32 *)0xFFF8, (7 << 12) | (3 << 8) | 28);
        rtl818x_iowrite32(priv, (__le32 *)0xFFFC, (7 << 12) | (3 << 8) | 28);
        rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);
 
-       rtl8225_write_phy_ofdm(dev, 0x97, 0x46); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6); msleep(1);
-       rtl8225_write_phy_ofdm(dev, 0x85, 0xfc); msleep(1);
-       rtl8225_write_phy_cck(dev, 0xc1, 0x88); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x97, 0x46);
+       rtl8225_write_phy_ofdm(dev, 0xa4, 0xb6);
+       rtl8225_write_phy_ofdm(dev, 0x85, 0xfc);
+       rtl8225_write_phy_cck(dev, 0xc1, 0x88);
 }
 
 static void rtl8225_rf_stop(struct ieee80211_hw *dev)
@@ -910,7 +895,7 @@ static void rtl8225_rf_stop(struct ieee80211_hw *dev)
        u8 reg;
        struct rtl8187_priv *priv = dev->priv;
 
-       rtl8225_write(dev, 0x4, 0x1f); msleep(1);
+       rtl8225_write(dev, 0x4, 0x1f);
 
        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
        reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
deleted file mode 100644 (file)
index 852789a..0000000
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
- * Driver for 802.11b cards using RAM-loadable Symbol firmware, such as
- * Symbol Wireless Networker LA4137, CompactFlash cards by Socket
- * Communications and Intel PRO/Wireless 2011B.
- *
- * The driver implements Symbol firmware download.  The rest is handled
- * in hermes.c and orinoco.c.
- *
- * Utilities for downloading the Symbol firmware are available at
- * http://sourceforge.net/projects/orinoco/
- *
- * Copyright (C) 2002-2005 Pavel Roskin <proski@gnu.org>
- * Portions based on orinoco_cs.c:
- *     Copyright (C) David Gibson, Linuxcare Australia
- * Portions based on Spectrum24tDnld.c from original spectrum24 driver:
- *     Copyright (C) Symbol Technologies.
- *
- * See copyright notice in file orinoco.c.
- */
-
-#define DRIVER_NAME "spectrum_cs"
-#define PFX DRIVER_NAME ": "
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
-#include <pcmcia/cisreg.h>
-#include <pcmcia/ds.h>
-
-#include "orinoco.h"
-
-/********************************************************************/
-/* Module stuff                                                            */
-/********************************************************************/
-
-MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
-MODULE_DESCRIPTION("Driver for Symbol Spectrum24 Trilogy cards with firmware downloader");
-MODULE_LICENSE("Dual MPL/GPL");
-
-/* Module parameters */
-
-/* Some D-Link cards have buggy CIS. They do work at 5v properly, but
- * don't have any CIS entry for it. This workaround it... */
-static int ignore_cis_vcc; /* = 0 */
-module_param(ignore_cis_vcc, int, 0);
-MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
-
-/********************************************************************/
-/* Data structures                                                 */
-/********************************************************************/
-
-/* PCMCIA specific device information (goes in the card field of
- * struct orinoco_private */
-struct orinoco_pccard {
-       struct pcmcia_device    *p_dev;
-       dev_node_t node;
-};
-
-/********************************************************************/
-/* Function prototypes                                             */
-/********************************************************************/
-
-static int spectrum_cs_config(struct pcmcia_device *link);
-static void spectrum_cs_release(struct pcmcia_device *link);
-
-/* Constants for the CISREG_CCSR register */
-#define HCR_RUN                0x07    /* run firmware after reset */
-#define HCR_IDLE       0x0E    /* don't run firmware after reset */
-#define HCR_MEM16      0x10    /* memory width bit, should be preserved */
-
-
-#define CS_CHECK(fn, ret) \
-  do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
-/*
- * Reset the card using configuration registers COR and CCSR.
- * If IDLE is 1, stop the firmware, so that it can be safely rewritten.
- */
-static int
-spectrum_reset(struct pcmcia_device *link, int idle)
-{
-       int last_ret, last_fn;
-       conf_reg_t reg;
-       u_int save_cor;
-
-       /* Doing it if hardware is gone is guaranteed crash */
-       if (!pcmcia_dev_present(link))
-               return -ENODEV;
-
-       /* Save original COR value */
-       reg.Function = 0;
-       reg.Action = CS_READ;
-       reg.Offset = CISREG_COR;
-       CS_CHECK(AccessConfigurationRegister,
-                pcmcia_access_configuration_register(link, &reg));
-       save_cor = reg.Value;
-
-       /* Soft-Reset card */
-       reg.Action = CS_WRITE;
-       reg.Offset = CISREG_COR;
-       reg.Value = (save_cor | COR_SOFT_RESET);
-       CS_CHECK(AccessConfigurationRegister,
-                pcmcia_access_configuration_register(link, &reg));
-       udelay(1000);
-
-       /* Read CCSR */
-       reg.Action = CS_READ;
-       reg.Offset = CISREG_CCSR;
-       CS_CHECK(AccessConfigurationRegister,
-                pcmcia_access_configuration_register(link, &reg));
-
-       /*
-        * Start or stop the firmware.  Memory width bit should be
-        * preserved from the value we've just read.
-        */
-       reg.Action = CS_WRITE;
-       reg.Offset = CISREG_CCSR;
-       reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16);
-       CS_CHECK(AccessConfigurationRegister,
-                pcmcia_access_configuration_register(link, &reg));
-       udelay(1000);
-
-       /* Restore original COR configuration index */
-       reg.Action = CS_WRITE;
-       reg.Offset = CISREG_COR;
-       reg.Value = (save_cor & ~COR_SOFT_RESET);
-       CS_CHECK(AccessConfigurationRegister,
-                pcmcia_access_configuration_register(link, &reg));
-       udelay(1000);
-       return 0;
-
-      cs_failed:
-       cs_error(link, last_fn, last_ret);
-       return -ENODEV;
-}
-
-/********************************************************************/
-/* Device methods                                                  */
-/********************************************************************/
-
-static int
-spectrum_cs_hard_reset(struct orinoco_private *priv)
-{
-       struct orinoco_pccard *card = priv->card;
-       struct pcmcia_device *link = card->p_dev;
-
-       /* Soft reset using COR and HCR */
-       spectrum_reset(link, 0);
-
-       return 0;
-}
-
-static int
-spectrum_cs_stop_firmware(struct orinoco_private *priv, int idle)
-{
-       struct orinoco_pccard *card = priv->card;
-       struct pcmcia_device *link = card->p_dev;
-
-       return spectrum_reset(link, idle);
-}
-
-/********************************************************************/
-/* PCMCIA stuff                                                    */
-/********************************************************************/
-
-/*
- * This creates an "instance" of the driver, allocating local data
- * structures for one device.  The device is registered with Card
- * Services.
- * 
- * The dev_link structure is initialized, but we don't actually
- * configure the card at this point -- we wait until we receive a card
- * insertion event.  */
-static int
-spectrum_cs_probe(struct pcmcia_device *link)
-{
-       struct net_device *dev;
-       struct orinoco_private *priv;
-       struct orinoco_pccard *card;
-
-       dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
-                              spectrum_cs_hard_reset,
-                              spectrum_cs_stop_firmware);
-       if (! dev)
-               return -ENOMEM;
-       priv = netdev_priv(dev);
-       card = priv->card;
-
-       /* Link both structures together */
-       card->p_dev = link;
-       link->priv = dev;
-
-       /* Interrupt setup */
-       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; 
-
-       /* General socket configuration defaults can go here.  In this
-        * client, we assume very little, and rely on the CIS for
-        * almost everything.  In most clients, many details (i.e.,
-        * number, sizes, and attributes of IO windows) are fixed by
-        * the nature of the device, and can be hard-wired here. */
-       link->conf.Attributes = 0;
-       link->conf.IntType = INT_MEMORY_AND_IO;
-
-       return spectrum_cs_config(link);
-}                              /* spectrum_cs_attach */
-
-/*
- * This deletes a driver "instance".  The device is de-registered with
- * Card Services.  If it has been released, all local data structures
- * are freed.  Otherwise, the structures will be freed when the device
- * is released.
- */
-static void spectrum_cs_detach(struct pcmcia_device *link)
-{
-       struct net_device *dev = link->priv;
-
-       if (link->dev_node)
-               unregister_netdev(dev);
-
-       spectrum_cs_release(link);
-
-       free_orinocodev(dev);
-}                              /* spectrum_cs_detach */
-
-/*
- * spectrum_cs_config() is scheduled to run after a CARD_INSERTION
- * event is received, to configure the PCMCIA socket, and to make the
- * device available to the system.
- */
-
-static int spectrum_cs_config_check(struct pcmcia_device *p_dev,
-                                   cistpl_cftable_entry_t *cfg,
-                                   cistpl_cftable_entry_t *dflt,
-                                   unsigned int vcc,
-                                   void *priv_data)
-{
-       if (cfg->index == 0)
-               goto next_entry;
-
-       /* Use power settings for Vcc and Vpp if present */
-       /* Note that the CIS values need to be rescaled */
-       if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
-               if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
-                       DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n",  vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
-                       if (!ignore_cis_vcc)
-                               goto next_entry;
-               }
-       } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
-               if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000) {
-                       DEBUG(2, "spectrum_cs_config: Vcc mismatch (vcc = %d, CIS = %d)\n",  vcc, dflt->vcc.param[CISTPL_POWER_VNOM] / 10000);
-                       if (!ignore_cis_vcc)
-                               goto next_entry;
-               }
-       }
-
-       if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
-               p_dev->conf.Vpp =
-                       cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-       else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
-               p_dev->conf.Vpp =
-                       dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-
-       /* Do we need to allocate an interrupt? */
-       p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
-
-       /* IO window settings */
-       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
-       if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
-               cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
-               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-               if (!(io->flags & CISTPL_IO_8BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-               if (!(io->flags & CISTPL_IO_16BIT))
-                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-               p_dev->io.BasePort1 = io->win[0].base;
-               p_dev->io.NumPorts1 = io->win[0].len;
-               if (io->nwin > 1) {
-                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
-                       p_dev->io.BasePort2 = io->win[1].base;
-                       p_dev->io.NumPorts2 = io->win[1].len;
-               }
-
-               /* This reserves IO space but doesn't actually enable it */
-               if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
-                       goto next_entry;
-       }
-       return 0;
-
-next_entry:
-       pcmcia_disable_device(p_dev);
-       return -ENODEV;
-};
-
-static int
-spectrum_cs_config(struct pcmcia_device *link)
-{
-       struct net_device *dev = link->priv;
-       struct orinoco_private *priv = netdev_priv(dev);
-       struct orinoco_pccard *card = priv->card;
-       hermes_t *hw = &priv->hw;
-       int last_fn, last_ret;
-       void __iomem *mem;
-
-       /*
-        * In this loop, we scan the CIS for configuration table
-        * entries, each of which describes a valid card
-        * configuration, including voltage, IO window, memory window,
-        * and interrupt settings.
-        *
-        * We make no assumptions about the card to be configured: we
-        * use just the information available in the CIS.  In an ideal
-        * world, this would work for any PCMCIA card, but it requires
-        * a complete and accurate CIS.  In practice, a driver usually
-        * "knows" most of these things without consulting the CIS,
-        * and most client drivers will only use the CIS to fill in
-        * implementation-defined details.
-        */
-       last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
-       if (last_ret) {
-               if (!ignore_cis_vcc)
-                       printk(KERN_ERR PFX "GetNextTuple(): No matching "
-                              "CIS configuration.  Maybe you need the "
-                              "ignore_cis_vcc=1 parameter.\n");
-               cs_error(link, RequestIO, last_ret);
-               goto failed;
-       }
-
-       /*
-        * Allocate an interrupt line.  Note that this does not assign
-        * a handler to the interrupt, unless the 'Handler' member of
-        * the irq structure is initialized.
-        */
-       CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-
-       /* We initialize the hermes structure before completing PCMCIA
-        * configuration just in case the interrupt handler gets
-        * called. */
-       mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
-       if (!mem)
-               goto cs_failed;
-
-       hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
-
-       /*
-        * This actually configures the PCMCIA socket -- setting up
-        * the I/O windows and the interrupt mapping, and putting the
-        * card and host interface into "Memory and IO" mode.
-        */
-       CS_CHECK(RequestConfiguration,
-                pcmcia_request_configuration(link, &link->conf));
-
-       /* Ok, we have the configuration, prepare to register the netdev */
-       dev->base_addr = link->io.BasePort1;
-       dev->irq = link->irq.AssignedIRQ;
-       card->node.major = card->node.minor = 0;
-
-       /* Reset card */
-       if (spectrum_cs_hard_reset(priv) != 0) {
-               goto failed;
-       }
-
-       SET_NETDEV_DEV(dev, &handle_to_dev(link));
-       /* Tell the stack we exist */
-       if (register_netdev(dev) != 0) {
-               printk(KERN_ERR PFX "register_netdev() failed\n");
-               goto failed;
-       }
-
-       /* At this point, the dev_node_t structure(s) needs to be
-        * initialized and arranged in a linked list at link->dev_node. */
-       strcpy(card->node.dev_name, dev->name);
-       link->dev_node = &card->node; /* link->dev_node being non-NULL is also
-                                    used to indicate that the
-                                    net_device has been registered */
-
-       /* Finally, report what we've done */
-       printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
-              "0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id,
-              link->irq.AssignedIRQ, link->io.BasePort1,
-              link->io.BasePort1 + link->io.NumPorts1 - 1);
-
-       return 0;
-
- cs_failed:
-       cs_error(link, last_fn, last_ret);
-
- failed:
-       spectrum_cs_release(link);
-       return -ENODEV;
-}                              /* spectrum_cs_config */
-
-/*
- * After a card is removed, spectrum_cs_release() will unregister the
- * device, and release the PCMCIA configuration.  If the device is
- * still open, this will be postponed until it is closed.
- */
-static void
-spectrum_cs_release(struct pcmcia_device *link)
-{
-       struct net_device *dev = link->priv;
-       struct orinoco_private *priv = netdev_priv(dev);
-       unsigned long flags;
-
-       /* We're committed to taking the device away now, so mark the
-        * hardware as unavailable */
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->hw_unavailable++;
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       pcmcia_disable_device(link);
-       if (priv->hw.iobase)
-               ioport_unmap(priv->hw.iobase);
-}                              /* spectrum_cs_release */
-
-
-static int
-spectrum_cs_suspend(struct pcmcia_device *link)
-{
-       struct net_device *dev = link->priv;
-       struct orinoco_private *priv = netdev_priv(dev);
-       unsigned long flags;
-       int err = 0;
-
-       /* Mark the device as stopped, to block IO until later */
-       spin_lock_irqsave(&priv->lock, flags);
-
-       err = __orinoco_down(dev);
-       if (err)
-               printk(KERN_WARNING "%s: Error %d downing interface\n",
-                      dev->name, err);
-
-       netif_device_detach(dev);
-       priv->hw_unavailable++;
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       return err;
-}
-
-static int
-spectrum_cs_resume(struct pcmcia_device *link)
-{
-       struct net_device *dev = link->priv;
-       struct orinoco_private *priv = netdev_priv(dev);
-
-       netif_device_attach(dev);
-       priv->hw_unavailable--;
-       schedule_work(&priv->reset_work);
-
-       return 0;
-}
-
-
-/********************************************************************/
-/* Module initialization                                           */
-/********************************************************************/
-
-/* Can't be declared "const" or the whole __initdata section will
- * become const */
-static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
-       " (Pavel Roskin <proski@gnu.org>,"
-       " David Gibson <hermes@gibson.dropbear.id.au>, et al)";
-
-static struct pcmcia_device_id spectrum_cs_ids[] = {
-       PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4137 */
-       PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */
-       PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless LAN PC Card", 0x816cc815, 0x6fbf459a), /* 2011B, not 2011 */
-       PCMCIA_DEVICE_NULL,
-};
-MODULE_DEVICE_TABLE(pcmcia, spectrum_cs_ids);
-
-static struct pcmcia_driver orinoco_driver = {
-       .owner          = THIS_MODULE,
-       .drv            = {
-               .name   = DRIVER_NAME,
-       },
-       .probe          = spectrum_cs_probe,
-       .remove         = spectrum_cs_detach,
-       .suspend        = spectrum_cs_suspend,
-       .resume         = spectrum_cs_resume,
-       .id_table       = spectrum_cs_ids,
-};
-
-static int __init
-init_spectrum_cs(void)
-{
-       printk(KERN_DEBUG "%s\n", version);
-
-       return pcmcia_register_driver(&orinoco_driver);
-}
-
-static void __exit
-exit_spectrum_cs(void)
-{
-       pcmcia_unregister_driver(&orinoco_driver);
-}
-
-module_init(init_spectrum_cs);
-module_exit(exit_spectrum_cs);
index 417e9e675facceab098ca13f594419572a0a0d6d..cf0d070ced130e773384cfab9c28c89ed48b0046 100644 (file)
@@ -1997,7 +1997,6 @@ static void deliver_packet(struct strip *strip_info, STRIP_Header * header,
 #ifdef EXT_COUNTERS
                strip_info->rx_bytes += packetlen;
 #endif
-               skb->dev->last_rx = jiffies;
                netif_rx(skb);
        }
 }
@@ -2490,7 +2489,6 @@ static void strip_dev_setup(struct net_device *dev)
         */
 
        dev->trans_start = 0;
-       dev->last_rx = 0;
        dev->tx_queue_len = 30; /* Drop after 30 frames queued */
 
        dev->flags = 0;
index e939a73ff794a731583292d5e41e7e8a23f64d8e..832679396b6cbc14a23124d35abd2ae389de83b6 100644 (file)
@@ -134,7 +134,7 @@ static inline void wv_16_on(unsigned long ioaddr, u16 hacr)
  */
 static inline void wv_ints_off(struct net_device * dev)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long ioaddr = dev->base_addr;
        
        lp->hacr &= ~HACR_INTRON;
@@ -148,7 +148,7 @@ static inline void wv_ints_off(struct net_device * dev)
  */
 static inline void wv_ints_on(struct net_device * dev)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long ioaddr = dev->base_addr;
 
        lp->hacr |= HACR_INTRON;
@@ -526,7 +526,7 @@ static inline void obram_write(unsigned long ioaddr, u16 o, u8 * b, int n)
  */
 static void wv_ack(struct net_device * dev)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long ioaddr = dev->base_addr;
        u16 scb_cs;
        int i;
@@ -568,7 +568,7 @@ static void wv_ack(struct net_device * dev)
  */
 static int wv_synchronous_cmd(struct net_device * dev, const char *str)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long ioaddr = dev->base_addr;
        u16 scb_cmd;
        ach_t cb;
@@ -824,7 +824,7 @@ if (lp->tx_n_in_use > 0)
  */
 static void wv_82586_reconfig(struct net_device * dev)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long flags;
 
        /* Arm the flag, will be cleard in wv_82586_config() */
@@ -859,8 +859,6 @@ static void wv_82586_reconfig(struct net_device * dev)
  */
 static void wv_psa_show(psa_t * p)
 {
-       DECLARE_MAC_BUF(mac);
-
        printk(KERN_DEBUG "##### WaveLAN PSA contents: #####\n");
        printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n",
               p->psa_io_base_addr_1,
@@ -872,13 +870,10 @@ static void wv_psa_show(psa_t * p)
        printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params);
        printk("psa_int_req_no: %d\n", p->psa_int_req_no);
 #ifdef DEBUG_SHOW_UNUSED
-       printk(KERN_DEBUG "psa_unused0[]: %s\n",
-              print_mac(mac, p->psa_unused0));
+       printk(KERN_DEBUG "psa_unused0[]: %pM\n", p->psa_unused0);
 #endif                         /* DEBUG_SHOW_UNUSED */
-       printk(KERN_DEBUG "psa_univ_mac_addr[]: %s\n",
-              print_mac(mac, p->psa_univ_mac_addr));
-       printk(KERN_DEBUG "psa_local_mac_addr[]: %s\n",
-              print_mac(mac, p->psa_local_mac_addr));
+       printk(KERN_DEBUG "psa_univ_mac_addr[]: %pM\n", p->psa_univ_mac_addr);
+       printk(KERN_DEBUG "psa_local_mac_addr[]: %pM\n", p->psa_local_mac_addr);
        printk(KERN_DEBUG "psa_univ_local_sel: %d, ",
               p->psa_univ_local_sel);
        printk("psa_comp_number: %d, ", p->psa_comp_number);
@@ -927,7 +922,7 @@ static void wv_psa_show(psa_t * p)
 static void wv_mmc_show(struct net_device * dev)
 {
        unsigned long ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        mmr_t m;
 
        /* Basic check */
@@ -1107,8 +1102,6 @@ static void wv_scb_show(unsigned long ioaddr)
  */
 static void wv_ru_show(struct net_device * dev)
 {
-       /* net_local *lp = (net_local *) dev->priv; */
-
        printk(KERN_DEBUG
               "##### WaveLAN i82586 receiver unit status: #####\n");
        printk(KERN_DEBUG "ru:");
@@ -1153,7 +1146,7 @@ static void wv_cu_show_one(struct net_device * dev, net_local * lp, int i, u16 p
  */
 static void wv_cu_show(struct net_device * dev)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned int i;
        u16 p;
 
@@ -1195,7 +1188,7 @@ static void wv_local_show(struct net_device * dev)
 {
        net_local *lp;
 
-       lp = (net_local *) dev->priv;
+       lp = netdev_priv(dev);
 
        printk(KERN_DEBUG "local:");
        printk(" tx_n_in_use=%d,", lp->tx_n_in_use);
@@ -1220,14 +1213,13 @@ static inline void wv_packet_info(u8 * p,       /* Packet to dump */
 {                              /* Name of the function */
        int i;
        int maxi;
-       DECLARE_MAC_BUF(mac);
 
        printk(KERN_DEBUG
-              "%s: %s(): dest %s, length %d\n",
-              msg1, msg2, print_mac(mac, p), length);
+              "%s: %s(): dest %pM, length %d\n",
+              msg1, msg2, p, length);
        printk(KERN_DEBUG
-              "%s: %s(): src %s, type 0x%02X%02X\n",
-              msg1, msg2, print_mac(mac, &p[6]), p[12], p[13]);
+              "%s: %s(): src %pM, type 0x%02X%02X\n",
+              msg1, msg2, &p[6], p[12], p[13]);
 
 #ifdef DEBUG_PACKET_DUMP
 
@@ -1256,11 +1248,8 @@ static inline void wv_packet_info(u8 * p,        /* Packet to dump */
 static void wv_init_info(struct net_device * dev)
 {
        short ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        psa_t psa;
-#ifdef DEBUG_BASIC_SHOW
-       DECLARE_MAC_BUF(mac);
-#endif
 
        /* Read the parameter storage area */
        psa_read(ioaddr, lp->hacr, 0, (unsigned char *) &psa, sizeof(psa));
@@ -1277,8 +1266,8 @@ static void wv_init_info(struct net_device * dev)
 
 #ifdef DEBUG_BASIC_SHOW
        /* Now, let's go for the basic stuff. */
-       printk(KERN_NOTICE "%s: WaveLAN at %#x, %s, IRQ %d",
-              dev->name, ioaddr, print_mac(mac, dev->dev_addr), dev->irq);
+       printk(KERN_NOTICE "%s: WaveLAN at %#x, %pM, IRQ %d",
+              dev->name, ioaddr, dev->dev_addr, dev->irq);
 
        /* Print current network ID. */
        if (psa.psa_nwid_select)
@@ -1369,7 +1358,7 @@ static en_stats *wavelan_get_stats(struct net_device * dev)
        printk(KERN_DEBUG "%s: <>wavelan_get_stats()\n", dev->name);
 #endif
 
-       return (&((net_local *) dev->priv)->stats);
+       return &((net_local *)netdev_priv(dev))->stats;
 }
 
 /*------------------------------------------------------------------*/
@@ -1382,7 +1371,7 @@ static en_stats *wavelan_get_stats(struct net_device * dev)
  */
 static void wavelan_set_multicast_list(struct net_device * dev)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
 
 #ifdef DEBUG_IOCTL_TRACE
        printk(KERN_DEBUG "%s: ->wavelan_set_multicast_list()\n",
@@ -1716,7 +1705,7 @@ static inline void wl_spy_gather(struct net_device * dev,
  */
 static inline void wl_his_gather(struct net_device * dev, u8 * stats)
 {                              /* Statistics to gather */
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        u8 level = stats[0] & MMR_SIGNAL_LVL;
        int i;
 
@@ -1753,7 +1742,7 @@ static int wavelan_set_nwid(struct net_device *dev,
                            char *extra)
 {
        unsigned long ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;        /* lp is not unused */
+       net_local *lp = netdev_priv(dev);       /* lp is not unused */
        psa_t psa;
        mm_t m;
        unsigned long flags;
@@ -1812,7 +1801,7 @@ static int wavelan_get_nwid(struct net_device *dev,
                            char *extra)
 {
        unsigned long ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;        /* lp is not unused */
+       net_local *lp = netdev_priv(dev);       /* lp is not unused */
        psa_t psa;
        unsigned long flags;
        int ret = 0;
@@ -1844,7 +1833,7 @@ static int wavelan_set_freq(struct net_device *dev,
                            char *extra)
 {
        unsigned long ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;        /* lp is not unused */
+       net_local *lp = netdev_priv(dev);       /* lp is not unused */
        unsigned long flags;
        int ret;
 
@@ -1874,7 +1863,7 @@ static int wavelan_get_freq(struct net_device *dev,
                            char *extra)
 {
        unsigned long ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;        /* lp is not unused */
+       net_local *lp = netdev_priv(dev);       /* lp is not unused */
        psa_t psa;
        unsigned long flags;
        int ret = 0;
@@ -1920,7 +1909,7 @@ static int wavelan_set_sens(struct net_device *dev,
                            char *extra)
 {
        unsigned long ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;        /* lp is not unused */
+       net_local *lp = netdev_priv(dev);       /* lp is not unused */
        psa_t psa;
        unsigned long flags;
        int ret = 0;
@@ -1956,7 +1945,7 @@ static int wavelan_get_sens(struct net_device *dev,
                            char *extra)
 {
        unsigned long ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;        /* lp is not unused */
+       net_local *lp = netdev_priv(dev);       /* lp is not unused */
        psa_t psa;
        unsigned long flags;
        int ret = 0;
@@ -1987,7 +1976,7 @@ static int wavelan_set_encode(struct net_device *dev,
                              char *extra)
 {
        unsigned long ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;        /* lp is not unused */
+       net_local *lp = netdev_priv(dev);       /* lp is not unused */
        unsigned long flags;
        psa_t psa;
        int ret = 0;
@@ -2057,7 +2046,7 @@ static int wavelan_get_encode(struct net_device *dev,
                              char *extra)
 {
        unsigned long ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;        /* lp is not unused */
+       net_local *lp = netdev_priv(dev);       /* lp is not unused */
        psa_t psa;
        unsigned long flags;
        int ret = 0;
@@ -2104,7 +2093,7 @@ static int wavelan_get_range(struct net_device *dev,
                             char *extra)
 {
        unsigned long ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;        /* lp is not unused */
+       net_local *lp = netdev_priv(dev);       /* lp is not unused */
        struct iw_range *range = (struct iw_range *) extra;
        unsigned long flags;
        int ret = 0;
@@ -2179,7 +2168,7 @@ static int wavelan_set_qthr(struct net_device *dev,
                            char *extra)
 {
        unsigned long ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;        /* lp is not unused */
+       net_local *lp = netdev_priv(dev);       /* lp is not unused */
        psa_t psa;
        unsigned long flags;
 
@@ -2211,7 +2200,7 @@ static int wavelan_get_qthr(struct net_device *dev,
                            char *extra)
 {
        unsigned long ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;        /* lp is not unused */
+       net_local *lp = netdev_priv(dev);       /* lp is not unused */
        psa_t psa;
        unsigned long flags;
 
@@ -2239,7 +2228,7 @@ static int wavelan_set_histo(struct net_device *dev,
                             union iwreq_data *wrqu,
                             char *extra)
 {
-       net_local *lp = (net_local *) dev->priv;        /* lp is not unused */
+       net_local *lp = netdev_priv(dev);       /* lp is not unused */
 
        /* Check the number of intervals. */
        if (wrqu->data.length > 16) {
@@ -2282,7 +2271,7 @@ static int wavelan_get_histo(struct net_device *dev,
                             union iwreq_data *wrqu,
                             char *extra)
 {
-       net_local *lp = (net_local *) dev->priv;        /* lp is not unused */
+       net_local *lp = netdev_priv(dev);       /* lp is not unused */
 
        /* Set the number of intervals. */
        wrqu->data.length = lp->his_number;
@@ -2386,7 +2375,7 @@ static const struct iw_handler_def        wavelan_handler_def =
 static iw_stats *wavelan_get_wireless_stats(struct net_device * dev)
 {
        unsigned long ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        mmr_t m;
        iw_stats *wstats;
        unsigned long flags;
@@ -2461,7 +2450,7 @@ static iw_stats *wavelan_get_wireless_stats(struct net_device * dev)
 static void
 wv_packet_read(struct net_device * dev, u16 buf_off, int sksize)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long ioaddr = dev->base_addr;
        struct sk_buff *skb;
 
@@ -2537,7 +2526,6 @@ wv_packet_read(struct net_device * dev, u16 buf_off, int sksize)
        netif_rx(skb);
 
        /* Keep statistics up to date */
-       dev->last_rx = jiffies;
        lp->stats.rx_packets++;
        lp->stats.rx_bytes += sksize;
 
@@ -2556,7 +2544,7 @@ wv_packet_read(struct net_device * dev, u16 buf_off, int sksize)
 static void wv_receive(struct net_device * dev)
 {
        unsigned long ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        fd_t fd;
        rbd_t rbd;
        int nreaped = 0;
@@ -2738,7 +2726,7 @@ static void wv_receive(struct net_device * dev)
  */
 static int wv_packet_write(struct net_device * dev, void *buf, short length)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long ioaddr = dev->base_addr;
        unsigned short txblock;
        unsigned short txpred;
@@ -2869,7 +2857,7 @@ static int wv_packet_write(struct net_device * dev, void *buf, short length)
  */
 static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long flags;
        char data[ETH_ZLEN];
 
@@ -2937,7 +2925,7 @@ static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev)
 static int wv_mmc_init(struct net_device * dev)
 {
        unsigned long ioaddr = dev->base_addr;
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        psa_t psa;
        mmw_t m;
        int configured;
@@ -3108,7 +3096,7 @@ static int wv_mmc_init(struct net_device * dev)
  */
 static int wv_ru_start(struct net_device * dev)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long ioaddr = dev->base_addr;
        u16 scb_cs;
        fd_t fd;
@@ -3200,7 +3188,7 @@ static int wv_ru_start(struct net_device * dev)
  */
 static int wv_cu_start(struct net_device * dev)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long ioaddr = dev->base_addr;
        int i;
        u16 txblock;
@@ -3301,7 +3289,7 @@ static int wv_cu_start(struct net_device * dev)
  */
 static int wv_82586_start(struct net_device * dev)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long ioaddr = dev->base_addr;
        scp_t scp;              /* system configuration pointer */
        iscp_t iscp;            /* intermediate scp */
@@ -3433,7 +3421,7 @@ static int wv_82586_start(struct net_device * dev)
  */
 static void wv_82586_config(struct net_device * dev)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long ioaddr = dev->base_addr;
        unsigned short txblock;
        unsigned short txpred;
@@ -3565,15 +3553,11 @@ static void wv_82586_config(struct net_device * dev)
                              WAVELAN_ADDR_SIZE >> 1);
 
 #ifdef DEBUG_CONFIG_INFO
- {
-               DECLARE_MAC_BUF(mac);
                printk(KERN_DEBUG
                       "%s: wv_82586_config(): set %d multicast addresses:\n",
                       dev->name, lp->mc_count);
                for (dmi = dev->mc_list; dmi; dmi = dmi->next)
-                       printk(KERN_DEBUG " %s\n",
-                              print_mac(mac, dmi->dmi_addr));
- }
+                       printk(KERN_DEBUG " %pM\n", dmi->dmi_addr);
 #endif
        }
 
@@ -3613,7 +3597,7 @@ static void wv_82586_config(struct net_device * dev)
  */
 static void wv_82586_stop(struct net_device * dev)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long ioaddr = dev->base_addr;
        u16 scb_cmd;
 
@@ -3650,7 +3634,7 @@ static void wv_82586_stop(struct net_device * dev)
  */
 static int wv_hw_reset(struct net_device * dev)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long ioaddr = dev->base_addr;
 
 #ifdef DEBUG_CONFIG_TRACE
@@ -3751,7 +3735,7 @@ static irqreturn_t wavelan_interrupt(int irq, void *dev_id)
        printk(KERN_DEBUG "%s: ->wavelan_interrupt()\n", dev->name);
 #endif
 
-       lp = (net_local *) dev->priv;
+       lp = netdev_priv(dev);
        ioaddr = dev->base_addr;
 
 #ifdef DEBUG_INTERRUPT_INFO
@@ -3894,7 +3878,7 @@ static irqreturn_t wavelan_interrupt(int irq, void *dev_id)
  */
 static void wavelan_watchdog(struct net_device *       dev)
 {
-       net_local *     lp = (net_local *)dev->priv;
+       net_local *lp = netdev_priv(dev);
        u_long          ioaddr = dev->base_addr;
        unsigned long   flags;
        unsigned int    nreaped;
@@ -3974,7 +3958,7 @@ static void wavelan_watchdog(struct net_device *  dev)
  */
 static int wavelan_open(struct net_device * dev)
 {
-       net_local *     lp = (net_local *)dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long   flags;
 
 #ifdef DEBUG_CALLBACK_TRACE
@@ -4029,7 +4013,7 @@ static int wavelan_open(struct net_device * dev)
  */
 static int wavelan_close(struct net_device * dev)
 {
-       net_local *lp = (net_local *) dev->priv;
+       net_local *lp = netdev_priv(dev);
        unsigned long flags;
 
 #ifdef DEBUG_CALLBACK_TRACE
@@ -4128,8 +4112,8 @@ static int __init wavelan_config(struct net_device *dev, unsigned short ioaddr)
        dev->if_port = 0;
 
        /* Initialize device structures */
-       memset(dev->priv, 0, sizeof(net_local));
-       lp = (net_local *) dev->priv;
+       memset(netdev_priv(dev), 0, sizeof(net_local));
+       lp = netdev_priv(dev);
 
        /* Back link to the device structure. */
        lp->dev = dev;
index e124b1d6267afa03cc5e3c149d8ab77080159b2c..de717f8ffd61061a5caccfa92cb62d70403b1087 100644 (file)
@@ -1020,7 +1020,6 @@ wv_82593_reconfig(struct net_device *     dev)
 static void
 wv_psa_show(psa_t *    p)
 {
-  DECLARE_MAC_BUF(mac);
   printk(KERN_DEBUG "##### wavelan psa contents: #####\n");
   printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n",
         p->psa_io_base_addr_1,
@@ -1034,13 +1033,10 @@ wv_psa_show(psa_t *     p)
   printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params);
   printk("psa_int_req_no: %d\n", p->psa_int_req_no);
 #ifdef DEBUG_SHOW_UNUSED
-  printk(KERN_DEBUG "psa_unused0[]: %s\n",
-        print_mac(mac, p->psa_unused0));
+  printk(KERN_DEBUG "psa_unused0[]: %pM\n", p->psa_unused0);
 #endif /* DEBUG_SHOW_UNUSED */
-  printk(KERN_DEBUG "psa_univ_mac_addr[]: %s\n",
-        print_mac(mac, p->psa_univ_mac_addr));
-  printk(KERN_DEBUG "psa_local_mac_addr[]: %s\n",
-        print_mac(mac, p->psa_local_mac_addr));
+  printk(KERN_DEBUG "psa_univ_mac_addr[]: %pM\n", p->psa_univ_mac_addr);
+  printk(KERN_DEBUG "psa_local_mac_addr[]: %pM\n", p->psa_local_mac_addr);
   printk(KERN_DEBUG "psa_univ_local_sel: %d, ", p->psa_univ_local_sel);
   printk("psa_comp_number: %d, ", p->psa_comp_number);
   printk("psa_thr_pre_set: 0x%02x\n", p->psa_thr_pre_set);
@@ -1238,12 +1234,11 @@ wv_packet_info(u_char *         p,              /* Packet to dump */
 {
   int          i;
   int          maxi;
-  DECLARE_MAC_BUF(mac);
 
-  printk(KERN_DEBUG "%s: %s(): dest %s, length %d\n",
-        msg1, msg2, print_mac(mac, p), length);
-  printk(KERN_DEBUG "%s: %s(): src %s, type 0x%02X%02X\n",
-        msg1, msg2, print_mac(mac, &p[6]), p[12], p[13]);
+  printk(KERN_DEBUG "%s: %s(): dest %pM, length %d\n",
+        msg1, msg2, p, length);
+  printk(KERN_DEBUG "%s: %s(): src %pM, type 0x%02X%02X\n",
+        msg1, msg2, &p[6], p[12], p[13]);
 
 #ifdef DEBUG_PACKET_DUMP
 
@@ -1274,7 +1269,6 @@ wv_init_info(struct net_device *  dev)
 {
   unsigned int base = dev->base_addr;
   psa_t                psa;
-  DECLARE_MAC_BUF(mac);
 
   /* Read the parameter storage area */
   psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
@@ -1291,10 +1285,8 @@ wv_init_info(struct net_device * dev)
 
 #ifdef DEBUG_BASIC_SHOW
   /* Now, let's go for the basic stuff */
-  printk(KERN_NOTICE "%s: WaveLAN: port %#x, irq %d, "
-        "hw_addr %s",
-        dev->name, base, dev->irq,
-        print_mac(mac, dev->dev_addr));
+  printk(KERN_NOTICE "%s: WaveLAN: port %#x, irq %d, hw_addr %pM",
+        dev->name, base, dev->irq, dev->dev_addr);
 
   /* Print current network id */
   if(psa.psa_nwid_select)
@@ -2243,13 +2235,7 @@ static int wavelan_set_wap(struct net_device *dev,
                           char *extra)
 {
 #ifdef DEBUG_IOCTL_INFO
-       printk(KERN_DEBUG "Set AP to : %02X:%02X:%02X:%02X:%02X:%02X\n",
-              wrqu->ap_addr.sa_data[0],
-              wrqu->ap_addr.sa_data[1],
-              wrqu->ap_addr.sa_data[2],
-              wrqu->ap_addr.sa_data[3],
-              wrqu->ap_addr.sa_data[4],
-              wrqu->ap_addr.sa_data[5]);
+       printk(KERN_DEBUG "Set AP to : %pM\n", wrqu->ap_addr.sa_data);
 #endif /* DEBUG_IOCTL_INFO */
 
        return -EOPNOTSUPP;
@@ -2892,7 +2878,6 @@ wv_packet_read(struct net_device *                dev,
   netif_rx(skb);
 
   /* Keep stats up to date */
-  dev->last_rx = jiffies;
   lp->stats.rx_packets++;
   lp->stats.rx_bytes += sksize;
 
@@ -3647,12 +3632,10 @@ wv_82593_config(struct net_device *     dev)
       int                      addrs_len = WAVELAN_ADDR_SIZE * lp->mc_count;
 
 #ifdef DEBUG_CONFIG_INFO
-      DECLARE_MAC_BUF(mac);
       printk(KERN_DEBUG "%s: wv_hw_config(): set %d multicast addresses:\n",
             dev->name, lp->mc_count);
       for(dmi=dev->mc_list; dmi; dmi=dmi->next)
-       printk(KERN_DEBUG " %s\n",
-              print_mac(mac, dmi->dmi_addr));
+       printk(KERN_DEBUG " %pM\n", dmi->dmi_addr);
 #endif
 
       /* Initialize adapter's ethernet multicast addresses */
index 65ceb088f7000c9e06b371605857302d59beeeff..59bb3a55ab48c82838da43c1545d9863560bf572 100644 (file)
@@ -2,7 +2,7 @@
 #define __WL3501_H__
 
 #include <linux/spinlock.h>
-#include <net/ieee80211.h>
+#include <linux/ieee80211.h>
 
 /* define for WLA 2.0 */
 #define WL3501_BLKSZ 256
@@ -548,7 +548,7 @@ struct wl3501_80211_tx_plcp_hdr {
 
 struct wl3501_80211_tx_hdr {
        struct wl3501_80211_tx_plcp_hdr pclp_hdr;
-       struct ieee80211_hdr_4addr              mac_hdr;
+       struct ieee80211_hdr            mac_hdr;
 } __attribute__ ((packed));
 
 /*
index 68789c6e1ce9ac96cb180b7c8a6d798719764294..c99a1b6b948fca668dfbf31b82ace895bb005de7 100644 (file)
@@ -860,10 +860,9 @@ static int wl3501_esbq_confirm(struct wl3501_card *this)
 static void wl3501_online(struct net_device *dev)
 {
        struct wl3501_card *this = netdev_priv(dev);
-       DECLARE_MAC_BUF(mac);
 
-       printk(KERN_INFO "%s: Wireless LAN online. BSSID: %s\n",
-              dev->name, print_mac(mac, this->bssid));
+       printk(KERN_INFO "%s: Wireless LAN online. BSSID: %pM\n",
+              dev->name, this->bssid);
        netif_wake_queue(dev);
 }
 
@@ -1014,7 +1013,6 @@ static inline void wl3501_md_ind_interrupt(struct net_device *dev,
                wl3501_receive(this, skb->data, pkt_len);
                skb_put(skb, pkt_len);
                skb->protocol   = eth_type_trans(skb, dev);
-               dev->last_rx    = jiffies;
                this->stats.rx_packets++;
                this->stats.rx_bytes += skb->len;
                netif_rx(skb);
@@ -1965,7 +1963,6 @@ static int wl3501_config(struct pcmcia_device *link)
        struct net_device *dev = link->priv;
        int i = 0, j, last_fn, last_ret;
        struct wl3501_card *this;
-       DECLARE_MAC_BUF(mac);
 
        /* Try allocating IO ports.  This tries a few fixed addresses.  If you
         * want, you can also read the card's config table to pick addresses --
@@ -2024,9 +2021,9 @@ static int wl3501_config(struct pcmcia_device *link)
 
        /* print probe information */
        printk(KERN_INFO "%s: wl3501 @ 0x%3.3x, IRQ %d, "
-              "MAC addr in flash ROM:%s\n",
+              "MAC addr in flash ROM:%pM\n",
               dev->name, this->base_addr, (int)dev->irq,
-              print_mac(mac, dev->dev_addr));
+              dev->dev_addr);
        /*
         * Initialize card parameters - added by jss
         */
index b16ec6e5f0e3913115fe6a40b15ae9a9e0bde4ca..1134e2fb18902bd0a80444fd4ee7b3427157e496 100644 (file)
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
+#include <linux/ieee80211.h>
 #include <net/iw_handler.h>
 #include <linux/string.h>
 #include <linux/if_arp.h>
 #include <linux/firmware.h>
-#include <net/ieee80211.h>
 #include "zd1201.h"
 
 static struct usb_device_id zd1201_table[] = {
@@ -328,7 +328,6 @@ static void zd1201_usbrx(struct urb *urb)
                        memcpy(skb_put(skb, 2), &data[datalen-24], 2);
                        memcpy(skb_put(skb, len), data, len);
                        skb->protocol = eth_type_trans(skb, zd->dev);
-                       skb->dev->last_rx = jiffies;
                        zd->stats.rx_packets++;
                        zd->stats.rx_bytes += skb->len;
                        netif_rx(skb);
@@ -346,7 +345,7 @@ static void zd1201_usbrx(struct urb *urb)
                                frag = kmalloc(sizeof(*frag), GFP_ATOMIC);
                                if (!frag)
                                        goto resubmit;
-                               skb = dev_alloc_skb(IEEE80211_DATA_LEN +14+2);
+                               skb = dev_alloc_skb(IEEE80211_MAX_DATA_LEN +14+2);
                                if (!skb) {
                                        kfree(frag);
                                        goto resubmit;
@@ -385,7 +384,6 @@ static void zd1201_usbrx(struct urb *urb)
                        memcpy(skb_put(skb, len), data+8, len);
                }
                skb->protocol = eth_type_trans(skb, zd->dev);
-               skb->dev->last_rx = jiffies;
                zd->stats.rx_packets++;
                zd->stats.rx_bytes += skb->len;
                netif_rx(skb);
index e0ac58b8ff1fafe3e57a042f8e2a2ddfafeacc30..f1519143f8a65e80fca00501be81e5fd456cec73 100644 (file)
@@ -378,7 +378,6 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
                [0] = { .addr = CR_MAC_ADDR_P1 },
                [1] = { .addr = CR_MAC_ADDR_P2 },
        };
-       DECLARE_MAC_BUF(mac);
 
        if (mac_addr) {
                reqs[0].value = (mac_addr[3] << 24)
@@ -387,8 +386,7 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
                              |  mac_addr[0];
                reqs[1].value = (mac_addr[5] <<  8)
                              |  mac_addr[4];
-               dev_dbg_f(zd_chip_dev(chip),
-                       "mac addr %s\n", print_mac(mac, mac_addr));
+               dev_dbg_f(zd_chip_dev(chip), "mac addr %pM\n", mac_addr);
        } else {
                dev_dbg_f(zd_chip_dev(chip), "set NULL mac\n");
        }
index fe1867b25ff7fb522e57927dfa6180f5f0f177bb..07513e48b8f250a1dd788dc3f7fb900fa2366592 100644 (file)
@@ -171,7 +171,7 @@ int zd_mac_init_hw(struct ieee80211_hw *hw)
 
        r = zd_reg2alpha2(mac->regdomain, alpha2);
        if (!r)
-               regulatory_hint(hw->wiphy, alpha2, NULL);
+               regulatory_hint(hw->wiphy, alpha2);
 
        r = 0;
 disable_int:
@@ -296,15 +296,14 @@ static void zd_op_stop(struct ieee80211_hw *hw)
  * If no status information has been requested, the skb is freed.
  */
 static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
-                     u32 flags, int ackssi, bool success)
+                     int ackssi, bool success)
 {
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
-       memset(&info->status, 0, sizeof(info->status));
+       ieee80211_tx_info_clear_status(info);
 
-       if (!success)
-               info->status.excessive_retries = 1;
-       info->flags |= flags;
+       if (success)
+               info->flags |= IEEE80211_TX_STAT_ACK;
        info->status.ack_signal = ackssi;
        ieee80211_tx_status_irqsafe(hw, skb);
 }
@@ -326,7 +325,7 @@ void zd_mac_tx_failed(struct ieee80211_hw *hw)
        if (skb == NULL)
                return;
 
-       tx_status(hw, skb, 0, 0, 0);
+       tx_status(hw, skb, 0, 0);
 }
 
 /**
@@ -342,12 +341,12 @@ void zd_mac_tx_failed(struct ieee80211_hw *hw)
 void zd_mac_tx_to_dev(struct sk_buff *skb, int error)
 {
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_hw *hw = info->driver_data[0];
+       struct ieee80211_hw *hw = info->rate_driver_data[0];
 
        skb_pull(skb, sizeof(struct zd_ctrlset));
        if (unlikely(error ||
            (info->flags & IEEE80211_TX_CTL_NO_ACK))) {
-               tx_status(hw, skb, 0, 0, !error);
+               tx_status(hw, skb, 0, !error);
        } else {
                struct sk_buff_head *q =
                        &zd_hw_mac(hw)->ack_wait_queue;
@@ -406,7 +405,8 @@ static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length)
 }
 
 static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
-                          struct ieee80211_hdr *header, u32 flags)
+                          struct ieee80211_hdr *header,
+                          struct ieee80211_tx_info *info)
 {
        /*
         * CONTROL TODO:
@@ -417,7 +417,7 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
        cs->control = 0;
 
        /* First fragment */
-       if (flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+       if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
                cs->control |= ZD_CS_NEED_RANDOM_BACKOFF;
 
        /* Multicast */
@@ -428,10 +428,10 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
        if (ieee80211_is_pspoll(header->frame_control))
                cs->control |= ZD_CS_PS_POLL_FRAME;
 
-       if (flags & IEEE80211_TX_CTL_USE_RTS_CTS)
+       if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
                cs->control |= ZD_CS_RTS;
 
-       if (flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
+       if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
                cs->control |= ZD_CS_SELF_CTS;
 
        /* FIXME: Management frame? */
@@ -517,12 +517,12 @@ static int fill_ctrlset(struct zd_mac *mac,
        txrate = ieee80211_get_tx_rate(mac->hw, info);
 
        cs->modulation = txrate->hw_value;
-       if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE)
+       if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
                cs->modulation = txrate->hw_value_short;
 
        cs->tx_length = cpu_to_le16(frag_len);
 
-       cs_set_control(mac, cs, hdr, info->flags);
+       cs_set_control(mac, cs, hdr, info);
 
        packet_length = frag_len + sizeof(struct zd_ctrlset) + 10;
        ZD_ASSERT(packet_length <= 0xffff);
@@ -577,7 +577,7 @@ static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        if (r)
                return r;
 
-       info->driver_data[0] = hw;
+       info->rate_driver_data[0] = hw;
 
        r = zd_usb_tx(&mac->chip.usb, skb);
        if (r)
@@ -618,7 +618,7 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
                if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1)))
                {
                        __skb_unlink(skb, q);
-                       tx_status(hw, skb, IEEE80211_TX_STAT_ACK, stats->signal, 1);
+                       tx_status(hw, skb, stats->signal, 1);
                        goto out;
                }
        }
@@ -743,9 +743,11 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw,
        zd_write_mac_addr(&mac->chip, NULL);
 }
 
-static int zd_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+static int zd_op_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct zd_mac *mac = zd_hw_mac(hw);
+       struct ieee80211_conf *conf = &hw->conf;
+
        return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
 }
 
@@ -852,14 +854,12 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw,
        if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) {
                zd_mc_add_all(&hash);
        } else {
-               DECLARE_MAC_BUF(macbuf);
-
                zd_mc_clear(&hash);
                for (i = 0; i < mc_count; i++) {
                        if (!mclist)
                                break;
-                       dev_dbg_f(zd_mac_dev(mac), "mc addr %s\n",
-                                 print_mac(macbuf, mclist->dmi_addr));
+                       dev_dbg_f(zd_mac_dev(mac), "mc addr %pM\n",
+                                 mclist->dmi_addr);
                        zd_mc_add_addr(&hash, mclist->dmi_addr);
                        mclist = mclist->next;
                }
index a3ccd8c1c716957bd669ec678681bc2fcfe1f806..04c1396669656261d87cf6dbc53a6bc1c4b748ff 100644 (file)
@@ -909,7 +909,7 @@ free_urb:
         * it might be freed by zd_mac_tx_to_dev or mac80211)
         */
        info = IEEE80211_SKB_CB(skb);
-       usb = &zd_hw_mac(info->driver_data[0])->chip.usb;
+       usb = &zd_hw_mac(info->rate_driver_data[0])->chip.usb;
        zd_mac_tx_to_dev(skb, urb->status);
        free_tx_urb(usb, urb);
        tx_dec_submitted_urbs(usb);
index c6948d8f53f62fbf4f6b06cf3292ebe80828132a..4b21bcf4af995e14d5823f0343a190ff2331b97c 100644 (file)
@@ -841,7 +841,6 @@ static int handle_incoming_queue(struct net_device *dev,
 
                /* Pass it up. */
                netif_receive_skb(skb);
-               dev->last_rx = jiffies;
        }
 
        return packets_dropped;
index da42aa06a3babc7982b37f820ebd9172cab0ffd6..03a3f34e90393c43202db9731caac53cd25ed40a 100644 (file)
@@ -239,8 +239,6 @@ int __init xtsonic_probe(struct platform_device *pdev)
        struct resource *resmem, *resirq;
        int err = 0;
 
-       DECLARE_MAC_BUF(mac);
-
        if ((resmem = platform_get_resource(pdev, IORESOURCE_MEM, 0)) == NULL)
                return -ENODEV;
 
@@ -263,8 +261,8 @@ int __init xtsonic_probe(struct platform_device *pdev)
        if ((err = register_netdev(dev)))
                goto out1;
 
-       printk("%s: SONIC ethernet @%08lx, MAC %s, IRQ %d\n", dev->name,
-              dev->base_addr, print_mac(mac, dev->dev_addr), dev->irq);
+       printk("%s: SONIC ethernet @%08lx, MAC %pM, IRQ %d\n", dev->name,
+              dev->base_addr, dev->dev_addr, dev->irq);
 
        return 0;
 
index 57e1f495b9fc0456db009a9540ec0f7111295b51..d8dbc57f3e564f938acdc19c415d55902a2650a4 100644 (file)
@@ -374,7 +374,6 @@ static int __devinit yellowfin_init_one(struct pci_dev *pdev,
 #else
        int bar = 1;
 #endif
-       DECLARE_MAC_BUF(mac);
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -481,10 +480,10 @@ static int __devinit yellowfin_init_one(struct pci_dev *pdev,
        if (i)
                goto err_out_unmap_status;
 
-       printk(KERN_INFO "%s: %s type %8x at %p, %s, IRQ %d.\n",
+       printk(KERN_INFO "%s: %s type %8x at %p, %pM, IRQ %d.\n",
                   dev->name, pci_id_tbl[chip_idx].name,
                   ioread32(ioaddr + ChipRev), ioaddr,
-                  print_mac(mac, dev->dev_addr), irq);
+                  dev->dev_addr, irq);
 
        if (np->drv_flags & HasMII) {
                int phy, phy_idx = 0;
@@ -1100,11 +1099,9 @@ static int yellowfin_rx(struct net_device *dev)
                        memcmp(le32_to_cpu(yp->rx_ring_dma +
                                entry*sizeof(struct yellowfin_desc)),
                                "\377\377\377\377\377\377", 6) != 0) {
-                       if (bogus_rx++ == 0) {
-                               DECLARE_MAC_BUF(mac);
-                               printk(KERN_WARNING "%s: Bad frame to %s\n",
-                                          dev->name, print_mac(mac, buf_addr));
-                       }
+                       if (bogus_rx++ == 0)
+                               printk(KERN_WARNING "%s: Bad frame to %pM\n",
+                                          dev->name, buf_addr);
 #endif
                } else {
                        struct sk_buff *skb;
@@ -1141,7 +1138,6 @@ static int yellowfin_rx(struct net_device *dev)
                        }
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
-                       dev->last_rx = jiffies;
                        dev->stats.rx_packets++;
                        dev->stats.rx_bytes += pkt_len;
                }
index a86c022d6a9494e4f96822095b06366d7531054b..f0b15c9347d0dae517497544ef629b9e0f8d80c1 100644 (file)
@@ -167,7 +167,7 @@ static void znet_tx_timeout (struct net_device *dev);
 /* Request needed resources */
 static int znet_request_resources (struct net_device *dev)
 {
-       struct znet_private *znet = dev->priv;
+       struct znet_private *znet = netdev_priv(dev);
        unsigned long flags;
 
        if (request_irq (dev->irq, &znet_interrupt, 0, "ZNet", dev))
@@ -201,7 +201,7 @@ static int znet_request_resources (struct net_device *dev)
 
 static void znet_release_resources (struct net_device *dev)
 {
-       struct znet_private *znet = dev->priv;
+       struct znet_private *znet = netdev_priv(dev);
        unsigned long flags;
 
        release_region (znet->sia_base, znet->sia_size);
@@ -216,7 +216,7 @@ static void znet_release_resources (struct net_device *dev)
 /* Keep the magical SIA stuff in a single function... */
 static void znet_transceiver_power (struct net_device *dev, int on)
 {
-       struct znet_private *znet = dev->priv;
+       struct znet_private *znet = netdev_priv(dev);
        unsigned char v;
 
        /* Turn on/off the 82501 SIA, using zenith-specific magic. */
@@ -235,7 +235,7 @@ static void znet_transceiver_power (struct net_device *dev, int on)
    Also used from hardware_init. */
 static void znet_set_multicast_list (struct net_device *dev)
 {
-       struct znet_private *znet = dev->priv;
+       struct znet_private *znet = netdev_priv(dev);
        short ioaddr = dev->base_addr;
        struct i82593_conf_block *cfblk = &znet->i593_init;
 
@@ -370,7 +370,6 @@ static int __init znet_probe (void)
        struct net_device *dev;
        char *p;
        int err = -ENOMEM;
-       DECLARE_MAC_BUF(mac);
 
        /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */
        for(p = (char *)phys_to_virt(0xf0000); p < (char *)phys_to_virt(0x100000); p++)
@@ -387,7 +386,7 @@ static int __init znet_probe (void)
        if (!dev)
                return -ENOMEM;
 
-       znet = dev->priv;
+       znet = netdev_priv(dev);
 
        netinfo = (struct netidblk *)p;
        dev->base_addr = netinfo->iobase1;
@@ -397,9 +396,9 @@ static int __init znet_probe (void)
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = netinfo->netid[i];
 
-       printk(KERN_INFO "%s: ZNET at %#3lx, %s"
+       printk(KERN_INFO "%s: ZNET at %#3lx, %pM"
               ", using IRQ %d DMA %d and %d.\n",
-              dev->name, dev->base_addr, print_mac(mac, dev->dev_addr),
+              dev->name, dev->base_addr, dev->dev_addr,
               dev->irq, netinfo->dma1, netinfo->dma2);
 
        if (znet_debug > 1) {
@@ -531,7 +530,7 @@ static void znet_tx_timeout (struct net_device *dev)
 static int znet_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
        int ioaddr = dev->base_addr;
-       struct znet_private *znet = dev->priv;
+       struct znet_private *znet = netdev_priv(dev);
        unsigned long flags;
        short length = skb->len;
 
@@ -601,7 +600,7 @@ static int znet_send_packet(struct sk_buff *skb, struct net_device *dev)
 static irqreturn_t znet_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
-       struct znet_private *znet = dev->priv;
+       struct znet_private *znet = netdev_priv(dev);
        int ioaddr;
        int boguscnt = 20;
        int handled = 0;
@@ -679,7 +678,7 @@ static irqreturn_t znet_interrupt(int irq, void *dev_id)
 
 static void znet_rx(struct net_device *dev)
 {
-       struct znet_private *znet = dev->priv;
+       struct znet_private *znet = netdev_priv(dev);
        int ioaddr = dev->base_addr;
        int boguscount = 1;
        short next_frame_end_offset = 0;                /* Offset of next frame start. */
@@ -786,7 +785,6 @@ static void znet_rx(struct net_device *dev)
                  }
                  skb->protocol=eth_type_trans(skb,dev);
                  netif_rx(skb);
-                 dev->last_rx = jiffies;
                  dev->stats.rx_packets++;
                  dev->stats.rx_bytes += pkt_len;
                }
@@ -829,7 +827,7 @@ static void show_dma(struct net_device *dev)
 {
        short ioaddr = dev->base_addr;
        unsigned char stat = inb (ioaddr);
-       struct znet_private *znet = dev->priv;
+       struct znet_private *znet = netdev_priv(dev);
        unsigned long flags;
        short dma_port = ((znet->tx_dma&3)<<2) + IO_DMA2_BASE;
        unsigned addr = inb(dma_port);
@@ -852,7 +850,7 @@ static void hardware_init(struct net_device *dev)
 {
        unsigned long flags;
        short ioaddr = dev->base_addr;
-       struct znet_private *znet = dev->priv;
+       struct znet_private *znet = netdev_priv(dev);
 
        znet->rx_cur = znet->rx_start;
        znet->tx_cur = znet->tx_start;
@@ -914,7 +912,7 @@ static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset)
 static __exit void znet_cleanup (void)
 {
        if (znet_dev) {
-               struct znet_private *znet = znet_dev->priv;
+               struct znet_private *znet = netdev_priv(znet_dev);
 
                unregister_netdev (znet_dev);
                kfree (znet->rx_start);
index 3926b2aa9cca4c7aaa761fbc486e65d727bf762b..9c73df4a0d307b781de5311a1ad8f148f826f62c 100644 (file)
@@ -151,7 +151,6 @@ static int __devinit zorro8390_init(struct net_device *dev,
        0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
        0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
     };
-    DECLARE_MAC_BUF(mac);
 
     /* Reset card. Who knows what dain-bramaged state it was left in. */
     {
@@ -216,7 +215,7 @@ static int __devinit zorro8390_init(struct net_device *dev,
        dev->dev_addr[i] = SA_prom[i];
 
 #ifdef DEBUG
-    printk("%s", print_mac(mac, dev->dev_addr));
+    printk("%pM", dev->dev_addr);
 #endif
 
     ei_status.name = name;
@@ -244,8 +243,8 @@ static int __devinit zorro8390_init(struct net_device *dev,
        return err;
     }
 
-    printk(KERN_INFO "%s: %s at 0x%08lx, Ethernet Address %s\n",
-          dev->name, name, board, print_mac(mac, dev->dev_addr));
+    printk(KERN_INFO "%s: %s at 0x%08lx, Ethernet Address %pM\n",
+          dev->name, name, board, dev->dev_addr);
 
     return 0;
 }
index 1b1e80336d2c516deffc59eff87e08b9e03706cf..8a8fad7a8bea8160a84eb655eafaa458408f6d11 100644 (file)
@@ -131,17 +131,13 @@ static int qeth_l2_send_setgroupmac_cb(struct qeth_card *card,
        mac = &cmd->data.setdelmac.mac[0];
        /* MAC already registered, needed in couple/uncouple case */
        if (cmd->hdr.return_code == 0x2005) {
-               QETH_DBF_MESSAGE(2, "Group MAC %02x:%02x:%02x:%02x:%02x:%02x "
-                         "already existing on %s \n",
-                         mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
-                         QETH_CARD_IFNAME(card));
+               QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s \n",
+                         mac, QETH_CARD_IFNAME(card));
                cmd->hdr.return_code = 0;
        }
        if (cmd->hdr.return_code)
-               QETH_DBF_MESSAGE(2, "Could not set group MAC "
-                         "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n",
-                         mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
-                         QETH_CARD_IFNAME(card), cmd->hdr.return_code);
+               QETH_DBF_MESSAGE(2, "Could not set group MAC %pM on %s: %x\n",
+                         mac, QETH_CARD_IFNAME(card), cmd->hdr.return_code);
        return 0;
 }
 
@@ -163,10 +159,8 @@ static int qeth_l2_send_delgroupmac_cb(struct qeth_card *card,
        cmd = (struct qeth_ipa_cmd *) data;
        mac = &cmd->data.setdelmac.mac[0];
        if (cmd->hdr.return_code)
-               QETH_DBF_MESSAGE(2, "Could not delete group MAC "
-                         "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n",
-                         mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
-                         QETH_CARD_IFNAME(card), cmd->hdr.return_code);
+               QETH_DBF_MESSAGE(2, "Could not delete group MAC %pM on %s: %x\n",
+                         mac, QETH_CARD_IFNAME(card), cmd->hdr.return_code);
        return 0;
 }
 
index ed6c54cae7b14a132c19241859470559c4a6b7aa..e11bce6ab63c7bd5290883d517f556979cedaf2a 100644 (file)
@@ -1601,14 +1601,14 @@ static int iscsi_tcp_get_addr(struct iscsi_conn *conn, struct socket *sock,
        case AF_INET:
                sin = (struct sockaddr_in *)addr;
                spin_lock_bh(&conn->session->lock);
-               sprintf(buf, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr));
+               sprintf(buf, "%pI4", &sin->sin_addr.s_addr);
                *port = be16_to_cpu(sin->sin_port);
                spin_unlock_bh(&conn->session->lock);
                break;
        case AF_INET6:
                sin6 = (struct sockaddr_in6 *)addr;
                spin_lock_bh(&conn->session->lock);
-               sprintf(buf, NIP6_FMT, NIP6(sin6->sin6_addr));
+               sprintf(buf, "%pI6", &sin6->sin6_addr);
                *port = be16_to_cpu(sin6->sin6_port);
                spin_unlock_bh(&conn->session->lock);
                break;
index db7ea3bb4e833afb50884b92c74f1b98c4b5d6ec..eb3a414b189a111f8110385440c0911300085210 100644 (file)
@@ -206,8 +206,7 @@ static int qla4xxx_conn_get_param(struct iscsi_cls_conn *conn,
                break;
        case ISCSI_PARAM_CONN_ADDRESS:
                /* TODO: what are the ipv6 bits */
-               len = sprintf(buf, "%u.%u.%u.%u\n",
-                             NIPQUAD(ddb_entry->ip_addr));
+               len = sprintf(buf, "%pI4\n", &ddb_entry->ip_addr);
                break;
        default:
                return -ENOSYS;
index 9aea43a8c4adce959b3aafcc1b171f807b2fc1a7..5ed4ae07bac108cd5f3f3999676c7031e6d5f2a5 100644 (file)
@@ -286,9 +286,7 @@ static ssize_t cxacru_sysfs_show_mac_address(struct device *dev,
        struct usbatm_data *usbatm_instance = usb_get_intfdata(intf);
        struct atm_dev *atm_dev = usbatm_instance->atm_dev;
 
-       return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                       atm_dev->esi[0], atm_dev->esi[1], atm_dev->esi[2],
-                       atm_dev->esi[3], atm_dev->esi[4], atm_dev->esi[5]);
+       return snprintf(buf, PAGE_SIZE, "%pM\n", atm_dev->esi);
 }
 
 static ssize_t cxacru_sysfs_show_adsl_state(struct device *dev,
index 06dd114910d45ac4cda3a080c375459329cada0d..fbea8563df1ede695f0ccf7b5dc8d367c6f623dc 100644 (file)
@@ -770,10 +770,7 @@ static int usbatm_atm_proc_read(struct atm_dev *atm_dev, loff_t * pos, char *pag
                return sprintf(page, "%s\n", instance->description);
 
        if (!left--)
-               return sprintf(page, "MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
-                              atm_dev->esi[0], atm_dev->esi[1],
-                              atm_dev->esi[2], atm_dev->esi[3],
-                              atm_dev->esi[4], atm_dev->esi[5]);
+               return sprintf(page, "MAC: %pM\n", atm_dev->esi);
 
        if (!left--)
                return sprintf(page,
index 66948b72bb9b06e5c73345322b800af69a9618db..00fa5239879dd7eec6adca5e9e224b6369304e49 100644 (file)
@@ -787,10 +787,8 @@ int __init gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN])
                dev_dbg(&g->dev, "register_netdev failed, %d\n", status);
                free_netdev(net);
        } else {
-               DECLARE_MAC_BUF(tmp);
-
-               INFO(dev, "MAC %s\n", print_mac(tmp, net->dev_addr));
-               INFO(dev, "HOST MAC %s\n", print_mac(tmp, dev->host_mac));
+               INFO(dev, "MAC %pM\n", net->dev_addr);
+               INFO(dev, "HOST MAC %pM\n", dev->host_mac);
 
                the_dev = dev;
        }
index cdfe8dfc4340a7317272737ca5c254602ff9d27f..10985fa233ccfc038e66abc5e5fad9cbe8362e4e 100644 (file)
@@ -313,12 +313,9 @@ int wlp_eda_for_virtual(struct wlp_eda *eda,
        list_for_each_entry(itr, &eda->cache, list_node) {
                if (!memcmp(itr->virt_addr, virt_addr,
                           sizeof(itr->virt_addr))) {
-                       d_printf(6, dev, "EDA: looking for "
-                              "%02x:%02x:%02x:%02x:%02x:%02x hit %02x:%02x "
+                       d_printf(6, dev, "EDA: looking for %pM hit %02x:%02x "
                               "wss %p tag 0x%02x state %u\n",
-                              virt_addr[0], virt_addr[1],
-                              virt_addr[2], virt_addr[3],
-                              virt_addr[4], virt_addr[5],
+                              virt_addr,
                               itr->dev_addr.data[1],
                               itr->dev_addr.data[0], itr->wss,
                               itr->tag, itr->state);
@@ -327,24 +324,13 @@ int wlp_eda_for_virtual(struct wlp_eda *eda,
                        found = 1;
                        break;
                } else
-                       d_printf(6, dev, "EDA: looking for "
-                              "%02x:%02x:%02x:%02x:%02x:%02x "
-                              "against "
-                              "%02x:%02x:%02x:%02x:%02x:%02x miss\n",
-                              virt_addr[0], virt_addr[1],
-                              virt_addr[2], virt_addr[3],
-                              virt_addr[4], virt_addr[5],
-                              itr->virt_addr[0], itr->virt_addr[1],
-                              itr->virt_addr[2], itr->virt_addr[3],
-                              itr->virt_addr[4], itr->virt_addr[5]);
+                       d_printf(6, dev, "EDA: looking for %pM against %pM miss\n",
+                                virt_addr, itr->virt_addr);
        }
        if (!found) {
                if (printk_ratelimit())
-                       dev_err(dev, "EDA: Eth addr %02x:%02x:%02x"
-                               ":%02x:%02x:%02x not found.\n",
-                               virt_addr[0], virt_addr[1],
-                               virt_addr[2], virt_addr[3],
-                               virt_addr[4], virt_addr[5]);
+                       dev_err(dev, "EDA: Eth addr %pM not found.\n",
+                               virt_addr);
                result = -ENODEV;
        }
        spin_unlock_irqrestore(&eda->lock, flags);
@@ -380,19 +366,13 @@ ssize_t wlp_eda_show(struct wlp *wlp, char *buf)
                           "tag state virt_addr\n");
        list_for_each_entry(entry, &eda->cache, list_node) {
                result += scnprintf(buf + result, PAGE_SIZE - result,
-                                   "%02x:%02x:%02x:%02x:%02x:%02x %02x:%02x "
-                                   "%p 0x%02x %s "
-                                   "%02x:%02x:%02x:%02x:%02x:%02x\n",
-                                   entry->eth_addr[0], entry->eth_addr[1],
-                                   entry->eth_addr[2], entry->eth_addr[3],
-                                   entry->eth_addr[4], entry->eth_addr[5],
+                                   "%pM %02x:%02x %p 0x%02x %s %pM\n",
+                                   entry->eth_addr,
                                    entry->dev_addr.data[1],
                                    entry->dev_addr.data[0], entry->wss,
                                    entry->tag,
                                    wlp_wss_connect_state_str(entry->state),
-                                   entry->virt_addr[0], entry->virt_addr[1],
-                                   entry->virt_addr[2], entry->virt_addr[3],
-                                   entry->virt_addr[4], entry->virt_addr[5]);
+                                   entry->virt_addr);
                if (result >= PAGE_SIZE)
                        break;
        }
index 9f7d1ae70269ac9de86404e5b6eb36b6a4d34f29..7578c1ab9e0be9ec3260c4cce41b78287f213bce 100644 (file)
@@ -646,7 +646,7 @@ static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v)
        }
 
        /* display one cell per line on subsequent lines */
-       seq_printf(m, "%u.%u.%u.%u\n", NIPQUAD(addr->s_addr));
+       seq_printf(m, "%pI4\n", &addr->s_addr);
        return 0;
 }
 
@@ -737,7 +737,7 @@ static int afs_proc_cell_servers_show(struct seq_file *m, void *v)
        }
 
        /* display one cell per line on subsequent lines */
-       sprintf(ipaddr, "%u.%u.%u.%u", NIPQUAD(server->addr));
+       sprintf(ipaddr, "%pI4", &server->addr);
        seq_printf(m, "%3d %-15.15s %5d\n",
                   atomic_read(&server->usage), ipaddr, server->fs_state);
 
index 28f2451419e1406b3be0aa0a0258fe14f73a0834..f4909951667554b6e4263ebebedc6d2513599d48 100644 (file)
@@ -105,7 +105,7 @@ struct afs_server *afs_lookup_server(struct afs_cell *cell,
 {
        struct afs_server *server, *candidate;
 
-       _enter("%p,"NIPQUAD_FMT, cell, NIPQUAD(addr->s_addr));
+       _enter("%p,%pI4", cell, &addr->s_addr);
 
        /* quick scan of the list to see if we already have the server */
        read_lock(&cell->servers_lock);
@@ -168,9 +168,8 @@ found_server:
 server_in_two_cells:
        write_unlock(&cell->servers_lock);
        kfree(candidate);
-       printk(KERN_NOTICE "kAFS:"
-              " Server "NIPQUAD_FMT" appears to be in two cells\n",
-              NIPQUAD(*addr));
+       printk(KERN_NOTICE "kAFS: Server %pI4 appears to be in two cells\n",
+              addr);
        _leave(" = -EEXIST");
        return ERR_PTR(-EEXIST);
 }
@@ -184,7 +183,7 @@ struct afs_server *afs_find_server(const struct in_addr *_addr)
        struct rb_node *p;
        struct in_addr addr = *_addr;
 
-       _enter(NIPQUAD_FMT, NIPQUAD(addr.s_addr));
+       _enter("%pI4", &addr.s_addr);
 
        read_lock(&afs_servers_lock);
 
index 0ab2fb5afef12a78a9ae2fdd0e79af761133468b..3fd3a9df043a6eee77c276563300be4c5ed390a7 100644 (file)
@@ -121,11 +121,9 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
 
        /* add the server address */
        if (server->addr.sockAddr.sin_family == AF_INET)
-               sprintf(dp, "ip4=" NIPQUAD_FMT,
-                       NIPQUAD(server->addr.sockAddr.sin_addr));
+               sprintf(dp, "ip4=%pI4", &server->addr.sockAddr.sin_addr);
        else if (server->addr.sockAddr.sin_family == AF_INET6)
-               sprintf(dp, "ip6=" NIP6_SEQFMT,
-                       NIP6(server->addr.sockAddr6.sin6_addr));
+               sprintf(dp, "ip6=%pi6", &server->addr.sockAddr6.sin6_addr);
        else
                goto out;
 
index c7d341714586fdfc9086c381dc310fe81a371237..204bd1354360156cb83d469127d5bb6899a13266 100644 (file)
@@ -2228,8 +2228,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
 
                /* new SMB session uses our srvTcp ref */
                pSesInfo->server = srvTcp;
-               sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
-                       NIPQUAD(sin_server->sin_addr.s_addr));
+               sprintf(pSesInfo->serverName, "%pI4",
+                       &sin_server->sin_addr.s_addr);
 
                write_lock(&cifs_tcp_ses_lock);
                list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list);
index 9fd8889097b728b735150ff82b1ff123a503dac7..c48c26380771f731655038ac7bb4ef53af0a84dd 100644 (file)
@@ -115,14 +115,14 @@ static void nlm_display_address(const struct sockaddr *sap,
                snprintf(buf, len, "unspecified");
                break;
        case AF_INET:
-               snprintf(buf, len, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr));
+               snprintf(buf, len, "%pI4", &sin->sin_addr.s_addr);
                break;
        case AF_INET6:
                if (ipv6_addr_v4mapped(&sin6->sin6_addr))
-                       snprintf(buf, len, NIPQUAD_FMT,
-                                NIPQUAD(sin6->sin6_addr.s6_addr32[3]));
+                       snprintf(buf, len, "%pI4",
+                                &sin6->sin6_addr.s6_addr32[3]);
                else
-                       snprintf(buf, len, NIP6_FMT, NIP6(sin6->sin6_addr));
+                       snprintf(buf, len, "%pI6", &sin6->sin6_addr);
                break;
        default:
                snprintf(buf, len, "unsupported address family");
index 4e7e958e8f6753236832ed9ebd82f6bae0746899..ffd3461f75efb332f44d8ce5b7e87a179eb6c2ce 100644 (file)
@@ -179,7 +179,7 @@ static __be32 *xdr_encode_mon_name(__be32 *p, struct nsm_args *argp)
 
        if (!nsm_use_hostnames) {
                snprintf(buffer, XDR_ADDRBUF_LEN,
-                        NIPQUAD_FMT, NIPQUAD(argp->addr));
+                        "%pI4", &argp->addr);
                name = buffer;
        }
 
index 8478fc25daee196383f3e40a34999795be41585e..d74d16ce0d49920ed710d0602c4797213aa79d38 100644 (file)
@@ -329,7 +329,7 @@ static int __init root_nfs_addr(void)
        }
 
        snprintf(nfs_data.hostname, sizeof(nfs_data.hostname),
-                "%u.%u.%u.%u", NIPQUAD(servaddr));
+                "%pI4", &servaddr);
        return 0;
 }
 
@@ -421,8 +421,8 @@ static int __init root_nfs_getport(int program, int version, int proto)
 {
        struct sockaddr_in sin;
 
-       printk(KERN_NOTICE "Looking up port of RPC %d/%d on %u.%u.%u.%u\n",
-               program, version, NIPQUAD(servaddr));
+       printk(KERN_NOTICE "Looking up port of RPC %d/%d on %pI4\n",
+               program, version, &servaddr);
        set_sockaddr(&sin, servaddr, 0);
        return rpcb_getport_sync(&sin, program, version, proto);
 }
index f48db679a1c681aecdfef6ed2eb662fec9d7d2bc..bb0313ac9e1fa1a6b94ddb51229298e88b955bfd 100644 (file)
@@ -462,14 +462,12 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
        switch (sap->sa_family) {
        case AF_INET: {
                struct sockaddr_in *sin = (struct sockaddr_in *)sap;
-               seq_printf(m, ",mountaddr=" NIPQUAD_FMT,
-                               NIPQUAD(sin->sin_addr.s_addr));
+               seq_printf(m, ",mountaddr=%pI4", &sin->sin_addr.s_addr);
                break;
        }
        case AF_INET6: {
                struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
-               seq_printf(m, ",mountaddr=" NIP6_FMT,
-                               NIP6(sin6->sin6_addr));
+               seq_printf(m, ",mountaddr=%pI6", &sin6->sin6_addr);
                break;
        }
        default:
index b0bebc552a11f3cec582b83c80c45c97a7734cdd..16efb8f8e062b28728eb57ccbe9e54f5f26cf514 100644 (file)
@@ -719,8 +719,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                status = nfserr_clid_inuse;
                if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)
                                || conf->cl_addr != sin->sin_addr.s_addr) {
-                       dprintk("NFSD: setclientid: string in use by client"
-                               "at %u.%u.%u.%u\n", NIPQUAD(conf->cl_addr));
+                       dprintk("NFSD: setclientid: string in use by clientat %pI4\n",
+                               &conf->cl_addr);
                        goto out;
                }
        }
index e3f9783fdcf7eba3872331b0c48f5aee7207fd62..77d7b8c531a6b14f351b280f84d98f0bf9e66401 100644 (file)
@@ -330,7 +330,7 @@ static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size)
                return -EINVAL;
 
        /* get ipv4 address */
-       if (sscanf(fo_path, NIPQUAD_FMT "%c", &b1, &b2, &b3, &b4, &c) != 4)
+       if (sscanf(fo_path, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) != 4)
                return -EINVAL;
        if (b1 > 255 || b2 > 255 || b3 > 255 || b4 > 255)
                return -EINVAL;
index 52276c02f71041665ba3389b9d690e46e8c075dd..f8424874fa0725b95065d5ce7031f63d0cdde586 100644 (file)
@@ -304,8 +304,8 @@ static int sc_seq_show(struct seq_file *seq, void *v)
                 * use of it here generates a warning with -Wbitwise */
                seq_printf(seq, "%p:\n"
                           "  krefs:           %d\n"
-                          "  sock:            %u.%u.%u.%u:%u -> "
-                                             "%u.%u.%u.%u:%u\n"
+                          "  sock:            %pI4:%u -> "
+                                             "%pI4:%u\n"
                           "  remote node:     %s\n"
                           "  page off:        %zu\n"
                           "  handshake ok:    %u\n"
@@ -319,8 +319,8 @@ static int sc_seq_show(struct seq_file *seq, void *v)
                           "  func type:       %u\n",
                           sc,
                           atomic_read(&sc->sc_kref.refcount),
-                          NIPQUAD(saddr), inet ? ntohs(sport) : 0,
-                          NIPQUAD(daddr), inet ? ntohs(dport) : 0,
+                          &saddr, inet ? ntohs(sport) : 0,
+                          &daddr, inet ? ntohs(dport) : 0,
                           sc->sc_node->nd_name,
                           sc->sc_page_off,
                           sc->sc_handshake_ok,
index 816a3f61330c6173ec04a360f4b7b40bb53ad0bf..70e8fa9e2539cdf210676778770e0de4405713e2 100644 (file)
@@ -250,7 +250,7 @@ static ssize_t o2nm_node_ipv4_port_write(struct o2nm_node *node,
 
 static ssize_t o2nm_node_ipv4_address_read(struct o2nm_node *node, char *page)
 {
-       return sprintf(page, "%u.%u.%u.%u\n", NIPQUAD(node->nd_ipv4_address));
+       return sprintf(page, "%pI4\n", &node->nd_ipv4_address);
 }
 
 static ssize_t o2nm_node_ipv4_address_write(struct o2nm_node *node,
index 2bcf706d9dd3c460d9bab05f963c74e08d21b188..9fbe849f634419d9f5418d6097e789906ba460b1 100644 (file)
@@ -1597,8 +1597,8 @@ static void o2net_start_connect(struct work_struct *work)
        ret = sock->ops->bind(sock, (struct sockaddr *)&myaddr,
                              sizeof(myaddr));
        if (ret) {
-               mlog(ML_ERROR, "bind failed with %d at address %u.%u.%u.%u\n",
-                    ret, NIPQUAD(mynode->nd_ipv4_address));
+               mlog(ML_ERROR, "bind failed with %d at address %pI4\n",
+                    ret, &mynode->nd_ipv4_address);
                goto out;
        }
 
@@ -1790,17 +1790,16 @@ static int o2net_accept_one(struct socket *sock)
 
        node = o2nm_get_node_by_ip(sin.sin_addr.s_addr);
        if (node == NULL) {
-               mlog(ML_NOTICE, "attempt to connect from unknown node at "
-                    "%u.%u.%u.%u:%d\n", NIPQUAD(sin.sin_addr.s_addr),
-                    ntohs(sin.sin_port));
+               mlog(ML_NOTICE, "attempt to connect from unknown node at %pI4:%d\n",
+                    &sin.sin_addr.s_addr, ntohs(sin.sin_port));
                ret = -EINVAL;
                goto out;
        }
 
        if (o2nm_this_node() > node->nd_num) {
                mlog(ML_NOTICE, "unexpected connect attempted from a lower "
-                    "numbered node '%s' at " "%u.%u.%u.%u:%d with num %u\n",
-                    node->nd_name, NIPQUAD(sin.sin_addr.s_addr),
+                    "numbered node '%s' at " "%pI4:%d with num %u\n",
+                    node->nd_name, &sin.sin_addr.s_addr,
                     ntohs(sin.sin_port), node->nd_num);
                ret = -EINVAL;
                goto out;
@@ -1810,8 +1809,8 @@ static int o2net_accept_one(struct socket *sock)
         * and tries to connect before we see their heartbeat */
        if (!o2hb_check_node_heartbeating_from_callback(node->nd_num)) {
                mlog(ML_CONN, "attempt to connect from node '%s' at "
-                    "%u.%u.%u.%u:%d but it isn't heartbeating\n",
-                    node->nd_name, NIPQUAD(sin.sin_addr.s_addr),
+                    "%pI4:%d but it isn't heartbeating\n",
+                    node->nd_name, &sin.sin_addr.s_addr,
                     ntohs(sin.sin_port));
                ret = -EINVAL;
                goto out;
@@ -1827,8 +1826,8 @@ static int o2net_accept_one(struct socket *sock)
        spin_unlock(&nn->nn_lock);
        if (ret) {
                mlog(ML_NOTICE, "attempt to connect from node '%s' at "
-                    "%u.%u.%u.%u:%d but it already has an open connection\n",
-                    node->nd_name, NIPQUAD(sin.sin_addr.s_addr),
+                    "%pI4:%d but it already has an open connection\n",
+                    node->nd_name, &sin.sin_addr.s_addr,
                     ntohs(sin.sin_port));
                goto out;
        }
@@ -1924,15 +1923,15 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port)
        sock->sk->sk_reuse = 1;
        ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin));
        if (ret < 0) {
-               mlog(ML_ERROR, "unable to bind socket at %u.%u.%u.%u:%u, "
-                    "ret=%d\n", NIPQUAD(addr), ntohs(port), ret);
+               mlog(ML_ERROR, "unable to bind socket at %pI4:%u, "
+                    "ret=%d\n", &addr, ntohs(port), ret);
                goto out;
        }
 
        ret = sock->ops->listen(sock, 64);
        if (ret < 0) {
-               mlog(ML_ERROR, "unable to listen on %u.%u.%u.%u:%u, ret=%d\n",
-                    NIPQUAD(addr), ntohs(port), ret);
+               mlog(ML_ERROR, "unable to listen on %pI4:%u, ret=%d\n",
+                    &addr, ntohs(port), ret);
        }
 
 out:
index 9c22396e8b50355e3058e93807f293112622079f..9c8d31bacf46ca6acfc083a9a3c2be8e4cd4d2e8 100644 (file)
@@ -54,3 +54,9 @@ SUBSYS(freezer)
 #endif
 
 /* */
+
+#ifdef CONFIG_NET_CLS_CGROUP
+SUBSYS(net_cls)
+#endif
+
+/* */
index 6080449fbec942b7a1340c4a0c131f1957b33e81..eda389ce04f42019091be7f0d88eef633094f927 100644 (file)
@@ -176,29 +176,23 @@ enum {
 };
 
 /* DCCP features (RFC 4340 section 6.4) */
-enum {
+enum dccp_feature_numbers {
        DCCPF_RESERVED = 0,
        DCCPF_CCID = 1,
-       DCCPF_SHORT_SEQNOS = 2,         /* XXX: not yet implemented */
+       DCCPF_SHORT_SEQNOS = 2,
        DCCPF_SEQUENCE_WINDOW = 3,
-       DCCPF_ECN_INCAPABLE = 4,        /* XXX: not yet implemented */
+       DCCPF_ECN_INCAPABLE = 4,
        DCCPF_ACK_RATIO = 5,
        DCCPF_SEND_ACK_VECTOR = 6,
        DCCPF_SEND_NDP_COUNT = 7,
        DCCPF_MIN_CSUM_COVER = 8,
-       DCCPF_DATA_CHECKSUM = 9,        /* XXX: not yet implemented */
+       DCCPF_DATA_CHECKSUM = 9,
        /* 10-127 reserved */
        DCCPF_MIN_CCID_SPECIFIC = 128,
+       DCCPF_SEND_LEV_RATE = 192,      /* RFC 4342, sec. 8.4 */
        DCCPF_MAX_CCID_SPECIFIC = 255,
 };
 
-/* this structure is argument to DCCP_SOCKOPT_CHANGE_X */
-struct dccp_so_feat {
-       __u8 dccpsf_feat;
-       __u8 __user *dccpsf_val;
-       __u8 dccpsf_len;
-};
-
 /* DCCP socket options */
 #define DCCP_SOCKOPT_PACKET_SIZE       1 /* XXX deprecated, without effect */
 #define DCCP_SOCKOPT_SERVICE           2
@@ -208,6 +202,7 @@ struct dccp_so_feat {
 #define DCCP_SOCKOPT_SERVER_TIMEWAIT   6
 #define DCCP_SOCKOPT_SEND_CSCOV                10
 #define DCCP_SOCKOPT_RECV_CSCOV                11
+#define DCCP_SOCKOPT_AVAILABLE_CCIDS   12
 #define DCCP_SOCKOPT_CCID_RX_INFO      128
 #define DCCP_SOCKOPT_CCID_TX_INFO      192
 
@@ -373,7 +368,6 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb)
   * @dccpms_ccid - Congestion Control Id (CCID) (section 10)
   * @dccpms_send_ack_vector - Send Ack Vector Feature (section 11.5)
   * @dccpms_send_ndp_count - Send NDP Count Feature (7.7.2)
-  * @dccpms_ack_ratio - Ack Ratio Feature (section 11.3)
   * @dccpms_pending - List of features being negotiated
   * @dccpms_conf -
   */
@@ -383,7 +377,6 @@ struct dccp_minisock {
        __u8                    dccpms_tx_ccid;
        __u8                    dccpms_send_ack_vector;
        __u8                    dccpms_send_ndp_count;
-       __u8                    dccpms_ack_ratio;
        struct list_head        dccpms_pending;
        struct list_head        dccpms_conf;
 };
@@ -411,6 +404,7 @@ extern void dccp_minisock_init(struct dccp_minisock *dmsk);
  * @dreq_iss: initial sequence number sent on the Response (RFC 4340, 7.1)
  * @dreq_isr: initial sequence number received on the Request
  * @dreq_service: service code present on the Request (there is just one)
+ * @dreq_featneg: feature negotiation options for this connection
  * The following two fields are analogous to the ones in dccp_sock:
  * @dreq_timestamp_echo: last received timestamp to echo (13.1)
  * @dreq_timestamp_echo: the time of receiving the last @dreq_timestamp_echo
@@ -420,6 +414,7 @@ struct dccp_request_sock {
        __u64                    dreq_iss;
        __u64                    dreq_isr;
        __be32                   dreq_service;
+       struct list_head         dreq_featneg;
        __u32                    dreq_timestamp_echo;
        __u32                    dreq_timestamp_time;
 };
@@ -497,6 +492,7 @@ struct dccp_ackvec;
  * @dccps_mss_cache - current value of MSS (path MTU minus header sizes)
  * @dccps_rate_last - timestamp for rate-limiting DCCP-Sync (RFC 4340, 7.5.4)
  * @dccps_minisock - associated minisock (accessed via dccp_msk)
+ * @dccps_featneg - tracks feature-negotiation state (mostly during handshake)
  * @dccps_hc_rx_ackvec - rx half connection ack vector
  * @dccps_hc_rx_ccid - CCID used for the receiver (or receiving half-connection)
  * @dccps_hc_tx_ccid - CCID used for the sender (or sending half-connection)
@@ -529,11 +525,12 @@ struct dccp_sock {
        __u32                           dccps_timestamp_time;
        __u16                           dccps_l_ack_ratio;
        __u16                           dccps_r_ack_ratio;
-       __u16                           dccps_pcslen;
-       __u16                           dccps_pcrlen;
+       __u8                            dccps_pcslen:4;
+       __u8                            dccps_pcrlen:4;
        __u64                           dccps_ndp_count:48;
        unsigned long                   dccps_rate_last;
        struct dccp_minisock            dccps_minisock;
+       struct list_head                dccps_featneg;
        struct dccp_ackvec              *dccps_hc_rx_ackvec;
        struct ccid                     *dccps_hc_rx_ccid;
        struct ccid                     *dccps_hc_tx_ccid;
index 14126bc36641df1d654102136aa8903d2859d994..56b0eb25d9276a6600e5898682fddcad85d994d3 100644 (file)
@@ -12,8 +12,8 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef IEEE80211_H
-#define IEEE80211_H
+#ifndef LINUX_IEEE80211_H
+#define LINUX_IEEE80211_H
 
 #include <linux/types.h>
 #include <asm/byteorder.h>
 #define IEEE80211_MAX_FRAME_LEN                2352
 
 #define IEEE80211_MAX_SSID_LEN         32
+
 #define IEEE80211_MAX_MESH_ID_LEN      32
+#define IEEE80211_MESH_CONFIG_LEN      19
+
 #define IEEE80211_QOS_CTL_LEN          2
 #define IEEE80211_QOS_CTL_TID_MASK     0x000F
 #define IEEE80211_QOS_CTL_TAG1D_MASK   0x0007
@@ -666,6 +669,13 @@ struct ieee80211_cts {
        u8 ra[6];
 } __attribute__ ((packed));
 
+struct ieee80211_pspoll {
+       __le16 frame_control;
+       __le16 aid;
+       u8 bssid[6];
+       u8 ta[6];
+} __attribute__ ((packed));
+
 /**
  * struct ieee80211_bar - HT Block Ack Request
  *
@@ -685,28 +695,88 @@ struct ieee80211_bar {
 #define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL     0x0000
 #define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA  0x0004
 
+
+#define IEEE80211_HT_MCS_MASK_LEN              10
+
+/**
+ * struct ieee80211_mcs_info - MCS information
+ * @rx_mask: RX mask
+ * @rx_highest: highest supported RX rate
+ * @tx_params: TX parameters
+ */
+struct ieee80211_mcs_info {
+       u8 rx_mask[IEEE80211_HT_MCS_MASK_LEN];
+       __le16 rx_highest;
+       u8 tx_params;
+       u8 reserved[3];
+} __attribute__((packed));
+
+/* 802.11n HT capability MSC set */
+#define IEEE80211_HT_MCS_RX_HIGHEST_MASK       0x3ff
+#define IEEE80211_HT_MCS_TX_DEFINED            0x01
+#define IEEE80211_HT_MCS_TX_RX_DIFF            0x02
+/* value 0 == 1 stream etc */
+#define IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK   0x0C
+#define IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT  2
+#define                IEEE80211_HT_MCS_TX_MAX_STREAMS 4
+#define IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION 0x10
+
+/*
+ * 802.11n D5.0 20.3.5 / 20.6 says:
+ * - indices 0 to 7 and 32 are single spatial stream
+ * - 8 to 31 are multiple spatial streams using equal modulation
+ *   [8..15 for two streams, 16..23 for three and 24..31 for four]
+ * - remainder are multiple spatial streams using unequal modulation
+ */
+#define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START 33
+#define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE \
+       (IEEE80211_HT_MCS_UNEQUAL_MODULATION_START / 8)
+
 /**
  * struct ieee80211_ht_cap - HT capabilities
  *
- * This structure refers to "HT capabilities element" as
- * described in 802.11n draft section 7.3.2.52
+ * This structure is the "HT capabilities element" as
+ * described in 802.11n D5.0 7.3.2.57
  */
 struct ieee80211_ht_cap {
        __le16 cap_info;
        u8 ampdu_params_info;
-       u8 supp_mcs_set[16];
+
+       /* 16 bytes MCS information */
+       struct ieee80211_mcs_info mcs;
+
        __le16 extended_ht_cap_info;
        __le32 tx_BF_cap_info;
        u8 antenna_selection_info;
 } __attribute__ ((packed));
 
+/* 802.11n HT capabilities masks (for cap_info) */
+#define IEEE80211_HT_CAP_LDPC_CODING           0x0001
+#define IEEE80211_HT_CAP_SUP_WIDTH_20_40       0x0002
+#define IEEE80211_HT_CAP_SM_PS                 0x000C
+#define IEEE80211_HT_CAP_GRN_FLD               0x0010
+#define IEEE80211_HT_CAP_SGI_20                        0x0020
+#define IEEE80211_HT_CAP_SGI_40                        0x0040
+#define IEEE80211_HT_CAP_TX_STBC               0x0080
+#define IEEE80211_HT_CAP_RX_STBC               0x0300
+#define IEEE80211_HT_CAP_DELAY_BA              0x0400
+#define IEEE80211_HT_CAP_MAX_AMSDU             0x0800
+#define IEEE80211_HT_CAP_DSSSCCK40             0x1000
+#define IEEE80211_HT_CAP_PSMP_SUPPORT          0x2000
+#define IEEE80211_HT_CAP_40MHZ_INTOLERANT      0x4000
+#define IEEE80211_HT_CAP_LSIG_TXOP_PROT                0x8000
+
+/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */
+#define IEEE80211_HT_AMPDU_PARM_FACTOR         0x03
+#define IEEE80211_HT_AMPDU_PARM_DENSITY                0x1C
+
 /**
- * struct ieee80211_ht_cap - HT additional information
+ * struct ieee80211_ht_info - HT information
  *
- * This structure refers to "HT information element" as
- * described in 802.11n draft section 7.3.2.53
+ * This structure is the "HT information element" as
+ * described in 802.11n D5.0 7.3.2.58
  */
-struct ieee80211_ht_addt_info {
+struct ieee80211_ht_info {
        u8 control_chan;
        u8 ht_param;
        __le16 operation_mode;
@@ -714,36 +784,33 @@ struct ieee80211_ht_addt_info {
        u8 basic_set[16];
 } __attribute__ ((packed));
 
-/* 802.11n HT capabilities masks */
-#define IEEE80211_HT_CAP_SUP_WIDTH             0x0002
-#define IEEE80211_HT_CAP_SM_PS                 0x000C
-#define IEEE80211_HT_CAP_GRN_FLD               0x0010
-#define IEEE80211_HT_CAP_SGI_20                        0x0020
-#define IEEE80211_HT_CAP_SGI_40                        0x0040
-#define IEEE80211_HT_CAP_DELAY_BA              0x0400
-#define IEEE80211_HT_CAP_MAX_AMSDU             0x0800
-#define IEEE80211_HT_CAP_DSSSCCK40             0x1000
-/* 802.11n HT capability AMPDU settings */
-#define IEEE80211_HT_CAP_AMPDU_FACTOR          0x03
-#define IEEE80211_HT_CAP_AMPDU_DENSITY         0x1C
-/* 802.11n HT capability MSC set */
-#define IEEE80211_SUPP_MCS_SET_UEQM            4
-#define IEEE80211_HT_CAP_MAX_STREAMS           4
-#define IEEE80211_SUPP_MCS_SET_LEN             10
-/* maximum streams the spec allows */
-#define IEEE80211_HT_CAP_MCS_TX_DEFINED                0x01
-#define IEEE80211_HT_CAP_MCS_TX_RX_DIFF                0x02
-#define IEEE80211_HT_CAP_MCS_TX_STREAMS                0x0C
-#define IEEE80211_HT_CAP_MCS_TX_UEQM           0x10
-/* 802.11n HT IE masks */
-#define IEEE80211_HT_IE_CHA_SEC_OFFSET         0x03
-#define IEEE80211_HT_IE_CHA_SEC_NONE           0x00
-#define IEEE80211_HT_IE_CHA_SEC_ABOVE          0x01
-#define IEEE80211_HT_IE_CHA_SEC_BELOW          0x03
-#define IEEE80211_HT_IE_CHA_WIDTH              0x04
-#define IEEE80211_HT_IE_HT_PROTECTION          0x0003
-#define IEEE80211_HT_IE_NON_GF_STA_PRSNT       0x0004
-#define IEEE80211_HT_IE_NON_HT_STA_PRSNT       0x0010
+/* for ht_param */
+#define IEEE80211_HT_PARAM_CHA_SEC_OFFSET              0x03
+#define                IEEE80211_HT_PARAM_CHA_SEC_NONE         0x00
+#define                IEEE80211_HT_PARAM_CHA_SEC_ABOVE        0x01
+#define                IEEE80211_HT_PARAM_CHA_SEC_BELOW        0x03
+#define IEEE80211_HT_PARAM_CHAN_WIDTH_ANY              0x04
+#define IEEE80211_HT_PARAM_RIFS_MODE                   0x08
+#define IEEE80211_HT_PARAM_SPSMP_SUPPORT               0x10
+#define IEEE80211_HT_PARAM_SERV_INTERVAL_GRAN          0xE0
+
+/* for operation_mode */
+#define IEEE80211_HT_OP_MODE_PROTECTION                        0x0003
+#define                IEEE80211_HT_OP_MODE_PROTECTION_NONE            0
+#define                IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER       1
+#define                IEEE80211_HT_OP_MODE_PROTECTION_20MHZ           2
+#define                IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED     3
+#define IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT          0x0004
+#define IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT          0x0010
+
+/* for stbc_param */
+#define IEEE80211_HT_STBC_PARAM_DUAL_BEACON            0x0040
+#define IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT          0x0080
+#define IEEE80211_HT_STBC_PARAM_STBC_BEACON            0x0100
+#define IEEE80211_HT_STBC_PARAM_LSIG_TXOP_FULLPROT     0x0200
+#define IEEE80211_HT_STBC_PARAM_PCO_ACTIVE             0x0400
+#define IEEE80211_HT_STBC_PARAM_PCO_PHASE              0x0800
+
 
 /* block-ack parameters */
 #define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
@@ -769,8 +836,7 @@ struct ieee80211_ht_addt_info {
 /* Authentication algorithms */
 #define WLAN_AUTH_OPEN 0
 #define WLAN_AUTH_SHARED_KEY 1
-#define WLAN_AUTH_FAST_BSS_TRANSITION 2
-#define WLAN_AUTH_LEAP 128
+#define WLAN_AUTH_LEAP 2
 
 #define WLAN_AUTH_CHALLENGE_LEN 128
 
@@ -949,7 +1015,7 @@ enum ieee80211_eid {
        WLAN_EID_EXT_SUPP_RATES = 50,
        /* 802.11n */
        WLAN_EID_HT_CAPABILITY = 45,
-       WLAN_EID_HT_EXTRA_INFO = 61,
+       WLAN_EID_HT_INFORMATION = 61,
        /* 802.11i */
        WLAN_EID_RSN = 48,
        WLAN_EID_WPA = 221,
@@ -1057,4 +1123,4 @@ static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr)
                return hdr->addr1;
 }
 
-#endif /* IEEE80211_H */
+#endif /* LINUX_IEEE80211_H */
index 65246846c844089e5eef7fce7054789f26ffe817..2a6e29620a963bcbfbd9195859fbab7c07f84266 100644 (file)
@@ -65,6 +65,7 @@
 #define IFF_BONDING    0x20            /* bonding master or slave      */
 #define IFF_SLAVE_NEEDARP 0x40         /* need ARPs for validation     */
 #define IFF_ISATAP     0x80            /* ISATAP interface (RFC4214)   */
+#define IFF_MASTER_ARPMON 0x100                /* bonding master, ARP mon in use */
 
 #define IF_GET_IFACE   0x0001          /* for querying only */
 #define IF_GET_PROTO   0x0002
index db458beef19dabe156b52eecab7bd30e11a7e5f9..d60122a3a0886310e9221405ad1c022f9d3d2fa7 100644 (file)
@@ -80,6 +80,10 @@ struct in_addr {
 /* BSD compatibility */
 #define IP_RECVRETOPTS IP_RETOPTS
 
+/* TProxy original addresses */
+#define IP_ORIGDSTADDR       20
+#define IP_RECVORIGDSTADDR   IP_ORIGDSTADDR
+
 /* IP_MTU_DISCOVER values */
 #define IP_PMTUDISC_DONT               0       /* Never send DF frames */
 #define IP_PMTUDISC_WANT               1       /* Use per route hints  */
index dc7e0d0a6474448aba71b4c32d2045afc44e240e..6002ae76785c9aeba493c0960aa5de508b139b49 100644 (file)
@@ -361,18 +361,6 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
        ((unsigned char *)&addr)[3]
 #define NIPQUAD_FMT "%u.%u.%u.%u"
 
-#define NIP6(addr) \
-       ntohs((addr).s6_addr16[0]), \
-       ntohs((addr).s6_addr16[1]), \
-       ntohs((addr).s6_addr16[2]), \
-       ntohs((addr).s6_addr16[3]), \
-       ntohs((addr).s6_addr16[4]), \
-       ntohs((addr).s6_addr16[5]), \
-       ntohs((addr).s6_addr16[6]), \
-       ntohs((addr).s6_addr16[7])
-#define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
-#define NIP6_SEQFMT "%04x%04x%04x%04x%04x%04x%04x%04x"
-
 #if defined(__LITTLE_ENDIAN)
 #define HIPQUAD(addr) \
        ((unsigned char *)&addr)[3], \
diff --git a/include/linux/list_nulls.h b/include/linux/list_nulls.h
new file mode 100644 (file)
index 0000000..93150ec
--- /dev/null
@@ -0,0 +1,94 @@
+#ifndef _LINUX_LIST_NULLS_H
+#define _LINUX_LIST_NULLS_H
+
+/*
+ * Special version of lists, where end of list is not a NULL pointer,
+ * but a 'nulls' marker, which can have many different values.
+ * (up to 2^31 different values guaranteed on all platforms)
+ *
+ * In the standard hlist, termination of a list is the NULL pointer.
+ * In this special 'nulls' variant, we use the fact that objects stored in
+ * a list are aligned on a word (4 or 8 bytes alignment).
+ * We therefore use the last significant bit of 'ptr' :
+ * Set to 1 : This is a 'nulls' end-of-list marker (ptr >> 1)
+ * Set to 0 : This is a pointer to some object (ptr)
+ */
+
+struct hlist_nulls_head {
+       struct hlist_nulls_node *first;
+};
+
+struct hlist_nulls_node {
+       struct hlist_nulls_node *next, **pprev;
+};
+#define INIT_HLIST_NULLS_HEAD(ptr, nulls) \
+       ((ptr)->first = (struct hlist_nulls_node *) (1UL | (((long)nulls) << 1)))
+
+#define hlist_nulls_entry(ptr, type, member) container_of(ptr,type,member)
+/**
+ * ptr_is_a_nulls - Test if a ptr is a nulls
+ * @ptr: ptr to be tested
+ *
+ */
+static inline int is_a_nulls(const struct hlist_nulls_node *ptr)
+{
+       return ((unsigned long)ptr & 1);
+}
+
+/**
+ * get_nulls_value - Get the 'nulls' value of the end of chain
+ * @ptr: end of chain
+ *
+ * Should be called only if is_a_nulls(ptr);
+ */
+static inline unsigned long get_nulls_value(const struct hlist_nulls_node *ptr)
+{
+       return ((unsigned long)ptr) >> 1;
+}
+
+static inline int hlist_nulls_unhashed(const struct hlist_nulls_node *h)
+{
+       return !h->pprev;
+}
+
+static inline int hlist_nulls_empty(const struct hlist_nulls_head *h)
+{
+       return is_a_nulls(h->first);
+}
+
+static inline void __hlist_nulls_del(struct hlist_nulls_node *n)
+{
+       struct hlist_nulls_node *next = n->next;
+       struct hlist_nulls_node **pprev = n->pprev;
+       *pprev = next;
+       if (!is_a_nulls(next))
+               next->pprev = pprev;
+}
+
+/**
+ * hlist_nulls_for_each_entry  - iterate over list of given type
+ * @tpos:      the type * to use as a loop cursor.
+ * @pos:       the &struct hlist_node to use as a loop cursor.
+ * @head:      the head for your list.
+ * @member:    the name of the hlist_node within the struct.
+ *
+ */
+#define hlist_nulls_for_each_entry(tpos, pos, head, member)                   \
+       for (pos = (head)->first;                                              \
+            (!is_a_nulls(pos)) &&                                             \
+               ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1;}); \
+            pos = pos->next)
+
+/**
+ * hlist_nulls_for_each_entry_from - iterate over a hlist continuing from current point
+ * @tpos:      the type * to use as a loop cursor.
+ * @pos:       the &struct hlist_node to use as a loop cursor.
+ * @member:    the name of the hlist_node within the struct.
+ *
+ */
+#define hlist_nulls_for_each_entry_from(tpos, pos, member)     \
+       for (; (!is_a_nulls(pos)) &&                            \
+               ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1;}); \
+            pos = pos->next)
+
+#endif
diff --git a/include/linux/mdio-gpio.h b/include/linux/mdio-gpio.h
new file mode 100644 (file)
index 0000000..e9d3fdf
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * MDIO-GPIO bus platform data structures
+ *
+ * Copyright (C) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __LINUX_MDIO_GPIO_H
+#define __LINUX_MDIO_GPIO_H
+
+#include <linux/mdio-bitbang.h>
+
+struct mdio_gpio_platform_data {
+       /* GPIO numbers for bus pins */
+       unsigned int mdc;
+       unsigned int mdio;
+
+       unsigned int phy_mask;
+       int irqs[PHY_MAX_ADDR];
+};
+
+#endif /* __LINUX_MDIO_GPIO_H */
index 9d77b1d7dca806e540838d27bbc632961a340f0e..12d7f4469dc9c6eeb897037bd7880777d86b218f 100644 (file)
@@ -1742,26 +1742,31 @@ static inline int skb_bond_should_drop(struct sk_buff *skb)
        struct net_device *dev = skb->dev;
        struct net_device *master = dev->master;
 
-       if (master &&
-           (dev->priv_flags & IFF_SLAVE_INACTIVE)) {
-               if ((dev->priv_flags & IFF_SLAVE_NEEDARP) &&
-                   skb->protocol == __constant_htons(ETH_P_ARP))
-                       return 0;
-
-               if (master->priv_flags & IFF_MASTER_ALB) {
-                       if (skb->pkt_type != PACKET_BROADCAST &&
-                           skb->pkt_type != PACKET_MULTICAST)
+       if (master) {
+               if (master->priv_flags & IFF_MASTER_ARPMON)
+                       dev->last_rx = jiffies;
+
+               if (dev->priv_flags & IFF_SLAVE_INACTIVE) {
+                       if ((dev->priv_flags & IFF_SLAVE_NEEDARP) &&
+                           skb->protocol == __constant_htons(ETH_P_ARP))
                                return 0;
-               }
-               if (master->priv_flags & IFF_MASTER_8023AD &&
-                   skb->protocol == __constant_htons(ETH_P_SLOW))
-                       return 0;
 
-               return 1;
+                       if (master->priv_flags & IFF_MASTER_ALB) {
+                               if (skb->pkt_type != PACKET_BROADCAST &&
+                                   skb->pkt_type != PACKET_MULTICAST)
+                                       return 0;
+                       }
+                       if (master->priv_flags & IFF_MASTER_8023AD &&
+                           skb->protocol == __constant_htons(ETH_P_SLOW))
+                               return 0;
+
+                       return 1;
+               }
        }
        return 0;
 }
 
+extern struct pernet_operations __net_initdata loopback_net_ops;
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_DEV_H */
index 9bad65400fba76cad80e742b3784adbd4ca50637..79827345351d061439b1154a44c1da8d6354ea7d 100644 (file)
@@ -25,8 +25,9 @@
  *
  * @NL80211_CMD_GET_WIPHY: request information about a wiphy or dump request
  *     to get a list of all present wiphys.
- * @NL80211_CMD_SET_WIPHY: set wiphy name, needs %NL80211_ATTR_WIPHY and
- *     %NL80211_ATTR_WIPHY_NAME.
+ * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or
+ *     %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME
+ *     and/or %NL80211_ATTR_WIPHY_TXQ_PARAMS.
  * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request
  *     or rename notification. Has attributes %NL80211_ATTR_WIPHY and
  *     %NL80211_ATTR_WIPHY_NAME.
  *     to the the specified ISO/IEC 3166-1 alpha2 country code. The core will
  *     store this as a valid request and then query userspace for it.
  *
+ * @NL80211_CMD_GET_MESH_PARAMS: Get mesh networking properties for the
+ *     interface identified by %NL80211_ATTR_IFINDEX
+ *
+ * @NL80211_CMD_SET_MESH_PARAMS: Set mesh networking properties for the
+ *      interface identified by %NL80211_ATTR_IFINDEX
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -148,6 +155,9 @@ enum nl80211_commands {
        NL80211_CMD_SET_REG,
        NL80211_CMD_REQ_SET_REG,
 
+       NL80211_CMD_GET_MESH_PARAMS,
+       NL80211_CMD_SET_MESH_PARAMS,
+
        /* add new commands above here */
 
        /* used to define NL80211_CMD_MAX below */
@@ -169,6 +179,7 @@ enum nl80211_commands {
  * @NL80211_ATTR_WIPHY: index of wiphy to operate on, cf.
  *     /sys/class/ieee80211/<phyname>/index
  * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming)
+ * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters
  *
  * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on
  * @NL80211_ATTR_IFNAME: network interface name
@@ -234,6 +245,9 @@ enum nl80211_commands {
  *     (u8, 0 or 1)
  * @NL80211_ATTR_BSS_SHORT_SLOT_TIME: whether short slot time enabled
  *     (u8, 0 or 1)
+ * @NL80211_ATTR_BSS_BASIC_RATES: basic rates, array of basic
+ *     rates in format defined by IEEE 802.11 7.3.2.2 but without the length
+ *     restriction (at most %NL80211_MAX_SUPP_RATES).
  *
  * @NL80211_ATTR_HT_CAPABILITY: HT Capability information element (from
  *     association request when used with NL80211_CMD_NEW_STATION)
@@ -296,6 +310,12 @@ enum nl80211_attrs {
        NL80211_ATTR_REG_ALPHA2,
        NL80211_ATTR_REG_RULES,
 
+       NL80211_ATTR_MESH_PARAMS,
+
+       NL80211_ATTR_BSS_BASIC_RATES,
+
+       NL80211_ATTR_WIPHY_TXQ_PARAMS,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
@@ -307,6 +327,8 @@ enum nl80211_attrs {
  * here
  */
 #define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY
+#define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES
+#define NL80211_ATTR_WIPHY_TXQ_PARAMS NL80211_ATTR_WIPHY_TXQ_PARAMS
 
 #define NL80211_MAX_SUPP_RATES                 32
 #define NL80211_MAX_SUPP_REG_RULES             32
@@ -452,17 +474,29 @@ enum nl80211_mpath_info {
  *     an array of nested frequency attributes
  * @NL80211_BAND_ATTR_RATES: supported bitrates in this band,
  *     an array of nested bitrate attributes
+ * @NL80211_BAND_ATTR_HT_MCS_SET: 16-byte attribute containing the MCS set as
+ *     defined in 802.11n
+ * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE
+ * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n
+ * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n
  */
 enum nl80211_band_attr {
        __NL80211_BAND_ATTR_INVALID,
        NL80211_BAND_ATTR_FREQS,
        NL80211_BAND_ATTR_RATES,
 
+       NL80211_BAND_ATTR_HT_MCS_SET,
+       NL80211_BAND_ATTR_HT_CAPA,
+       NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
+       NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
+
        /* keep last */
        __NL80211_BAND_ATTR_AFTER_LAST,
        NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1
 };
 
+#define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA
+
 /**
  * enum nl80211_frequency_attr - frequency attributes
  * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz
@@ -594,4 +628,113 @@ enum nl80211_mntr_flags {
        NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_AFTER_LAST - 1
 };
 
+/**
+ * enum nl80211_meshconf_params - mesh configuration parameters
+ *
+ * Mesh configuration parameters
+ *
+ * @__NL80211_MESHCONF_INVALID: internal use
+ *
+ * @NL80211_MESHCONF_RETRY_TIMEOUT: specifies the initial retry timeout in
+ * millisecond units, used by the Peer Link Open message
+ *
+ * @NL80211_MESHCONF_CONFIRM_TIMEOUT: specifies the inital confirm timeout, in
+ * millisecond units, used by the peer link management to close a peer link
+ *
+ * @NL80211_MESHCONF_HOLDING_TIMEOUT: specifies the holding timeout, in
+ * millisecond units
+ *
+ * @NL80211_MESHCONF_MAX_PEER_LINKS: maximum number of peer links allowed
+ * on this mesh interface
+ *
+ * @NL80211_MESHCONF_MAX_RETRIES: specifies the maximum number of peer link
+ * open retries that can be sent to establish a new peer link instance in a
+ * mesh
+ *
+ * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh
+ * point.
+ *
+ * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically
+ * open peer links when we detect compatible mesh peers.
+ *
+ * @NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES: the number of action frames
+ * containing a PREQ that an MP can send to a particular destination (path
+ * target)
+ *
+ * @NL80211_MESHCONF_PATH_REFRESH_TIME: how frequently to refresh mesh paths
+ * (in milliseconds)
+ *
+ * @NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT: minimum length of time to wait
+ * until giving up on a path discovery (in milliseconds)
+ *
+ * @NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT: The time (in TUs) for which mesh
+ * points receiving a PREQ shall consider the forwarding information from the
+ * root to be valid. (TU = time unit)
+ *
+ * @NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL: The minimum interval of time (in
+ * TUs) during which an MP can send only one action frame containing a PREQ
+ * reference element
+ *
+ * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs)
+ * that it takes for an HWMP information element to propagate across the mesh
+ *
+ * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
+ *
+ * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
+ */
+enum nl80211_meshconf_params {
+       __NL80211_MESHCONF_INVALID,
+       NL80211_MESHCONF_RETRY_TIMEOUT,
+       NL80211_MESHCONF_CONFIRM_TIMEOUT,
+       NL80211_MESHCONF_HOLDING_TIMEOUT,
+       NL80211_MESHCONF_MAX_PEER_LINKS,
+       NL80211_MESHCONF_MAX_RETRIES,
+       NL80211_MESHCONF_TTL,
+       NL80211_MESHCONF_AUTO_OPEN_PLINKS,
+       NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
+       NL80211_MESHCONF_PATH_REFRESH_TIME,
+       NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
+       NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
+       NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
+       NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
+
+       /* keep last */
+       __NL80211_MESHCONF_ATTR_AFTER_LAST,
+       NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_txq_attr - TX queue parameter attributes
+ * @__NL80211_TXQ_ATTR_INVALID: Attribute number 0 is reserved
+ * @NL80211_TXQ_ATTR_QUEUE: TX queue identifier (NL80211_TXQ_Q_*)
+ * @NL80211_TXQ_ATTR_TXOP: Maximum burst time in units of 32 usecs, 0 meaning
+ *     disabled
+ * @NL80211_TXQ_ATTR_CWMIN: Minimum contention window [a value of the form
+ *     2^n-1 in the range 1..32767]
+ * @NL80211_TXQ_ATTR_CWMAX: Maximum contention window [a value of the form
+ *     2^n-1 in the range 1..32767]
+ * @NL80211_TXQ_ATTR_AIFS: Arbitration interframe space [0..255]
+ * @__NL80211_TXQ_ATTR_AFTER_LAST: Internal
+ * @NL80211_TXQ_ATTR_MAX: Maximum TXQ attribute number
+ */
+enum nl80211_txq_attr {
+       __NL80211_TXQ_ATTR_INVALID,
+       NL80211_TXQ_ATTR_QUEUE,
+       NL80211_TXQ_ATTR_TXOP,
+       NL80211_TXQ_ATTR_CWMIN,
+       NL80211_TXQ_ATTR_CWMAX,
+       NL80211_TXQ_ATTR_AIFS,
+
+       /* keep last */
+       __NL80211_TXQ_ATTR_AFTER_LAST,
+       NL80211_TXQ_ATTR_MAX = __NL80211_TXQ_ATTR_AFTER_LAST - 1
+};
+
+enum nl80211_txq_q {
+       NL80211_TXQ_Q_VO,
+       NL80211_TXQ_Q_VI,
+       NL80211_TXQ_Q_BE,
+       NL80211_TXQ_Q_BK
+};
+
 #endif /* __LINUX_NL80211_H */
index 7cf7824df77814b327b1fb4abbd263273bd55bf4..e6aa8482ad7a910fdbf256b8d2cd7203d13f0e4b 100644 (file)
@@ -394,6 +394,20 @@ enum
 
 #define TCA_BASIC_MAX (__TCA_BASIC_MAX - 1)
 
+
+/* Cgroup classifier */
+
+enum
+{
+       TCA_CGROUP_UNSPEC,
+       TCA_CGROUP_ACT,
+       TCA_CGROUP_POLICE,
+       TCA_CGROUP_EMATCHES,
+       __TCA_CGROUP_MAX,
+};
+
+#define TCA_CGROUP_MAX (__TCA_CGROUP_MAX - 1)
+
 /* Extended Matches */
 
 struct tcf_ematch_tree_hdr
diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h
new file mode 100644 (file)
index 0000000..f9ddd03
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef _LINUX_RCULIST_NULLS_H
+#define _LINUX_RCULIST_NULLS_H
+
+#ifdef __KERNEL__
+
+/*
+ * RCU-protected list version
+ */
+#include <linux/list_nulls.h>
+#include <linux/rcupdate.h>
+
+/**
+ * hlist_nulls_del_init_rcu - deletes entry from hash list with re-initialization
+ * @n: the element to delete from the hash list.
+ *
+ * Note: hlist_nulls_unhashed() on the node return true after this. It is
+ * useful for RCU based read lockfree traversal if the writer side
+ * must know if the list entry is still hashed or already unhashed.
+ *
+ * In particular, it means that we can not poison the forward pointers
+ * that may still be used for walking the hash list and we can only
+ * zero the pprev pointer so list_unhashed() will return true after
+ * this.
+ *
+ * The caller must take whatever precautions are necessary (such as
+ * holding appropriate locks) to avoid racing with another
+ * list-mutation primitive, such as hlist_nulls_add_head_rcu() or
+ * hlist_nulls_del_rcu(), running on this same list.  However, it is
+ * perfectly legal to run concurrently with the _rcu list-traversal
+ * primitives, such as hlist_nulls_for_each_entry_rcu().
+ */
+static inline void hlist_nulls_del_init_rcu(struct hlist_nulls_node *n)
+{
+       if (!hlist_nulls_unhashed(n)) {
+               __hlist_nulls_del(n);
+               n->pprev = NULL;
+       }
+}
+
+/**
+ * hlist_nulls_del_rcu - deletes entry from hash list without re-initialization
+ * @n: the element to delete from the hash list.
+ *
+ * Note: hlist_nulls_unhashed() on entry does not return true after this,
+ * the entry is in an undefined state. It is useful for RCU based
+ * lockfree traversal.
+ *
+ * In particular, it means that we can not poison the forward
+ * pointers that may still be used for walking the hash list.
+ *
+ * The caller must take whatever precautions are necessary
+ * (such as holding appropriate locks) to avoid racing
+ * with another list-mutation primitive, such as hlist_nulls_add_head_rcu()
+ * or hlist_nulls_del_rcu(), running on this same list.
+ * However, it is perfectly legal to run concurrently with
+ * the _rcu list-traversal primitives, such as
+ * hlist_nulls_for_each_entry().
+ */
+static inline void hlist_nulls_del_rcu(struct hlist_nulls_node *n)
+{
+       __hlist_nulls_del(n);
+       n->pprev = LIST_POISON2;
+}
+
+/**
+ * hlist_nulls_add_head_rcu
+ * @n: the element to add to the hash list.
+ * @h: the list to add to.
+ *
+ * Description:
+ * Adds the specified element to the specified hlist_nulls,
+ * while permitting racing traversals.
+ *
+ * The caller must take whatever precautions are necessary
+ * (such as holding appropriate locks) to avoid racing
+ * with another list-mutation primitive, such as hlist_nulls_add_head_rcu()
+ * or hlist_nulls_del_rcu(), running on this same list.
+ * However, it is perfectly legal to run concurrently with
+ * the _rcu list-traversal primitives, such as
+ * hlist_nulls_for_each_entry_rcu(), used to prevent memory-consistency
+ * problems on Alpha CPUs.  Regardless of the type of CPU, the
+ * list-traversal primitive must be guarded by rcu_read_lock().
+ */
+static inline void hlist_nulls_add_head_rcu(struct hlist_nulls_node *n,
+                                       struct hlist_nulls_head *h)
+{
+       struct hlist_nulls_node *first = h->first;
+
+       n->next = first;
+       n->pprev = &h->first;
+       rcu_assign_pointer(h->first, n);
+       if (!is_a_nulls(first))
+               first->pprev = &n->next;
+}
+/**
+ * hlist_nulls_for_each_entry_rcu - iterate over rcu list of given type
+ * @tpos:      the type * to use as a loop cursor.
+ * @pos:       the &struct hlist_nulls_node to use as a loop cursor.
+ * @head:      the head for your list.
+ * @member:    the name of the hlist_nulls_node within the struct.
+ *
+ */
+#define hlist_nulls_for_each_entry_rcu(tpos, pos, head, member) \
+       for (pos = rcu_dereference((head)->first);                       \
+               (!is_a_nulls(pos)) &&                   \
+               ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \
+               pos = rcu_dereference(pos->next))
+
+#endif
+#endif
index 2725f4e5a9bf837f691ddc88361fcc280af4fb96..a01b6f84e3bcbc710565ff87b5e28bf7e1cc8e8f 100644 (file)
@@ -250,6 +250,9 @@ typedef unsigned char *sk_buff_data_t;
  *     @tc_verd: traffic control verdict
  *     @ndisc_nodetype: router type (from link layer)
  *     @do_not_encrypt: set to prevent encryption of this frame
+ *     @requeue: set to indicate that the wireless core should attempt
+ *             a software retry on this frame if we failed to
+ *             receive an ACK for it
  *     @dma_cookie: a cookie to one of several possible DMA operations
  *             done by skb DMA functions
  *     @secmark: security marking
@@ -269,8 +272,9 @@ struct sk_buff {
                struct  dst_entry       *dst;
                struct  rtable          *rtable;
        };
+#ifdef CONFIG_XFRM
        struct  sec_path        *sp;
-
+#endif
        /*
         * This is the control buffer. It is free to use for every
         * layer. Please put your private variables there. If you
@@ -325,6 +329,7 @@ struct sk_buff {
 #endif
 #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
        __u8                    do_not_encrypt:1;
+       __u8                    requeue:1;
 #endif
        /* 0/13/14 bit hole */
 
@@ -1864,6 +1869,18 @@ static inline void skb_copy_queue_mapping(struct sk_buff *to, const struct sk_bu
        to->queue_mapping = from->queue_mapping;
 }
 
+#ifdef CONFIG_XFRM
+static inline struct sec_path *skb_sec_path(struct sk_buff *skb)
+{
+       return skb->sp;
+}
+#else
+static inline struct sec_path *skb_sec_path(struct sk_buff *skb)
+{
+       return NULL;
+}
+#endif
+
 static inline int skb_is_gso(const struct sk_buff *skb)
 {
        return skb_shinfo(skb)->gso_size;
diff --git a/include/linux/smsc911x.h b/include/linux/smsc911x.h
new file mode 100644 (file)
index 0000000..47c4ffd
--- /dev/null
@@ -0,0 +1,42 @@
+/***************************************************************************
+ *
+ * Copyright (C) 2004-2008 SMSC
+ * Copyright (C) 2005-2008 ARM
+ *
+ * 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 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ ***************************************************************************/
+#ifndef __LINUX_SMSC911X_H__
+#define __LINUX_SMSC911X_H__
+
+#include <linux/phy.h>
+
+/* platform_device configuration data, should be assigned to
+ * the platform_device's dev.platform_data */
+struct smsc911x_platform_config {
+       unsigned int irq_polarity;
+       unsigned int irq_type;
+       phy_interface_t phy_interface;
+};
+
+/* Constants for platform_device irq polarity configuration */
+#define SMSC911X_IRQ_POLARITY_ACTIVE_LOW       0
+#define SMSC911X_IRQ_POLARITY_ACTIVE_HIGH      1
+
+/* Constants for platform_device irq type configuration */
+#define SMSC911X_IRQ_TYPE_OPEN_DRAIN           0
+#define SMSC911X_IRQ_TYPE_PUSH_PULL            1
+
+#endif /* __LINUX_SMSC911X_H__ */
index 6fd7b016517f4e588f9cba7de616af751547e2c7..0127daca43548c85c219abc6445101165380eef9 100644 (file)
@@ -139,14 +139,14 @@ static inline char *__svc_print_addr(struct sockaddr *addr,
 {
        switch (addr->sa_family) {
        case AF_INET:
-               snprintf(buf, len, "%u.%u.%u.%u, port=%u",
-                       NIPQUAD(((struct sockaddr_in *) addr)->sin_addr),
+               snprintf(buf, len, "%pI4, port=%u",
+                       &((struct sockaddr_in *)addr)->sin_addr,
                        ntohs(((struct sockaddr_in *) addr)->sin_port));
                break;
 
        case AF_INET6:
-               snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x, port=%u",
-                       NIP6(((struct sockaddr_in6 *) addr)->sin6_addr),
+               snprintf(buf, len, "%pI6, port=%u",
+                        &((struct sockaddr_in6 *)addr)->sin6_addr,
                        ntohs(((struct sockaddr_in6 *) addr)->sin6_port));
                break;
 
index 5e33761b9b8a9d7c038d6e062221f5f68a0def3b..5cdd0aa8bde94b0d53c37fe8bf463b9d07845c15 100644 (file)
@@ -20,6 +20,7 @@
 #define VIRTIO_NET_F_HOST_TSO6 12      /* Host can handle TSOv6 in. */
 #define VIRTIO_NET_F_HOST_ECN  13      /* Host can handle TSO[6] w/ ECN in. */
 #define VIRTIO_NET_F_HOST_UFO  14      /* Host can handle UFO in. */
+#define VIRTIO_NET_F_MRG_RXBUF 15      /* Host can merge receive buffers. */
 
 struct virtio_net_config
 {
@@ -44,4 +45,12 @@ struct virtio_net_hdr
        __u16 csum_start;       /* Position to start checksumming from */
        __u16 csum_offset;      /* Offset after that to place checksum */
 };
+
+/* This is the version of the header to use when the MRG_RXBUF
+ * feature has been negotiated. */
+struct virtio_net_hdr_mrg_rxbuf {
+       struct virtio_net_hdr hdr;
+       __u16 num_buffers;      /* Number of merged rx buffers */
+};
+
 #endif /* _LINUX_VIRTIO_NET_H */
index 4bc1e6b86cb21ae1b0bc3ab24fd26806e4e3445e..52f3abd453a1386953963e6765725eb3d60fc025 100644 (file)
@@ -199,6 +199,9 @@ enum {
 #define XFRM_MSG_NEWSPDINFO XFRM_MSG_NEWSPDINFO
        XFRM_MSG_GETSPDINFO,
 #define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO
+
+       XFRM_MSG_MAPPING,
+#define XFRM_MSG_MAPPING XFRM_MSG_MAPPING
        __XFRM_MSG_MAX
 };
 #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1)
@@ -438,6 +441,15 @@ struct xfrm_user_migrate {
        __u16                           new_family;
 };
 
+struct xfrm_user_mapping {
+       struct xfrm_usersa_id           id;
+       __u32                           reqid;
+       xfrm_address_t                  old_saddr;
+       xfrm_address_t                  new_saddr;
+       __be16                          old_sport;
+       __be16                          new_sport;
+};
+
 #ifndef __KERNEL__
 /* backwards compatibility for userspace */
 #define XFRMGRP_ACQUIRE                1
@@ -464,6 +476,8 @@ enum xfrm_nlgroups {
 #define XFRMNLGRP_REPORT       XFRMNLGRP_REPORT
        XFRMNLGRP_MIGRATE,
 #define XFRMNLGRP_MIGRATE      XFRMNLGRP_MIGRATE
+       XFRMNLGRP_MAPPING,
+#define XFRMNLGRP_MAPPING      XFRMNLGRP_MAPPING
        __XFRMNLGRP_MAX
 };
 #define XFRMNLGRP_MAX  (__XFRMNLGRP_MAX - 1)
index 0e85ec39b6380de904efe8c2ac0c89b3cb6f12e0..1d57835d73f2d3d7c262c643a41e2b571f49fe4f 100644 (file)
@@ -280,11 +280,16 @@ struct mpath_info {
  *     (0 = no, 1 = yes, -1 = do not change)
  * @use_short_slot_time: Whether the use of short slot time is allowed
  *     (0 = no, 1 = yes, -1 = do not change)
+ * @basic_rates: basic rates in IEEE 802.11 format
+ *     (or NULL for no change)
+ * @basic_rates_len: number of basic rates
  */
 struct bss_parameters {
        int use_cts_prot;
        int use_short_preamble;
        int use_short_slot_time;
+       u8 *basic_rates;
+       u8 basic_rates_len;
 };
 
 /**
@@ -331,22 +336,59 @@ struct ieee80211_regdomain {
        struct ieee80211_reg_rule reg_rules[];
 };
 
-#define MHZ_TO_KHZ(freq) (freq * 1000)
-#define KHZ_TO_MHZ(freq) (freq / 1000)
-#define DBI_TO_MBI(gain) (gain * 100)
-#define MBI_TO_DBI(gain) (gain / 100)
-#define DBM_TO_MBM(gain) (gain * 100)
-#define MBM_TO_DBM(gain) (gain / 100)
+#define MHZ_TO_KHZ(freq) ((freq) * 1000)
+#define KHZ_TO_MHZ(freq) ((freq) / 1000)
+#define DBI_TO_MBI(gain) ((gain) * 100)
+#define MBI_TO_DBI(gain) ((gain) / 100)
+#define DBM_TO_MBM(gain) ((gain) * 100)
+#define MBM_TO_DBM(gain) ((gain) / 100)
 
 #define REG_RULE(start, end, bw, gain, eirp, reg_flags) { \
-       .freq_range.start_freq_khz = (start) * 1000, \
-       .freq_range.end_freq_khz = (end) * 1000, \
-       .freq_range.max_bandwidth_khz = (bw) * 1000, \
-       .power_rule.max_antenna_gain = (gain) * 100, \
-       .power_rule.max_eirp = (eirp) * 100, \
+       .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \
+       .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \
+       .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \
+       .power_rule.max_antenna_gain = DBI_TO_MBI(gain), \
+       .power_rule.max_eirp = DBM_TO_MBM(eirp), \
        .flags = reg_flags, \
        }
 
+struct mesh_config {
+       /* Timeouts in ms */
+       /* Mesh plink management parameters */
+       u16 dot11MeshRetryTimeout;
+       u16 dot11MeshConfirmTimeout;
+       u16 dot11MeshHoldingTimeout;
+       u16 dot11MeshMaxPeerLinks;
+       u8  dot11MeshMaxRetries;
+       u8  dot11MeshTTL;
+       bool auto_open_plinks;
+       /* HWMP parameters */
+       u8  dot11MeshHWMPmaxPREQretries;
+       u32 path_refresh_time;
+       u16 min_discovery_timeout;
+       u32 dot11MeshHWMPactivePathTimeout;
+       u16 dot11MeshHWMPpreqMinInterval;
+       u16 dot11MeshHWMPnetDiameterTraversalTime;
+};
+
+/**
+ * struct ieee80211_txq_params - TX queue parameters
+ * @queue: TX queue identifier (NL80211_TXQ_Q_*)
+ * @txop: Maximum burst time in units of 32 usecs, 0 meaning disabled
+ * @cwmin: Minimum contention window [a value of the form 2^n-1 in the range
+ *     1..32767]
+ * @cwmax: Maximum contention window [a value of the form 2^n-1 in the range
+ *     1..32767]
+ * @aifs: Arbitration interframe space [0..255]
+ */
+struct ieee80211_txq_params {
+       enum nl80211_txq_q queue;
+       u16 txop;
+       u16 cwmin;
+       u16 cwmax;
+       u8 aifs;
+};
+
 /* from net/wireless.h */
 struct wiphy;
 
@@ -397,9 +439,17 @@ struct wiphy;
  *
  * @change_station: Modify a given station.
  *
+ * @get_mesh_params: Put the current mesh parameters into *params
+ *
+ * @set_mesh_params: Set mesh parameters.
+ *     The mask is a bitfield which tells us which parameters to
+ *     set, and which to leave alone.
+ *
  * @set_mesh_cfg: set mesh parameters (by now, just mesh id)
  *
  * @change_bss: Modify parameters for a given BSS.
+ *
+ * @set_txq_params: Set TX queue parameters
  */
 struct cfg80211_ops {
        int     (*add_virtual_intf)(struct wiphy *wiphy, char *name,
@@ -452,9 +502,17 @@ struct cfg80211_ops {
        int     (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev,
                               int idx, u8 *dst, u8 *next_hop,
                               struct mpath_info *pinfo);
-
+       int     (*get_mesh_params)(struct wiphy *wiphy,
+                               struct net_device *dev,
+                               struct mesh_config *conf);
+       int     (*set_mesh_params)(struct wiphy *wiphy,
+                               struct net_device *dev,
+                               const struct mesh_config *nconf, u32 mask);
        int     (*change_bss)(struct wiphy *wiphy, struct net_device *dev,
                              struct bss_parameters *params);
+
+       int     (*set_txq_params)(struct wiphy *wiphy,
+                                 struct ieee80211_txq_params *params);
 };
 
 #endif /* __NET_CFG80211_H */
index 8a8b71e5f3f13578a2004fe84ee6e17dc7caa9a4..6c778799bf103f3dd7dd6dab9948b66b5c19d535 100644 (file)
@@ -59,8 +59,11 @@ struct dst_entry
 
        struct neighbour        *neighbour;
        struct hh_cache         *hh;
+#ifdef CONFIG_XFRM
        struct xfrm_state       *xfrm;
-
+#else
+       void                    *__pad1;
+#endif
        int                     (*input)(struct sk_buff*);
        int                     (*output)(struct sk_buff*);
 
@@ -70,8 +73,20 @@ struct dst_entry
 
 #ifdef CONFIG_NET_CLS_ROUTE
        __u32                   tclassid;
+#else
+       __u32                   __pad2;
 #endif
 
+
+       /*
+        * Align __refcnt to a 64 bytes alignment
+        * (L1_CACHE_SIZE would be too much)
+        */
+#ifdef CONFIG_64BIT
+       long                    __pad_to_align_refcnt[2];
+#else
+       long                    __pad_to_align_refcnt[1];
+#endif
        /*
         * __refcnt wants to be on a different cache line from
         * input/output/ops or performance tanks badly
@@ -103,7 +118,6 @@ struct dst_ops
        void                    (*link_failure)(struct sk_buff *);
        void                    (*update_pmtu)(struct dst_entry *dst, u32 mtu);
        int                     (*local_out)(struct sk_buff *skb);
-       int                     entry_size;
 
        atomic_t                entries;
        struct kmem_cache               *kmem_cachep;
@@ -157,6 +171,11 @@ dst_metric_locked(struct dst_entry *dst, int metric)
 
 static inline void dst_hold(struct dst_entry * dst)
 {
+       /*
+        * If your kernel compilation stops here, please check
+        * __pad_to_align_refcnt declaration in struct dst_entry
+        */
+       BUILD_BUG_ON(offsetof(struct dst_entry, __refcnt) & 63);
        atomic_inc(&dst->__refcnt);
 }
 
index 93a56de3594be63de5c2a2847ea78fbb68db940b..738734a4653bd0f65bcc0edf579301b15de99bff 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/if_ether.h>    /* ETH_ALEN */
 #include <linux/kernel.h>      /* ARRAY_SIZE */
 #include <linux/wireless.h>
+#include <linux/ieee80211.h>
 
 #define IEEE80211_VERSION "git-1.1.13"
 
@@ -127,10 +128,6 @@ static inline bool ieee80211_ratelimit_debug(u32 level)
 }
 #endif                         /* CONFIG_IEEE80211_DEBUG */
 
-/* escape_essid() is intended to be used in debug (and possibly error)
- * messages. It should never be used for passing essid to user space. */
-const char *escape_essid(const char *essid, u8 essid_len);
-
 /*
  * To use the debug system:
  *
@@ -218,94 +215,6 @@ struct ieee80211_snap_hdr {
 #define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
 #define WLAN_GET_SEQ_SEQ(seq)  (((seq) & IEEE80211_SCTL_SEQ) >> 4)
 
-/* Authentication algorithms */
-#define WLAN_AUTH_OPEN 0
-#define WLAN_AUTH_SHARED_KEY 1
-#define WLAN_AUTH_LEAP 2
-
-#define WLAN_AUTH_CHALLENGE_LEN 128
-
-#define WLAN_CAPABILITY_ESS (1<<0)
-#define WLAN_CAPABILITY_IBSS (1<<1)
-#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
-#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
-#define WLAN_CAPABILITY_PRIVACY (1<<4)
-#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
-#define WLAN_CAPABILITY_PBCC (1<<6)
-#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
-#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8)
-#define WLAN_CAPABILITY_QOS (1<<9)
-#define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10)
-#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
-
-/* 802.11g ERP information element */
-#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
-#define WLAN_ERP_USE_PROTECTION (1<<1)
-#define WLAN_ERP_BARKER_PREAMBLE (1<<2)
-
-/* Status codes */
-enum ieee80211_statuscode {
-       WLAN_STATUS_SUCCESS = 0,
-       WLAN_STATUS_UNSPECIFIED_FAILURE = 1,
-       WLAN_STATUS_CAPS_UNSUPPORTED = 10,
-       WLAN_STATUS_REASSOC_NO_ASSOC = 11,
-       WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12,
-       WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13,
-       WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14,
-       WLAN_STATUS_CHALLENGE_FAIL = 15,
-       WLAN_STATUS_AUTH_TIMEOUT = 16,
-       WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17,
-       WLAN_STATUS_ASSOC_DENIED_RATES = 18,
-       /* 802.11b */
-       WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19,
-       WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20,
-       WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21,
-       /* 802.11h */
-       WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22,
-       WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23,
-       WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24,
-       /* 802.11g */
-       WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
-       WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
-       /* 802.11i */
-       WLAN_STATUS_INVALID_IE = 40,
-       WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
-       WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42,
-       WLAN_STATUS_INVALID_AKMP = 43,
-       WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
-       WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
-       WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
-};
-
-/* Reason codes */
-enum ieee80211_reasoncode {
-       WLAN_REASON_UNSPECIFIED = 1,
-       WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
-       WLAN_REASON_DEAUTH_LEAVING = 3,
-       WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
-       WLAN_REASON_DISASSOC_AP_BUSY = 5,
-       WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
-       WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
-       WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8,
-       WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9,
-       /* 802.11h */
-       WLAN_REASON_DISASSOC_BAD_POWER = 10,
-       WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11,
-       /* 802.11i */
-       WLAN_REASON_INVALID_IE = 13,
-       WLAN_REASON_MIC_FAILURE = 14,
-       WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
-       WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16,
-       WLAN_REASON_IE_DIFFERENT = 17,
-       WLAN_REASON_INVALID_GROUP_CIPHER = 18,
-       WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19,
-       WLAN_REASON_INVALID_AKMP = 20,
-       WLAN_REASON_UNSUPP_RSN_VERSION = 21,
-       WLAN_REASON_INVALID_RSN_IE_CAP = 22,
-       WLAN_REASON_IEEE8021X_FAILED = 23,
-       WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
-};
-
 /* Action categories - 802.11h */
 enum ieee80211_actioncategories {
        WLAN_ACTION_SPECTRUM_MGMT = 0,
@@ -534,15 +443,6 @@ enum ieee80211_mfie {
        MFIE_TYPE_QOS_PARAMETER = 222,
 };
 
-/* Minimal header; can be used for passing 802.11 frames with sufficient
- * information to determine what type of underlying data type is actually
- * stored in the data. */
-struct ieee80211_hdr {
-       __le16 frame_ctl;
-       __le16 duration_id;
-       u8 payload[0];
-} __attribute__ ((packed));
-
 struct ieee80211_hdr_1addr {
        __le16 frame_ctl;
        __le16 duration_id;
@@ -590,18 +490,6 @@ struct ieee80211_hdr_3addrqos {
        __le16 qos_ctl;
 } __attribute__ ((packed));
 
-struct ieee80211_hdr_4addrqos {
-       __le16 frame_ctl;
-       __le16 duration_id;
-       u8 addr1[ETH_ALEN];
-       u8 addr2[ETH_ALEN];
-       u8 addr3[ETH_ALEN];
-       __le16 seq_ctl;
-       u8 addr4[ETH_ALEN];
-       u8 payload[0];
-       __le16 qos_ctl;
-} __attribute__ ((packed));
-
 struct ieee80211_info_element {
        u8 id;
        u8 len;
@@ -733,7 +621,6 @@ struct ieee80211_txb {
 
 #define MAX_WPA_IE_LEN 64
 
-#define NETWORK_EMPTY_ESSID    (1<<0)
 #define NETWORK_HAS_OFDM       (1<<1)
 #define NETWORK_HAS_CCK        (1<<2)
 
@@ -1135,22 +1022,6 @@ static inline void *ieee80211_priv(struct net_device *dev)
        return ((struct ieee80211_device *)netdev_priv(dev))->priv;
 }
 
-static inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
-{
-       /* Single white space is for Linksys APs */
-       if (essid_len == 1 && essid[0] == ' ')
-               return 1;
-
-       /* Otherwise, if the entire essid is 0, we assume it is hidden */
-       while (essid_len) {
-               essid_len--;
-               if (essid[essid_len] != '\0')
-                       return 0;
-       }
-
-       return 1;
-}
-
 static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee,
                                          int mode)
 {
@@ -1208,7 +1079,7 @@ static inline int ieee80211_get_hdrlen(u16 fc)
 
 static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
 {
-       switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
+       switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control))) {
        case IEEE80211_1ADDR_LEN:
                return ((struct ieee80211_hdr_1addr *)hdr)->payload;
        case IEEE80211_2ADDR_LEN:
index 5cc182f9ecae58154b9d0a0d175887822d81dc2b..4818960451112cf34f20721e16e749baae7e5923 100644 (file)
@@ -41,8 +41,8 @@
  * I'll experiment with dynamic table growth later.
  */
 struct inet_ehash_bucket {
-       struct hlist_head chain;
-       struct hlist_head twchain;
+       struct hlist_nulls_head chain;
+       struct hlist_nulls_head twchain;
 };
 
 /* There are a few simple rules, which allow for local port reuse by
@@ -77,13 +77,20 @@ struct inet_ehash_bucket {
  * ports are created in O(1) time?  I thought so. ;-)  -DaveM
  */
 struct inet_bind_bucket {
+#ifdef CONFIG_NET_NS
        struct net              *ib_net;
+#endif
        unsigned short          port;
        signed short            fastreuse;
        struct hlist_node       node;
        struct hlist_head       owners;
 };
 
+static inline struct net *ib_net(struct inet_bind_bucket *ib)
+{
+       return read_pnet(&ib->ib_net);
+}
+
 #define inet_bind_bucket_for_each(tb, node, head) \
        hlist_for_each_entry(tb, node, head, node)
 
index 80e4977631b8b18ba67e44024895fee03adbe7f9..4b8ece22b8e94417879a6504e87afe5bd0ecc371 100644 (file)
@@ -110,7 +110,7 @@ struct inet_timewait_sock {
 #define tw_state               __tw_common.skc_state
 #define tw_reuse               __tw_common.skc_reuse
 #define tw_bound_dev_if                __tw_common.skc_bound_dev_if
-#define tw_node                        __tw_common.skc_node
+#define tw_node                        __tw_common.skc_nulls_node
 #define tw_bind_node           __tw_common.skc_bind_node
 #define tw_refcnt              __tw_common.skc_refcnt
 #define tw_hash                        __tw_common.skc_hash
@@ -137,10 +137,10 @@ struct inet_timewait_sock {
        struct hlist_node       tw_death_node;
 };
 
-static inline void inet_twsk_add_node(struct inet_timewait_sock *tw,
-                                     struct hlist_head *list)
+static inline void inet_twsk_add_node_rcu(struct inet_timewait_sock *tw,
+                                     struct hlist_nulls_head *list)
 {
-       hlist_add_head(&tw->tw_node, list);
+       hlist_nulls_add_head_rcu(&tw->tw_node, list);
 }
 
 static inline void inet_twsk_add_bind_node(struct inet_timewait_sock *tw,
@@ -175,7 +175,7 @@ static inline int inet_twsk_del_dead_node(struct inet_timewait_sock *tw)
 }
 
 #define inet_twsk_for_each(tw, node, head) \
-       hlist_for_each_entry(tw, node, head, tw_node)
+       hlist_nulls_for_each_entry(tw, node, head, tw_node)
 
 #define inet_twsk_for_each_inmate(tw, node, jail) \
        hlist_for_each_entry(tw, node, jail, tw_death_node)
index fe9fcf73c85ed26135b802a959382a85e5d64e43..8f6abf4883e3008a77b92fbf0c778582bd242b02 100644 (file)
@@ -87,12 +87,12 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len,
        int len;
 #ifdef CONFIG_IP_VS_IPV6
        if (af == AF_INET6)
-               len = snprintf(&buf[*idx], buf_len - *idx, "[" NIP6_FMT "]",
-                              NIP6(addr->in6)) + 1;
+               len = snprintf(&buf[*idx], buf_len - *idx, "[%pI6]",
+                              &addr->in6) + 1;
        else
 #endif
-               len = snprintf(&buf[*idx], buf_len - *idx, NIPQUAD_FMT,
-                              NIPQUAD(addr->ip)) + 1;
+               len = snprintf(&buf[*idx], buf_len - *idx, "%pI4",
+                              &addr->ip) + 1;
 
        *idx += len;
        BUG_ON(*idx > buf_len + 1);
@@ -503,9 +503,6 @@ struct ip_vs_scheduler {
        char                    *name;          /* scheduler name */
        atomic_t                refcnt;         /* reference counter */
        struct module           *module;        /* THIS_MODULE/NULL */
-#ifdef CONFIG_IP_VS_IPV6
-       int                     supports_ipv6;  /* scheduler has IPv6 support */
-#endif
 
        /* scheduler initializing service */
        int (*init_service)(struct ip_vs_service *svc);
diff --git a/include/net/lib80211.h b/include/net/lib80211.h
new file mode 100644 (file)
index 0000000..e1558a1
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * lib80211.h -- common bits for IEEE802.11 wireless drivers
+ *
+ * Copyright (c) 2008, John W. Linville <linville@tuxdriver.com>
+ *
+ */
+
+#ifndef LIB80211_H
+#define LIB80211_H
+
+#include <linux/ieee80211.h>
+
+/* print_ssid() is intended to be used in debug (and possibly error)
+ * messages. It should never be used for passing ssid to user space. */
+const char *print_ssid(char *buf, const char *ssid, u8 ssid_len);
+#define DECLARE_SSID_BUF(var) char var[IEEE80211_MAX_SSID_LEN * 4 + 1] __maybe_unused
+
+#endif /* LIB80211_H */
index 8856e2d60e9fe5cc04e83445e2b9ea5a6f63f031..53856003aa183993761e8856cf344329ef11d97e 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright 2002-2005, Devicescape Software, Inc.
  * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
- * Copyright 2007      Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net>
  *
  * 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
@@ -81,22 +81,6 @@ enum ieee80211_notification_types {
        IEEE80211_NOTIFY_RE_ASSOC,
 };
 
-/**
- * struct ieee80211_ht_bss_info - describing BSS's HT characteristics
- *
- * This structure describes most essential parameters needed
- * to describe 802.11n HT characteristics in a BSS.
- *
- * @primary_channel: channel number of primery channel
- * @bss_cap: 802.11n's general BSS capabilities (e.g. channel width)
- * @bss_op_mode: 802.11n's BSS operation modes (e.g. HT protection)
- */
-struct ieee80211_ht_bss_info {
-       u8 primary_channel;
-       u8 bss_cap;  /* use IEEE80211_HT_IE_CHA_ */
-       u8 bss_op_mode; /* use IEEE80211_HT_IE_ */
-};
-
 /**
  * enum ieee80211_max_queues - maximum number of queues
  *
@@ -115,7 +99,7 @@ enum ieee80211_max_queues {
  * The information provided in this structure is required for QoS
  * transmit queue configuration. Cf. IEEE 802.11 7.3.2.29.
  *
- * @aifs: arbitration interface space [0..255]
+ * @aifs: arbitration interframe space [0..255]
  * @cw_min: minimum contention window [a value of the form
  *     2^n-1 in the range 1..32767]
  * @cw_max: maximum contention window [like @cw_min]
@@ -171,6 +155,19 @@ enum ieee80211_bss_change {
        BSS_CHANGED_BASIC_RATES         = 1<<5,
 };
 
+/**
+ * struct ieee80211_bss_ht_conf - BSS's changing HT configuration
+ * @secondary_channel_offset: secondary channel offset, uses
+ *     %IEEE80211_HT_PARAM_CHA_SEC_ values
+ * @width_40_ok: indicates that 40 MHz bandwidth may be used for TX
+ * @operation_mode: HT operation mode (like in &struct ieee80211_ht_info)
+ */
+struct ieee80211_bss_ht_conf {
+       u8 secondary_channel_offset;
+       bool width_40_ok;
+       u16 operation_mode;
+};
+
 /**
  * struct ieee80211_bss_conf - holds the BSS's changing parameters
  *
@@ -180,15 +177,17 @@ enum ieee80211_bss_change {
  * @assoc: association status
  * @aid: association ID number, valid only when @assoc is true
  * @use_cts_prot: use CTS protection
- * @use_short_preamble: use 802.11b short preamble
- * @use_short_slot: use short slot time (only relevant for ERP)
+ * @use_short_preamble: use 802.11b short preamble;
+ *     if the hardware cannot handle this it must set the
+ *     IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE hardware flag
+ * @use_short_slot: use short slot time (only relevant for ERP);
+ *     if the hardware cannot handle this it must set the
+ *     IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE hardware flag
  * @dtim_period: num of beacons before the next DTIM, for PSM
  * @timestamp: beacon timestamp
  * @beacon_int: beacon interval
  * @assoc_capability: capabilities taken from assoc resp
- * @assoc_ht: association in HT mode
- * @ht_conf: ht capabilities
- * @ht_bss_conf: ht extended capabilities
+ * @ht: BSS's HT configuration
  * @basic_rates: bitmap of basic rates, each bit stands for an
  *     index into the rate table configured by the driver in
  *     the current band.
@@ -206,10 +205,7 @@ struct ieee80211_bss_conf {
        u16 assoc_capability;
        u64 timestamp;
        u64 basic_rates;
-       /* ht related data */
-       bool assoc_ht;
-       struct ieee80211_ht_info *ht_conf;
-       struct ieee80211_ht_bss_info *ht_bss_conf;
+       struct ieee80211_bss_ht_conf ht;
 };
 
 /**
@@ -218,29 +214,24 @@ struct ieee80211_bss_conf {
  * These flags are used with the @flags member of &ieee80211_tx_info.
  *
  * @IEEE80211_TX_CTL_REQ_TX_STATUS: request TX status callback for this frame.
- * @IEEE80211_TX_CTL_USE_RTS_CTS: use RTS-CTS before sending frame
- * @IEEE80211_TX_CTL_USE_CTS_PROTECT: use CTS protection for the frame (e.g.,
- *     for combined 802.11g / 802.11b networks)
+ * @IEEE80211_TX_CTL_ASSIGN_SEQ: The driver has to assign a sequence
+ *     number to this frame, taking care of not overwriting the fragment
+ *     number and increasing the sequence number only when the
+ *     IEEE80211_TX_CTL_FIRST_FRAGMENT flag is set. mac80211 will properly
+ *     assign sequence numbers to QoS-data frames but cannot do so correctly
+ *     for non-QoS-data and management frames because beacons need them from
+ *     that counter as well and mac80211 cannot guarantee proper sequencing.
+ *     If this flag is set, the driver should instruct the hardware to
+ *     assign a sequence number to the frame or assign one itself. Cf. IEEE
+ *     802.11-2007 7.1.3.4.1 paragraph 3. This flag will always be set for
+ *     beacons and always be clear for frames without a sequence number field.
  * @IEEE80211_TX_CTL_NO_ACK: tell the low level not to wait for an ack
- * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: TBD
  * @IEEE80211_TX_CTL_CLEAR_PS_FILT: clear powersave filter for destination
  *     station
- * @IEEE80211_TX_CTL_REQUEUE: TBD
  * @IEEE80211_TX_CTL_FIRST_FRAGMENT: this is a first fragment of the frame
- * @IEEE80211_TX_CTL_SHORT_PREAMBLE: TBD
- * @IEEE80211_TX_CTL_LONG_RETRY_LIMIT: this frame should be send using the
- *     through set_retry_limit configured long retry value
  * @IEEE80211_TX_CTL_SEND_AFTER_DTIM: send this frame after DTIM beacon
  * @IEEE80211_TX_CTL_AMPDU: this frame should be sent as part of an A-MPDU
- * @IEEE80211_TX_CTL_OFDM_HT: this frame can be sent in HT OFDM rates. number
- *     of streams when this flag is on can be extracted from antenna_sel_tx,
- *     so if 1 antenna is marked use SISO, 2 antennas marked use MIMO, n
- *     antennas marked use MIMO_n.
- * @IEEE80211_TX_CTL_GREEN_FIELD: use green field protection for this frame
- * @IEEE80211_TX_CTL_40_MHZ_WIDTH: send this frame using 40 Mhz channel width
- * @IEEE80211_TX_CTL_DUP_DATA: duplicate data frame on both 20 Mhz channels
- * @IEEE80211_TX_CTL_SHORT_GI: send this frame using short guard interval
- * @IEEE80211_TX_CTL_INJECTED: TBD
+ * @IEEE80211_TX_CTL_INJECTED: Frame was injected, internal to mac80211.
  * @IEEE80211_TX_STAT_TX_FILTERED: The frame was not transmitted
  *     because the destination STA was in powersave mode.
  * @IEEE80211_TX_STAT_ACK: Frame was acknowledged
@@ -248,62 +239,66 @@ struct ieee80211_bss_conf {
  *     is for the whole aggregation.
  * @IEEE80211_TX_STAT_AMPDU_NO_BACK: no block ack was returned,
  *     so consider using block ack request (BAR).
- * @IEEE80211_TX_CTL_ASSIGN_SEQ: The driver has to assign a sequence
- *     number to this frame, taking care of not overwriting the fragment
- *     number and increasing the sequence number only when the
- *     IEEE80211_TX_CTL_FIRST_FRAGMENT flags is set. mac80211 will properly
- *     assign sequence numbers to QoS-data frames but cannot do so correctly
- *     for non-QoS-data and management frames because beacons need them from
- *     that counter as well and mac80211 cannot guarantee proper sequencing.
- *     If this flag is set, the driver should instruct the hardware to
- *     assign a sequence number to the frame or assign one itself. Cf. IEEE
- *     802.11-2007 7.1.3.4.1 paragraph 3. This flag will always be set for
- *     beacons always be clear for frames without a sequence number field.
+ * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: internal to mac80211, can be
+ *     set by rate control algorithms to indicate probe rate, will
+ *     be cleared for fragmented frames (except on the last fragment)
  */
 enum mac80211_tx_control_flags {
        IEEE80211_TX_CTL_REQ_TX_STATUS          = BIT(0),
-       IEEE80211_TX_CTL_USE_RTS_CTS            = BIT(2),
-       IEEE80211_TX_CTL_USE_CTS_PROTECT        = BIT(3),
-       IEEE80211_TX_CTL_NO_ACK                 = BIT(4),
-       IEEE80211_TX_CTL_RATE_CTRL_PROBE        = BIT(5),
-       IEEE80211_TX_CTL_CLEAR_PS_FILT          = BIT(6),
-       IEEE80211_TX_CTL_REQUEUE                = BIT(7),
-       IEEE80211_TX_CTL_FIRST_FRAGMENT         = BIT(8),
-       IEEE80211_TX_CTL_SHORT_PREAMBLE         = BIT(9),
-       IEEE80211_TX_CTL_LONG_RETRY_LIMIT       = BIT(10),
-       IEEE80211_TX_CTL_SEND_AFTER_DTIM        = BIT(12),
-       IEEE80211_TX_CTL_AMPDU                  = BIT(13),
-       IEEE80211_TX_CTL_OFDM_HT                = BIT(14),
-       IEEE80211_TX_CTL_GREEN_FIELD            = BIT(15),
-       IEEE80211_TX_CTL_40_MHZ_WIDTH           = BIT(16),
-       IEEE80211_TX_CTL_DUP_DATA               = BIT(17),
-       IEEE80211_TX_CTL_SHORT_GI               = BIT(18),
-       IEEE80211_TX_CTL_INJECTED               = BIT(19),
-       IEEE80211_TX_STAT_TX_FILTERED           = BIT(20),
-       IEEE80211_TX_STAT_ACK                   = BIT(21),
-       IEEE80211_TX_STAT_AMPDU                 = BIT(22),
-       IEEE80211_TX_STAT_AMPDU_NO_BACK         = BIT(23),
-       IEEE80211_TX_CTL_ASSIGN_SEQ             = BIT(24),
+       IEEE80211_TX_CTL_ASSIGN_SEQ             = BIT(1),
+       IEEE80211_TX_CTL_NO_ACK                 = BIT(2),
+       IEEE80211_TX_CTL_CLEAR_PS_FILT          = BIT(3),
+       IEEE80211_TX_CTL_FIRST_FRAGMENT         = BIT(4),
+       IEEE80211_TX_CTL_SEND_AFTER_DTIM        = BIT(5),
+       IEEE80211_TX_CTL_AMPDU                  = BIT(6),
+       IEEE80211_TX_CTL_INJECTED               = BIT(7),
+       IEEE80211_TX_STAT_TX_FILTERED           = BIT(8),
+       IEEE80211_TX_STAT_ACK                   = BIT(9),
+       IEEE80211_TX_STAT_AMPDU                 = BIT(10),
+       IEEE80211_TX_STAT_AMPDU_NO_BACK         = BIT(11),
+       IEEE80211_TX_CTL_RATE_CTRL_PROBE        = BIT(12),
+};
+
+enum mac80211_rate_control_flags {
+       IEEE80211_TX_RC_USE_RTS_CTS             = BIT(0),
+       IEEE80211_TX_RC_USE_CTS_PROTECT         = BIT(1),
+       IEEE80211_TX_RC_USE_SHORT_PREAMBLE      = BIT(2),
+
+       /* rate index is an MCS rate number instead of an index */
+       IEEE80211_TX_RC_MCS                     = BIT(3),
+       IEEE80211_TX_RC_GREEN_FIELD             = BIT(4),
+       IEEE80211_TX_RC_40_MHZ_WIDTH            = BIT(5),
+       IEEE80211_TX_RC_DUP_DATA                = BIT(6),
+       IEEE80211_TX_RC_SHORT_GI                = BIT(7),
 };
 
 
-#define IEEE80211_TX_INFO_DRIVER_DATA_SIZE \
-       (sizeof(((struct sk_buff *)0)->cb) - 8)
-#define IEEE80211_TX_INFO_DRIVER_DATA_PTRS \
-       (IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *))
+/* there are 40 bytes if you don't need the rateset to be kept */
+#define IEEE80211_TX_INFO_DRIVER_DATA_SIZE 40
+
+/* if you do need the rateset, then you have less space */
+#define IEEE80211_TX_INFO_RATE_DRIVER_DATA_SIZE 24
 
-/* maximum number of alternate rate retry stages */
-#define IEEE80211_TX_MAX_ALTRATE       3
+/* maximum number of rate stages */
+#define IEEE80211_TX_MAX_RATES 5
 
 /**
- * struct ieee80211_tx_altrate - alternate rate selection/status
+ * struct ieee80211_tx_rate - rate selection/status
  *
- * @rate_idx: rate index to attempt to send with
- * @limit: number of retries before fallback
+ * @idx: rate index to attempt to send with
+ * @flags: rate control flags (&enum mac80211_rate_control_flags)
+ * @count: number of tries in this rate before going to the next rate
+ *
+ * A value of -1 for @idx indicates an invalid rate and, if used
+ * in an array of retry rates, that no more rates should be tried.
+ *
+ * When used for transmit status reporting, the driver should
+ * always report the rate along with the flags it used.
  */
-struct ieee80211_tx_altrate {
-       s8 rate_idx;
-       u8 limit;
+struct ieee80211_tx_rate {
+       s8 idx;
+       u8 count;
+       u8 flags;
 };
 
 /**
@@ -318,15 +313,12 @@ struct ieee80211_tx_altrate {
  * it may be NULL.
  *
  * @flags: transmit info flags, defined above
- * @band: TBD
- * @tx_rate_idx: TBD
- * @antenna_sel_tx: TBD
+ * @band: the band to transmit on (use for checking for races)
+ * @antenna_sel_tx: antenna to use, 0 for automatic diversity
  * @control: union for control data
  * @status: union for status data
  * @driver_data: array of driver_data pointers
  * @retry_count: number of retries
- * @excessive_retries: set to 1 if the frame was retried many times
- *     but not acknowledged
  * @ampdu_ack_len: number of aggregated frames.
  *     relevant only if IEEE80211_TX_STATUS_AMPDU was set.
  * @ampdu_ack_map: block ack bit map for the aggregation.
@@ -337,31 +329,43 @@ struct ieee80211_tx_info {
        /* common information */
        u32 flags;
        u8 band;
-       s8 tx_rate_idx;
+
        u8 antenna_sel_tx;
 
-       /* 1 byte hole */
+       /* 2 byte hole */
 
        union {
                struct {
+                       union {
+                               /* rate control */
+                               struct {
+                                       struct ieee80211_tx_rate rates[
+                                               IEEE80211_TX_MAX_RATES];
+                                       s8 rts_cts_rate_idx;
+                               };
+                               /* only needed before rate control */
+                               unsigned long jiffies;
+                       };
                        /* NB: vif can be NULL for injected frames */
                        struct ieee80211_vif *vif;
                        struct ieee80211_key_conf *hw_key;
                        struct ieee80211_sta *sta;
-                       unsigned long jiffies;
-                       s8 rts_cts_rate_idx;
-                       u8 retry_limit;
-                       struct ieee80211_tx_altrate retries[IEEE80211_TX_MAX_ALTRATE];
                } control;
                struct {
+                       struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES];
+                       u8 ampdu_ack_len;
                        u64 ampdu_ack_map;
                        int ack_signal;
-                       struct ieee80211_tx_altrate retries[IEEE80211_TX_MAX_ALTRATE + 1];
-                       u8 retry_count;
-                       bool excessive_retries;
-                       u8 ampdu_ack_len;
+                       /* 8 bytes free */
                } status;
-               void *driver_data[IEEE80211_TX_INFO_DRIVER_DATA_PTRS];
+               struct {
+                       struct ieee80211_tx_rate driver_rates[
+                               IEEE80211_TX_MAX_RATES];
+                       void *rate_driver_data[
+                               IEEE80211_TX_INFO_RATE_DRIVER_DATA_SIZE / sizeof(void *)];
+               };
+               void *driver_data[
+                       IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *)];
        };
 };
 
@@ -370,6 +374,41 @@ static inline struct ieee80211_tx_info *IEEE80211_SKB_CB(struct sk_buff *skb)
        return (struct ieee80211_tx_info *)skb->cb;
 }
 
+/**
+ * ieee80211_tx_info_clear_status - clear TX status
+ *
+ * @info: The &struct ieee80211_tx_info to be cleared.
+ *
+ * When the driver passes an skb back to mac80211, it must report
+ * a number of things in TX status. This function clears everything
+ * in the TX status but the rate control information (it does clear
+ * the count since you need to fill that in anyway).
+ *
+ * NOTE: You can only use this function if you do NOT use
+ *      info->driver_data! Use info->rate_driver_data
+ *      instead if you need only the less space that allows.
+ */
+static inline void
+ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
+{
+       int i;
+
+       BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, status.rates) !=
+                    offsetof(struct ieee80211_tx_info, control.rates));
+       BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, status.rates) !=
+                    offsetof(struct ieee80211_tx_info, driver_rates));
+       BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, status.rates) != 8);
+       /* clear the rate counts */
+       for (i = 0; i < IEEE80211_TX_MAX_RATES; i++)
+               info->status.rates[i].count = 0;
+
+       BUILD_BUG_ON(
+           offsetof(struct ieee80211_tx_info, status.ampdu_ack_len) != 23);
+       memset(&info->status.ampdu_ack_len, 0,
+              sizeof(struct ieee80211_tx_info) -
+              offsetof(struct ieee80211_tx_info, status.ampdu_ack_len));
+}
+
 
 /**
  * enum mac80211_rx_flags - receive flags
@@ -442,21 +481,48 @@ struct ieee80211_rx_status {
  *
  * Flags to define PHY configuration options
  *
- * @IEEE80211_CONF_SHORT_SLOT_TIME: use 802.11g short slot time
  * @IEEE80211_CONF_RADIOTAP: add radiotap header at receive time (if supported)
- * @IEEE80211_CONF_SUPPORT_HT_MODE: use 802.11n HT capabilities (if supported)
  * @IEEE80211_CONF_PS: Enable 802.11 power save mode
  */
 enum ieee80211_conf_flags {
-       /*
-        * TODO: IEEE80211_CONF_SHORT_SLOT_TIME will be removed once drivers
-        * have been converted to use bss_info_changed() for slot time
-        * configuration
-        */
-       IEEE80211_CONF_SHORT_SLOT_TIME  = (1<<0),
-       IEEE80211_CONF_RADIOTAP         = (1<<1),
-       IEEE80211_CONF_SUPPORT_HT_MODE  = (1<<2),
-       IEEE80211_CONF_PS               = (1<<3),
+       IEEE80211_CONF_RADIOTAP         = (1<<0),
+       IEEE80211_CONF_PS               = (1<<1),
+};
+
+/* XXX: remove all this once drivers stop trying to use it */
+static inline int __deprecated __IEEE80211_CONF_SHORT_SLOT_TIME(void)
+{
+       return 0;
+}
+#define IEEE80211_CONF_SHORT_SLOT_TIME (__IEEE80211_CONF_SHORT_SLOT_TIME())
+
+struct ieee80211_ht_conf {
+       bool enabled;
+};
+
+/**
+ * enum ieee80211_conf_changed - denotes which configuration changed
+ *
+ * @IEEE80211_CONF_CHANGE_RADIO_ENABLED: the value of radio_enabled changed
+ * @IEEE80211_CONF_CHANGE_BEACON_INTERVAL: the beacon interval changed
+ * @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed
+ * @IEEE80211_CONF_CHANGE_RADIOTAP: the radiotap flag changed
+ * @IEEE80211_CONF_CHANGE_PS: the PS flag changed
+ * @IEEE80211_CONF_CHANGE_POWER: the TX power changed
+ * @IEEE80211_CONF_CHANGE_CHANNEL: the channel changed
+ * @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed
+ * @IEEE80211_CONF_CHANGE_HT: HT configuration changed
+ */
+enum ieee80211_conf_changed {
+       IEEE80211_CONF_CHANGE_RADIO_ENABLED     = BIT(0),
+       IEEE80211_CONF_CHANGE_BEACON_INTERVAL   = BIT(1),
+       IEEE80211_CONF_CHANGE_LISTEN_INTERVAL   = BIT(2),
+       IEEE80211_CONF_CHANGE_RADIOTAP          = BIT(3),
+       IEEE80211_CONF_CHANGE_PS                = BIT(4),
+       IEEE80211_CONF_CHANGE_POWER             = BIT(5),
+       IEEE80211_CONF_CHANGE_CHANNEL           = BIT(6),
+       IEEE80211_CONF_CHANGE_RETRY_LIMITS      = BIT(7),
+       IEEE80211_CONF_CHANGE_HT                = BIT(8),
 };
 
 /**
@@ -465,34 +531,31 @@ enum ieee80211_conf_flags {
  * This struct indicates how the driver shall configure the hardware.
  *
  * @radio_enabled: when zero, driver is required to switch off the radio.
- *     TODO make a flag
  * @beacon_int: beacon interval (TODO make interface config)
  * @listen_interval: listen interval in units of beacon interval
  * @flags: configuration flags defined above
  * @power_level: requested transmit power (in dBm)
- * @max_antenna_gain: maximum antenna gain (in dBi)
- * @antenna_sel_tx: transmit antenna selection, 0: default/diversity,
- *     1/2: antenna 0/1
- * @antenna_sel_rx: receive antenna selection, like @antenna_sel_tx
- * @ht_conf: describes current self configuration of 802.11n HT capabilies
- * @ht_bss_conf: describes current BSS configuration of 802.11n HT parameters
  * @channel: the channel to tune to
+ * @ht: the HT configuration for the device
+ * @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame
+ *    (a frame not RTS protected), called "dot11LongRetryLimit" in 802.11,
+ *    but actually means the number of transmissions not the number of retries
+ * @short_frame_max_tx_count: Maximum number of transmissions for a "short"
+ *    frame, called "dot11ShortRetryLimit" in 802.11, but actually means the
+ *    number of transmissions not the number of retries
  */
 struct ieee80211_conf {
-       int radio_enabled;
-
        int beacon_int;
-       u16 listen_interval;
        u32 flags;
        int power_level;
-       int max_antenna_gain;
-       u8 antenna_sel_tx;
-       u8 antenna_sel_rx;
 
-       struct ieee80211_channel *channel;
+       u16 listen_interval;
+       bool radio_enabled;
 
-       struct ieee80211_ht_info ht_conf;
-       struct ieee80211_ht_bss_info ht_bss_conf;
+       u8 long_frame_max_tx_count, short_frame_max_tx_count;
+
+       struct ieee80211_channel *channel;
+       struct ieee80211_ht_conf ht;
 };
 
 /**
@@ -502,11 +565,14 @@ struct ieee80211_conf {
  * use during the life of a virtual interface.
  *
  * @type: type of this virtual interface
+ * @bss_conf: BSS configuration for this interface, either our own
+ *     or the BSS we're associated to
  * @drv_priv: data area for driver use, will always be aligned to
  *     sizeof(void *).
  */
 struct ieee80211_vif {
        enum nl80211_iftype type;
+       struct ieee80211_bss_conf bss_conf;
        /* must be last */
        u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
 };
@@ -550,14 +616,12 @@ struct ieee80211_if_init_conf {
  * enum ieee80211_if_conf_change - interface config change flags
  *
  * @IEEE80211_IFCC_BSSID: The BSSID changed.
- * @IEEE80211_IFCC_SSID: The SSID changed.
  * @IEEE80211_IFCC_BEACON: The beacon for this interface changed
  *     (currently AP and MESH only), use ieee80211_beacon_get().
  */
 enum ieee80211_if_conf_change {
        IEEE80211_IFCC_BSSID    = BIT(0),
-       IEEE80211_IFCC_SSID     = BIT(1),
-       IEEE80211_IFCC_BEACON   = BIT(2),
+       IEEE80211_IFCC_BEACON   = BIT(1),
 };
 
 /**
@@ -565,11 +629,6 @@ enum ieee80211_if_conf_change {
  *
  * @changed: parameters that have changed, see &enum ieee80211_if_conf_change.
  * @bssid: BSSID of the network we are associated to/creating.
- * @ssid: used (together with @ssid_len) by drivers for hardware that
- *     generate beacons independently. The pointer is valid only during the
- *     config_interface() call, so copy the value somewhere if you need
- *     it.
- * @ssid_len: length of the @ssid field.
  *
  * This structure is passed to the config_interface() callback of
  * &struct ieee80211_hw.
@@ -577,8 +636,6 @@ enum ieee80211_if_conf_change {
 struct ieee80211_if_conf {
        u32 changed;
        u8 *bssid;
-       u8 *ssid;
-       size_t ssid_len;
 };
 
 /**
@@ -685,7 +742,7 @@ enum set_key_cmd {
  * @addr: MAC address
  * @aid: AID we assigned to the station if we're an AP
  * @supp_rates: Bitmap of supported rates (per band)
- * @ht_info: HT capabilities of this STA
+ * @ht_cap: HT capabilities of this STA; restricted to our own TX capabilities
  * @drv_priv: data area for driver use, will always be aligned to
  *     sizeof(void *), size is determined in hw information.
  */
@@ -693,7 +750,7 @@ struct ieee80211_sta {
        u64 supp_rates[IEEE80211_NUM_BANDS];
        u8 addr[ETH_ALEN];
        u16 aid;
-       struct ieee80211_ht_info ht_info;
+       struct ieee80211_sta_ht_cap ht_cap;
 
        /* must be last */
        u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
@@ -777,6 +834,9 @@ enum ieee80211_tkip_key_type {
  * @IEEE80211_HW_SPECTRUM_MGMT:
  *     Hardware supports spectrum management defined in 802.11h
  *     Measurement, Channel Switch, Quieting, TPC
+ *
+ * @IEEE80211_HW_AMPDU_AGGREGATION:
+ *     Hardware supports 11n A-MPDU aggregation.
  */
 enum ieee80211_hw_flags {
        IEEE80211_HW_RX_INCLUDES_FCS                    = 1<<1,
@@ -788,6 +848,7 @@ enum ieee80211_hw_flags {
        IEEE80211_HW_SIGNAL_DBM                         = 1<<7,
        IEEE80211_HW_NOISE_DBM                          = 1<<8,
        IEEE80211_HW_SPECTRUM_MGMT                      = 1<<9,
+       IEEE80211_HW_AMPDU_AGGREGATION                  = 1<<10,
 };
 
 /**
@@ -846,8 +907,8 @@ enum ieee80211_hw_flags {
  * @sta_data_size: size (in bytes) of the drv_priv data area
  *     within &struct ieee80211_sta.
  *
- * @max_altrates: maximum number of alternate rate retry stages
- * @max_altrate_tries: maximum number of tries for each stage
+ * @max_rates: maximum number of alternate rate retry stages
+ * @max_rate_tries: maximum number of tries for each stage
  */
 struct ieee80211_hw {
        struct ieee80211_conf conf;
@@ -864,12 +925,10 @@ struct ieee80211_hw {
        u16 ampdu_queues;
        u16 max_listen_interval;
        s8 max_signal;
-       u8 max_altrates;
-       u8 max_altrate_tries;
+       u8 max_rates;
+       u8 max_rate_tries;
 };
 
-struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy);
-
 /**
  * SET_IEEE80211_DEV - set device for 802.11 hardware
  *
@@ -882,7 +941,7 @@ static inline void SET_IEEE80211_DEV(struct ieee80211_hw *hw, struct device *dev
 }
 
 /**
- * SET_IEEE80211_PERM_ADDR - set the permanenet MAC address for 802.11 hardware
+ * SET_IEEE80211_PERM_ADDR - set the permanent MAC address for 802.11 hardware
  *
  * @hw: the &struct ieee80211_hw to set the MAC address for
  * @addr: the address to set
@@ -906,9 +965,9 @@ static inline struct ieee80211_rate *
 ieee80211_get_tx_rate(const struct ieee80211_hw *hw,
                      const struct ieee80211_tx_info *c)
 {
-       if (WARN_ON(c->tx_rate_idx < 0))
+       if (WARN_ON(c->control.rates[0].idx < 0))
                return NULL;
-       return &hw->wiphy->bands[c->band]->bitrates[c->tx_rate_idx];
+       return &hw->wiphy->bands[c->band]->bitrates[c->control.rates[0].idx];
 }
 
 static inline struct ieee80211_rate *
@@ -924,9 +983,9 @@ static inline struct ieee80211_rate *
 ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
                             const struct ieee80211_tx_info *c, int idx)
 {
-       if (c->control.retries[idx].rate_idx < 0)
+       if (c->control.rates[idx + 1].idx < 0)
                return NULL;
-       return &hw->wiphy->bands[c->band]->bitrates[c->control.retries[idx].rate_idx];
+       return &hw->wiphy->bands[c->band]->bitrates[c->control.rates[idx + 1].idx];
 }
 
 /**
@@ -975,7 +1034,7 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
  * This happens everytime the iv16 wraps around (every 65536 packets). The
  * set_key() call will happen only once for each key (unless the AP did
  * rekeying), it will not include a valid phase 1 key. The valid phase 1 key is
- * provided by udpate_tkip_key only. The trigger that makes mac80211 call this
+ * provided by update_tkip_key only. The trigger that makes mac80211 call this
  * handler is software decryption with wrap around of iv16.
  */
 
@@ -1068,12 +1127,14 @@ enum ieee80211_filter_flags {
  * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation
  * @IEEE80211_AMPDU_TX_START: start Tx aggregation
  * @IEEE80211_AMPDU_TX_STOP: stop Tx aggregation
+ * @IEEE80211_AMPDU_TX_RESUME: resume TX aggregation
  */
 enum ieee80211_ampdu_mlme_action {
        IEEE80211_AMPDU_RX_START,
        IEEE80211_AMPDU_RX_STOP,
        IEEE80211_AMPDU_TX_START,
        IEEE80211_AMPDU_TX_STOP,
+       IEEE80211_AMPDU_TX_RESUME,
 };
 
 /**
@@ -1109,7 +1170,7 @@ enum ieee80211_ampdu_mlme_action {
  *     Must be implemented.
  *
  * @add_interface: Called when a netdevice attached to the hardware is
- *     enabled. Because it is not called for monitor mode devices, @open
+ *     enabled. Because it is not called for monitor mode devices, @start
  *     and @stop must be implemented.
  *     The driver should perform any initialization it needs before
  *     the device can be enabled. The initial configuration for the
@@ -1175,10 +1236,8 @@ enum ieee80211_ampdu_mlme_action {
  *     the device does fragmentation by itself; if this method is assigned then
  *     the stack will not do fragmentation.
  *
- * @set_retry_limit: Configuration of retry limits (if device needs it)
- *
  * @sta_notify: Notifies low level driver about addition or removal
- *     of assocaited station or AP.
+ *     of associated station or AP.
  *
  * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
  *     bursting) for a hardware TX queue.
@@ -1219,7 +1278,7 @@ struct ieee80211_ops {
                             struct ieee80211_if_init_conf *conf);
        void (*remove_interface)(struct ieee80211_hw *hw,
                                 struct ieee80211_if_init_conf *conf);
-       int (*config)(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
+       int (*config)(struct ieee80211_hw *hw, u32 changed);
        int (*config_interface)(struct ieee80211_hw *hw,
                                struct ieee80211_vif *vif,
                                struct ieee80211_if_conf *conf);
@@ -1246,8 +1305,6 @@ struct ieee80211_ops {
                             u32 *iv32, u16 *iv16);
        int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value);
        int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value);
-       int (*set_retry_limit)(struct ieee80211_hw *hw,
-                              u32 short_retry, u32 long_retr);
        void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        enum sta_notify_cmd, struct ieee80211_sta *sta);
        int (*conf_tx)(struct ieee80211_hw *hw, u16 queue,
@@ -1480,7 +1537,7 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
  * the next beacon frame from the 802.11 code. The low-level is responsible
  * for calling this function before beacon data is needed (e.g., based on
  * hardware interrupt). Returned skb is used only once and low-level driver
- * is responsible of freeing it.
+ * is responsible for freeing it.
  */
 struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
                                     struct ieee80211_vif *vif);
@@ -1823,24 +1880,38 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw,
 
 
 /* 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 ieee80211_tx_rate_control - rate control information for/from RC algo
+ *
+ * @hw: The hardware the algorithm is invoked for.
+ * @sband: The band this frame is being transmitted on.
+ * @bss_conf: the current BSS configuration
+ * @reported_rate: The rate control algorithm can fill this in to indicate
+ *     which rate should be reported to userspace as the current rate and
+ *     used for rate calculations in the mesh network.
+ * @rts: whether RTS will be used for this frame because it is longer than the
+ *     RTS threshold
+ * @short_preamble: whether mac80211 will request short-preamble transmission
+ *     if the selected rate supports it
+ * @max_rate_idx: user-requested maximum rate (not MCS for now)
+ * @skb: the skb that will be transmitted, the control information in it needs
+ *     to be filled in
+ */
+struct ieee80211_tx_rate_control {
+       struct ieee80211_hw *hw;
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_bss_conf *bss_conf;
+       struct sk_buff *skb;
+       struct ieee80211_tx_rate reported_rate;
+       bool rts, short_preamble;
+       u8 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);
@@ -1852,10 +1923,8 @@ struct rate_control_ops {
        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 (*get_rate)(void *priv, struct ieee80211_sta *sta, void *priv_sta,
+                        struct ieee80211_tx_rate_control *txrc);
 
        void (*add_sta_debugfs)(void *priv, void *priv_sta,
                                struct dentry *dir);
index 11dd0137c6a5b34ee1434c4b699b68d304ce5d46..ce532f2222ce723daf21eaea7429bcbb5a26b4a8 100644 (file)
@@ -108,6 +108,20 @@ extern void                        ndisc_send_redirect(struct sk_buff *skb,
 
 extern int                     ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir);
 
+extern struct sk_buff          *ndisc_build_skb(struct net_device *dev,
+                                                const struct in6_addr *daddr,
+                                                const struct in6_addr *saddr,
+                                                struct icmp6hdr *icmp6h,
+                                                const struct in6_addr *target,
+                                                int llinfo);
+
+extern void                    ndisc_send_skb(struct sk_buff *skb,
+                                              struct net_device *dev,
+                                              struct neighbour *neigh,
+                                              const struct in6_addr *daddr,
+                                              const struct in6_addr *saddr,
+                                              struct icmp6hdr *icmp6h);
+
 
 
 /*
index aa4b708654a497a318732f7c5cfb6f00fdc65d1a..d8d790e56d3daa2d7b1751220ca1fa4314a57346 100644 (file)
@@ -180,9 +180,6 @@ struct neigh_table
        __u32                   hash_rnd;
        unsigned int            hash_chain_gc;
        struct pneigh_entry     **phash_buckets;
-#ifdef CONFIG_PROC_FS
-       struct proc_dir_entry   *pde;
-#endif
 };
 
 /* flags for neigh_update() */
@@ -223,11 +220,7 @@ extern void                        neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *p
 static inline
 struct net                     *neigh_parms_net(const struct neigh_parms *parms)
 {
-#ifdef CONFIG_NET_NS
-       return parms->net;
-#else
-       return &init_net;
-#endif
+       return read_pnet(&parms->net);
 }
 
 extern unsigned long           neigh_rand_reach_time(unsigned long base);
@@ -244,11 +237,7 @@ extern int                 pneigh_delete(struct neigh_table *tbl, struct net *net, const void
 static inline
 struct net                     *pneigh_net(const struct pneigh_entry *pneigh)
 {
-#ifdef CONFIG_NET_NS
-       return pneigh->net;
-#else
-       return &init_net;
-#endif
+       return read_pnet(&pneigh->net);
 }
 
 extern void neigh_app_ns(struct neighbour *n);
index 700c53a3c6fa22d9e49f522616da870b99522d3c..319557789a40aab7b47609035ceb600dc6ab8dc0 100644 (file)
@@ -192,6 +192,24 @@ static inline void release_net(struct net *net)
 }
 #endif
 
+#ifdef CONFIG_NET_NS
+
+static inline void write_pnet(struct net **pnet, struct net *net)
+{
+       *pnet = net;
+}
+
+static inline struct net *read_pnet(struct net * const *pnet)
+{
+       return *pnet;
+}
+
+#else
+
+#define write_pnet(pnet, net)  do { (void)(net);} while (0)
+#define read_pnet(pnet)                (&init_net)
+
+#endif
 
 #define for_each_net(VAR)                              \
        list_for_each_entry(VAR, &net_namespace_list, list)
index a6874ba22d546322dc5ef9c2c86271003ec156e4..f2f6aa73dc10fd3ec65d3428118c486c2b51b20a 100644 (file)
@@ -112,20 +112,20 @@ struct nf_conntrack_tuple_mask
 static inline void nf_ct_dump_tuple_ip(const struct nf_conntrack_tuple *t)
 {
 #ifdef DEBUG
-       printk("tuple %p: %u " NIPQUAD_FMT ":%hu -> " NIPQUAD_FMT ":%hu\n",
+       printk("tuple %p: %u %pI4:%hu -> %pI4:%hu\n",
               t, t->dst.protonum,
-              NIPQUAD(t->src.u3.ip), ntohs(t->src.u.all),
-              NIPQUAD(t->dst.u3.ip), ntohs(t->dst.u.all));
+              &t->src.u3.ip, ntohs(t->src.u.all),
+              &t->dst.u3.ip, ntohs(t->dst.u.all));
 #endif
 }
 
 static inline void nf_ct_dump_tuple_ipv6(const struct nf_conntrack_tuple *t)
 {
 #ifdef DEBUG
-       printk("tuple %p: %u " NIP6_FMT " %hu -> " NIP6_FMT " %hu\n",
+       printk("tuple %p: %u %pI6 %hu -> %pI6 %hu\n",
               t, t->dst.protonum,
-              NIP6(*(struct in6_addr *)t->src.u3.all), ntohs(t->src.u.all),
-              NIP6(*(struct in6_addr *)t->dst.u3.all), ntohs(t->dst.u.all));
+              t->src.u3.all, ntohs(t->src.u.all),
+              t->dst.u3.all, ntohs(t->dst.u.all));
 #endif
 }
 
index 3643bbb8e585e4018cbd66606d64c12a7edf84ac..46b7764f17740d5b2484ddf6d2c706c2218db305 100644 (file)
@@ -233,7 +233,7 @@ extern int          nla_parse(struct nlattr *tb[], int maxtype,
 extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype);
 extern size_t          nla_strlcpy(char *dst, const struct nlattr *nla,
                                    size_t dstsize);
-extern int             nla_memcpy(void *dest, struct nlattr *src, int count);
+extern int             nla_memcpy(void *dest, const struct nlattr *src, int count);
 extern int             nla_memcmp(const struct nlattr *nla, const void *data,
                                   size_t size);
 extern int             nla_strcmp(const struct nlattr *nla, const char *str);
@@ -741,7 +741,7 @@ static inline struct nlattr *nla_find_nested(struct nlattr *nla, int attrtype)
  * See nla_parse()
  */
 static inline int nla_parse_nested(struct nlattr *tb[], int maxtype,
-                                  struct nlattr *nla,
+                                  const struct nlattr *nla,
                                   const struct nla_policy *policy)
 {
        return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
@@ -875,7 +875,7 @@ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
  * nla_get_u32 - return payload of u32 attribute
  * @nla: u32 netlink attribute
  */
-static inline u32 nla_get_u32(struct nlattr *nla)
+static inline u32 nla_get_u32(const struct nlattr *nla)
 {
        return *(u32 *) nla_data(nla);
 }
@@ -884,7 +884,7 @@ static inline u32 nla_get_u32(struct nlattr *nla)
  * nla_get_be32 - return payload of __be32 attribute
  * @nla: __be32 netlink attribute
  */
-static inline __be32 nla_get_be32(struct nlattr *nla)
+static inline __be32 nla_get_be32(const struct nlattr *nla)
 {
        return *(__be32 *) nla_data(nla);
 }
@@ -893,7 +893,7 @@ static inline __be32 nla_get_be32(struct nlattr *nla)
  * nla_get_u16 - return payload of u16 attribute
  * @nla: u16 netlink attribute
  */
-static inline u16 nla_get_u16(struct nlattr *nla)
+static inline u16 nla_get_u16(const struct nlattr *nla)
 {
        return *(u16 *) nla_data(nla);
 }
@@ -902,7 +902,7 @@ static inline u16 nla_get_u16(struct nlattr *nla)
  * nla_get_be16 - return payload of __be16 attribute
  * @nla: __be16 netlink attribute
  */
-static inline __be16 nla_get_be16(struct nlattr *nla)
+static inline __be16 nla_get_be16(const struct nlattr *nla)
 {
        return *(__be16 *) nla_data(nla);
 }
@@ -911,7 +911,7 @@ static inline __be16 nla_get_be16(struct nlattr *nla)
  * nla_get_le16 - return payload of __le16 attribute
  * @nla: __le16 netlink attribute
  */
-static inline __le16 nla_get_le16(struct nlattr *nla)
+static inline __le16 nla_get_le16(const struct nlattr *nla)
 {
        return *(__le16 *) nla_data(nla);
 }
@@ -920,7 +920,7 @@ static inline __le16 nla_get_le16(struct nlattr *nla)
  * nla_get_u8 - return payload of u8 attribute
  * @nla: u8 netlink attribute
  */
-static inline u8 nla_get_u8(struct nlattr *nla)
+static inline u8 nla_get_u8(const struct nlattr *nla)
 {
        return *(u8 *) nla_data(nla);
 }
@@ -929,7 +929,7 @@ static inline u8 nla_get_u8(struct nlattr *nla)
  * nla_get_u64 - return payload of u64 attribute
  * @nla: u64 netlink attribute
  */
-static inline u64 nla_get_u64(struct nlattr *nla)
+static inline u64 nla_get_u64(const struct nlattr *nla)
 {
        u64 tmp;
 
@@ -942,7 +942,7 @@ static inline u64 nla_get_u64(struct nlattr *nla)
  * nla_get_flag - return payload of flag attribute
  * @nla: flag netlink attribute
  */
-static inline int nla_get_flag(struct nlattr *nla)
+static inline int nla_get_flag(const struct nlattr *nla)
 {
        return !!nla;
 }
@@ -953,7 +953,7 @@ static inline int nla_get_flag(struct nlattr *nla)
  *
  * Returns the number of milliseconds in jiffies.
  */
-static inline unsigned long nla_get_msecs(struct nlattr *nla)
+static inline unsigned long nla_get_msecs(const struct nlattr *nla)
 {
        u64 msecs = nla_get_u64(nla);
 
index ece1c926b5d18204855d484349148bb442823c6e..977f482d97a95144f0f777df1b0bbbacb7f1b11e 100644 (file)
@@ -49,6 +49,8 @@ struct netns_ipv4 {
        int sysctl_icmp_ratelimit;
        int sysctl_icmp_ratemask;
        int sysctl_icmp_errors_use_inbound_ifaddr;
+       int sysctl_rt_cache_rebuild_count;
+       int current_rt_cache_rebuild_count;
 
        struct timer_list rt_secret_timer;
        atomic_t rt_genid;
index aa9e282db4855ffe0733f72f6e25b3cc89b913bc..d1ca3144464438f6ba1dc442ec36315d6f7e195f 100644 (file)
@@ -246,7 +246,7 @@ struct tcf_ematch_ops
 };
 
 extern int tcf_em_register(struct tcf_ematch_ops *);
-extern int tcf_em_unregister(struct tcf_ematch_ops *);
+extern void tcf_em_unregister(struct tcf_ematch_ops *);
 extern int tcf_em_tree_validate(struct tcf_proto *, struct nlattr *,
                                struct tcf_ematch_tree *);
 extern void tcf_em_tree_destroy(struct tcf_proto *, struct tcf_ematch_tree *);
index 3fe49d808957309f29f1cb9532892fc06e936f2e..f8c47429044aee1db7ddf54a14e405305be51b0a 100644 (file)
@@ -53,7 +53,6 @@ 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;
@@ -111,7 +110,7 @@ struct Qdisc_ops
 
        int                     (*enqueue)(struct sk_buff *, struct Qdisc *);
        struct sk_buff *        (*dequeue)(struct Qdisc *);
-       int                     (*requeue)(struct sk_buff *, struct Qdisc *);
+       struct sk_buff *        (*peek)(struct Qdisc *);
        unsigned int            (*drop)(struct Qdisc *);
 
        int                     (*init)(struct Qdisc *, struct nlattr *arg);
@@ -432,19 +431,38 @@ static inline struct sk_buff *qdisc_dequeue_tail(struct Qdisc *sch)
        return __qdisc_dequeue_tail(sch, &sch->q);
 }
 
-static inline int __qdisc_requeue(struct sk_buff *skb, struct Qdisc *sch,
-                                 struct sk_buff_head *list)
+static inline struct sk_buff *qdisc_peek_head(struct Qdisc *sch)
 {
-       __skb_queue_head(list, skb);
-       sch->qstats.backlog += qdisc_pkt_len(skb);
-       sch->qstats.requeues++;
+       return skb_peek(&sch->q);
+}
 
-       return NET_XMIT_SUCCESS;
+/* generic pseudo peek method for non-work-conserving qdisc */
+static inline struct sk_buff *qdisc_peek_dequeued(struct Qdisc *sch)
+{
+       /* we can reuse ->gso_skb because peek isn't called for root qdiscs */
+       if (!sch->gso_skb) {
+               sch->gso_skb = sch->dequeue(sch);
+               if (sch->gso_skb)
+                       /* it's still part of the queue */
+                       sch->q.qlen++;
+       }
+
+       return sch->gso_skb;
 }
 
-static inline int qdisc_requeue(struct sk_buff *skb, struct Qdisc *sch)
+/* use instead of qdisc->dequeue() for all qdiscs queried with ->peek() */
+static inline struct sk_buff *qdisc_dequeue_peeked(struct Qdisc *sch)
 {
-       return __qdisc_requeue(skb, sch, &sch->q);
+       struct sk_buff *skb = sch->gso_skb;
+
+       if (skb) {
+               sch->gso_skb = NULL;
+               sch->q.qlen--;
+       } else {
+               skb = sch->dequeue(sch);
+       }
+
+       return skb;
 }
 
 static inline void __qdisc_reset_queue(struct Qdisc *sch,
index ed71b110edf795094336e436816d9bdd5e6a1aab..23797506f593e87af3df9171ab75929513085278 100644 (file)
@@ -285,15 +285,15 @@ extern int sctp_debug_flag;
        if (sctp_debug_flag) { \
                if (saddr->sa.sa_family == AF_INET6) { \
                        printk(KERN_DEBUG \
-                              lead NIP6_FMT trail, \
+                              lead "%pI6" trail, \
                               leadparm, \
-                              NIP6(saddr->v6.sin6_addr), \
+                              &saddr->v6.sin6_addr, \
                               otherparms); \
                } else { \
                        printk(KERN_DEBUG \
-                              lead NIPQUAD_FMT trail, \
+                              lead "%pI4" trail, \
                               leadparm, \
-                              NIPQUAD(saddr->v4.sin_addr.s_addr), \
+                              &saddr->v4.sin_addr.s_addr, \
                               otherparms); \
                } \
        }
index 2f47107f6d0f8f018feaba3a75eeff4dd64d14ec..00cd486d362fc973b94a0e47de65d08187da3eca 100644 (file)
@@ -42,6 +42,7 @@
 
 #include <linux/kernel.h>
 #include <linux/list.h>
+#include <linux/list_nulls.h>
 #include <linux/timer.h>
 #include <linux/cache.h>
 #include <linux/module.h>
@@ -52,6 +53,7 @@
 #include <linux/security.h>
 
 #include <linux/filter.h>
+#include <linux/rculist_nulls.h>
 
 #include <asm/atomic.h>
 #include <net/dst.h>
@@ -106,6 +108,7 @@ struct net;
  *     @skc_reuse: %SO_REUSEADDR setting
  *     @skc_bound_dev_if: bound device index if != 0
  *     @skc_node: main hash linkage for various protocol lookup tables
+ *     @skc_nulls_node: main hash linkage for UDP/UDP-Lite protocol
  *     @skc_bind_node: bind hash linkage for various protocol lookup tables
  *     @skc_refcnt: reference count
  *     @skc_hash: hash value used with various protocol lookup tables
@@ -120,7 +123,10 @@ struct sock_common {
        volatile unsigned char  skc_state;
        unsigned char           skc_reuse;
        int                     skc_bound_dev_if;
-       struct hlist_node       skc_node;
+       union {
+               struct hlist_node       skc_node;
+               struct hlist_nulls_node skc_nulls_node;
+       };
        struct hlist_node       skc_bind_node;
        atomic_t                skc_refcnt;
        unsigned int            skc_hash;
@@ -206,6 +212,7 @@ struct sock {
 #define sk_reuse               __sk_common.skc_reuse
 #define sk_bound_dev_if                __sk_common.skc_bound_dev_if
 #define sk_node                        __sk_common.skc_node
+#define sk_nulls_node          __sk_common.skc_nulls_node
 #define sk_bind_node           __sk_common.skc_bind_node
 #define sk_refcnt              __sk_common.skc_refcnt
 #define sk_hash                        __sk_common.skc_hash
@@ -229,7 +236,9 @@ struct sock {
        } sk_backlog;
        wait_queue_head_t       *sk_sleep;
        struct dst_entry        *sk_dst_cache;
+#ifdef CONFIG_XFRM
        struct xfrm_policy      *sk_policy[2];
+#endif
        rwlock_t                sk_dst_lock;
        atomic_t                sk_rmem_alloc;
        atomic_t                sk_wmem_alloc;
@@ -237,7 +246,9 @@ struct sock {
        int                     sk_sndbuf;
        struct sk_buff_head     sk_receive_queue;
        struct sk_buff_head     sk_write_queue;
+#ifdef CONFIG_NET_DMA
        struct sk_buff_head     sk_async_wait_queue;
+#endif
        int                     sk_wmem_queued;
        int                     sk_forward_alloc;
        gfp_t                   sk_allocation;
@@ -269,7 +280,9 @@ struct sock {
        struct sk_buff          *sk_send_head;
        __u32                   sk_sndmsg_off;
        int                     sk_write_pending;
+#ifdef CONFIG_SECURITY
        void                    *sk_security;
+#endif
        __u32                   sk_mark;
        /* XXX 4 bytes hole on 64 bit */
        void                    (*sk_state_change)(struct sock *sk);
@@ -294,12 +307,30 @@ static inline struct sock *sk_head(const struct hlist_head *head)
        return hlist_empty(head) ? NULL : __sk_head(head);
 }
 
+static inline struct sock *__sk_nulls_head(const struct hlist_nulls_head *head)
+{
+       return hlist_nulls_entry(head->first, struct sock, sk_nulls_node);
+}
+
+static inline struct sock *sk_nulls_head(const struct hlist_nulls_head *head)
+{
+       return hlist_nulls_empty(head) ? NULL : __sk_nulls_head(head);
+}
+
 static inline struct sock *sk_next(const struct sock *sk)
 {
        return sk->sk_node.next ?
                hlist_entry(sk->sk_node.next, struct sock, sk_node) : NULL;
 }
 
+static inline struct sock *sk_nulls_next(const struct sock *sk)
+{
+       return (!is_a_nulls(sk->sk_nulls_node.next)) ?
+               hlist_nulls_entry(sk->sk_nulls_node.next,
+                                 struct sock, sk_nulls_node) :
+               NULL;
+}
+
 static inline int sk_unhashed(const struct sock *sk)
 {
        return hlist_unhashed(&sk->sk_node);
@@ -315,6 +346,11 @@ static __inline__ void sk_node_init(struct hlist_node *node)
        node->pprev = NULL;
 }
 
+static __inline__ void sk_nulls_node_init(struct hlist_nulls_node *node)
+{
+       node->pprev = NULL;
+}
+
 static __inline__ void __sk_del_node(struct sock *sk)
 {
        __hlist_del(&sk->sk_node);
@@ -361,6 +397,27 @@ static __inline__ int sk_del_node_init(struct sock *sk)
        return rc;
 }
 
+static __inline__ int __sk_nulls_del_node_init_rcu(struct sock *sk)
+{
+       if (sk_hashed(sk)) {
+               hlist_nulls_del_init_rcu(&sk->sk_nulls_node);
+               return 1;
+       }
+       return 0;
+}
+
+static __inline__ int sk_nulls_del_node_init_rcu(struct sock *sk)
+{
+       int rc = __sk_nulls_del_node_init_rcu(sk);
+
+       if (rc) {
+               /* paranoid for a while -acme */
+               WARN_ON(atomic_read(&sk->sk_refcnt) == 1);
+               __sock_put(sk);
+       }
+       return rc;
+}
+
 static __inline__ void __sk_add_node(struct sock *sk, struct hlist_head *list)
 {
        hlist_add_head(&sk->sk_node, list);
@@ -372,6 +429,17 @@ static __inline__ void sk_add_node(struct sock *sk, struct hlist_head *list)
        __sk_add_node(sk, list);
 }
 
+static __inline__ void __sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list)
+{
+       hlist_nulls_add_head_rcu(&sk->sk_nulls_node, list);
+}
+
+static __inline__ void sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list)
+{
+       sock_hold(sk);
+       __sk_nulls_add_node_rcu(sk, list);
+}
+
 static __inline__ void __sk_del_bind_node(struct sock *sk)
 {
        __hlist_del(&sk->sk_bind_node);
@@ -385,9 +453,16 @@ static __inline__ void sk_add_bind_node(struct sock *sk,
 
 #define sk_for_each(__sk, node, list) \
        hlist_for_each_entry(__sk, node, list, sk_node)
+#define sk_nulls_for_each(__sk, node, list) \
+       hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node)
+#define sk_nulls_for_each_rcu(__sk, node, list) \
+       hlist_nulls_for_each_entry_rcu(__sk, node, list, sk_nulls_node)
 #define sk_for_each_from(__sk, node) \
        if (__sk && ({ node = &(__sk)->sk_node; 1; })) \
                hlist_for_each_entry_from(__sk, node, sk_node)
+#define sk_nulls_for_each_from(__sk, node) \
+       if (__sk && ({ node = &(__sk)->sk_nulls_node; 1; })) \
+               hlist_nulls_for_each_entry_from(__sk, node, sk_nulls_node)
 #define sk_for_each_continue(__sk, node) \
        if (__sk && ({ node = &(__sk)->sk_node; 1; })) \
                hlist_for_each_entry_continue(__sk, node, sk_node)
@@ -587,8 +662,9 @@ struct proto {
        int                     *sysctl_rmem;
        int                     max_header;
 
-       struct kmem_cache               *slab;
+       struct kmem_cache       *slab;
        unsigned int            obj_size;
+       int                     slab_flags;
 
        atomic_t                *orphan_count;
 
@@ -597,7 +673,7 @@ struct proto {
 
        union {
                struct inet_hashinfo    *hashinfo;
-               struct hlist_head       *udp_hash;
+               struct udp_table        *udp_table;
                struct raw_hashinfo     *raw_hash;
        } h;
 
index 438014d57610d3c22355746e7f73e73ec73a3785..8f26b28fb407cb2b4149f0ea425db5d0fb6116c6 100644 (file)
@@ -590,7 +590,6 @@ struct tcp_skb_cb {
 #define TCPCB_EVER_RETRANS     0x80    /* Ever retransmitted frame     */
 #define TCPCB_RETRANS          (TCPCB_SACKED_RETRANS|TCPCB_EVER_RETRANS)
 
-       __u16           urg_ptr;        /* Valid w/URG flags is set.    */
        __u32           ack_seq;        /* Sequence number ACK'd        */
 };
 
index 1e205095ea687aee5f76913a1d03d47c1121e948..90e6ce56be6576826ef51f9c85d4ae0d91791dbb 100644 (file)
@@ -50,8 +50,15 @@ struct udp_skb_cb {
 };
 #define UDP_SKB_CB(__skb)      ((struct udp_skb_cb *)((__skb)->cb))
 
-extern struct hlist_head udp_hash[UDP_HTABLE_SIZE];
-extern rwlock_t udp_hash_lock;
+struct udp_hslot {
+       struct hlist_nulls_head head;
+       spinlock_t              lock;
+} __attribute__((aligned(2 * sizeof(long))));
+struct udp_table {
+       struct udp_hslot        hash[UDP_HTABLE_SIZE];
+};
+extern struct udp_table udp_table;
+extern void udp_table_init(struct udp_table *);
 
 
 /* Note: this must match 'valbool' in sock_setsockopt */
@@ -110,15 +117,7 @@ static inline void udp_lib_hash(struct sock *sk)
        BUG();
 }
 
-static inline void udp_lib_unhash(struct sock *sk)
-{
-       write_lock_bh(&udp_hash_lock);
-       if (sk_del_node_init(sk)) {
-               inet_sk(sk)->num = 0;
-               sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
-       }
-       write_unlock_bh(&udp_hash_lock);
-}
+extern void udp_lib_unhash(struct sock *sk);
 
 static inline void udp_lib_close(struct sock *sk, long timeout)
 {
@@ -187,7 +186,7 @@ extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
 struct udp_seq_afinfo {
        char                    *name;
        sa_family_t             family;
-       struct hlist_head       *hashtable;
+       struct udp_table        *udp_table;
        struct file_operations  seq_fops;
        struct seq_operations   seq_ops;
 };
@@ -196,7 +195,7 @@ struct udp_iter_state {
        struct seq_net_private  p;
        sa_family_t             family;
        int                     bucket;
-       struct hlist_head       *hashtable;
+       struct udp_table        *udp_table;
 };
 
 #ifdef CONFIG_PROC_FS
index b76b2e377af4540bc8336328f55485d87a26947b..afdffe607b2425fd66a2a1c8ae30b3bca1eb1494 100644 (file)
@@ -11,7 +11,7 @@
 #define UDPLITE_RECV_CSCOV   11 /* receiver partial coverage (threshold ) */
 
 extern struct proto            udplite_prot;
-extern struct hlist_head       udplite_hash[UDP_HTABLE_SIZE];
+extern struct udp_table                udplite_table;
 
 /*
  *     Checksum computation is all in software, hence simpler getfrag.
index 721efb363db73cd0bb06270e5c1463a6e7ffe930..412351560b764453570062387e835ad61a95cf29 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/netdevice.h>
 #include <linux/debugfs.h>
 #include <linux/list.h>
+#include <linux/ieee80211.h>
 #include <net/cfg80211.h>
 
 /**
@@ -133,23 +134,23 @@ struct ieee80211_rate {
 };
 
 /**
- * struct ieee80211_ht_info - describing STA's HT capabilities
+ * struct ieee80211_sta_ht_cap - STA's HT capabilities
  *
  * This structure describes most essential parameters needed
  * to describe 802.11n HT capabilities for an STA.
  *
- * @ht_supported: is HT supported by STA, 0: no, 1: yes
+ * @ht_supported: is HT supported by the STA
  * @cap: HT capabilities map as described in 802.11n spec
  * @ampdu_factor: Maximum A-MPDU length factor
  * @ampdu_density: Minimum A-MPDU spacing
- * @supp_mcs_set: Supported MCS set as described in 802.11n spec
+ * @mcs: Supported MCS rates
  */
-struct ieee80211_ht_info {
+struct ieee80211_sta_ht_cap {
        u16 cap; /* use IEEE80211_HT_CAP_ */
-       u8 ht_supported;
+       bool ht_supported;
        u8 ampdu_factor;
        u8 ampdu_density;
-       u8 supp_mcs_set[16];
+       struct ieee80211_mcs_info mcs;
 };
 
 /**
@@ -173,7 +174,7 @@ struct ieee80211_supported_band {
        enum ieee80211_band band;
        int n_channels;
        int n_bitrates;
-       struct ieee80211_ht_info ht_info;
+       struct ieee80211_sta_ht_cap ht_cap;
 };
 
 /**
@@ -262,9 +263,9 @@ static inline struct device *wiphy_dev(struct wiphy *wiphy)
 /**
  * wiphy_name - get wiphy name
  */
-static inline char *wiphy_name(struct wiphy *wiphy)
+static inline const char *wiphy_name(struct wiphy *wiphy)
 {
-       return wiphy->dev.bus_id;
+       return dev_name(&wiphy->dev);
 }
 
 /**
@@ -340,55 +341,36 @@ ieee80211_get_channel(struct wiphy *wiphy, int 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
- *     own &struct wiphy
- * @alpha2: the ISO/IEC 3166 alpha2 being claimed the regulatory domain
- *     should be in. If @rd is set this should be NULL
- * @rd: a complete regulatory domain, if passed the caller need not worry
- *     about freeing it
+ * ieee80211_get_response_rate - get basic rate for a given rate
  *
- * The Wireless subsystem can use this function to hint to the wireless core
- * what it believes should be the current regulatory domain by
- * giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory
- * domain should be in or by providing a completely build regulatory domain.
- *
- * Returns -EALREADY if *a regulatory domain* has already been set. Note that
- * this could be by another driver. It is safe for drivers to continue if
- * -EALREADY is returned, if drivers are not capable of world roaming they
- * should not register more channels than they support. Right now we only
- * support listening to the first driver hint. If the driver is capable
- * of world roaming but wants to respect its own EEPROM mappings for
- * specific regulatory domains it should register the @reg_notifier callback
- * on the &struct wiphy. Returns 0 if the hint went through fine or through an
- * intersection operation. Otherwise a standard error code is returned.
+ * @sband: the band to look for rates in
+ * @basic_rates: bitmap of basic rates
+ * @bitrate: the bitrate for which to find the basic rate
  *
+ * This function returns the basic rate corresponding to a given
+ * bitrate, that is the next lower bitrate contained in the basic
+ * rate map, which is, for this function, given as a bitmap of
+ * indices of rates in the band's bitrate table.
  */
-extern int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
-               const char *alpha2, struct ieee80211_regdomain *rd);
+struct ieee80211_rate *
+ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
+                           u64 basic_rates, int bitrate);
+
 /**
  * regulatory_hint - driver hint to the wireless core a regulatory domain
- * @wiphy: the driver's very own &struct wiphy
+ * @wiphy: the wireless device giving the hint (used only for reporting
+ *     conflicts)
  * @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain
  *     should be in. If @rd is set this should be NULL. Note that if you
  *     set this to NULL you should still set rd->alpha2 to some accepted
  *     alpha2.
- * @rd: a complete regulatory domain provided by the driver. If passed
- *     the driver does not need to worry about freeing it.
  *
  * Wireless drivers can use this function to hint to the wireless core
  * what it believes should be the current regulatory domain by
  * giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory
  * domain should be in or by providing a completely build regulatory domain.
  * If the driver provides an ISO/IEC 3166 alpha2 userspace will be queried
- * for a regulatory domain structure for the respective country. If
- * a regulatory domain is build and passed you should set the alpha2
- * if possible, otherwise set it to the special value of "99" which tells
- * the wireless core it is unknown. If you pass a built regulatory domain
- * and we return non zero you are in charge of kfree()'ing the structure.
- *
- * See __regulatory_hint() documentation for possible return values.
+ * for a regulatory domain structure for the respective country.
  */
-extern int regulatory_hint(struct wiphy *wiphy,
-               const char *alpha2, struct ieee80211_regdomain *rd);
+extern void regulatory_hint(struct wiphy *wiphy, const char *alpha2);
 #endif /* __NET_WIRELESS_H */
index 11c890ad8ebb83fad2aebbebbcd49a2c00a1b261..45e11b3631e4228b6fec6ebf761e4b5a23259700 100644 (file)
@@ -467,7 +467,6 @@ struct xfrm_policy_walk {
 
 struct xfrm_policy
 {
-       struct xfrm_policy      *next;
        struct hlist_node       bydst;
        struct hlist_node       byidx;
 
@@ -882,6 +881,7 @@ struct xfrm_dst
        u32 path_cookie;
 };
 
+#ifdef CONFIG_XFRM
 static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
 {
        dst_release(xdst->route);
@@ -894,6 +894,7 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
        xdst->partner = NULL;
 #endif
 }
+#endif
 
 extern void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
 
@@ -1536,9 +1537,11 @@ static inline void xfrm_states_delete(struct xfrm_state **states, int n)
 }
 #endif
 
+#ifdef CONFIG_XFRM
 static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
 {
        return skb->sp->xvec[skb->sp->len - 1];
 }
+#endif
 
 #endif /* _NET_XFRM_H */
index a013bbc237178c1bc86c522b0e3ee4a66f47a2c9..6897724ff5df0731e717305afaaca37112ec5897 100644 (file)
@@ -581,6 +581,62 @@ static char *resource_string(char *buf, char *end, struct resource *res, int fie
        return string(buf, end, sym, field_width, precision, flags);
 }
 
+static char *mac_address_string(char *buf, char *end, u8 *addr, int field_width,
+                               int precision, int flags)
+{
+       char mac_addr[6 * 3]; /* (6 * 2 hex digits), 5 colons and trailing zero */
+       char *p = mac_addr;
+       int i;
+
+       for (i = 0; i < 6; i++) {
+               p = pack_hex_byte(p, addr[i]);
+               if (!(flags & SPECIAL) && i != 5)
+                       *p++ = ':';
+       }
+       *p = '\0';
+
+       return string(buf, end, mac_addr, field_width, precision, flags & ~SPECIAL);
+}
+
+static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width,
+                        int precision, int flags)
+{
+       char ip6_addr[8 * 5]; /* (8 * 4 hex digits), 7 colons and trailing zero */
+       char *p = ip6_addr;
+       int i;
+
+       for (i = 0; i < 8; i++) {
+               p = pack_hex_byte(p, addr[2 * i]);
+               p = pack_hex_byte(p, addr[2 * i + 1]);
+               if (!(flags & SPECIAL) && i != 7)
+                       *p++ = ':';
+       }
+       *p = '\0';
+
+       return string(buf, end, ip6_addr, field_width, precision, flags & ~SPECIAL);
+}
+
+static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width,
+                        int precision, int flags)
+{
+       char ip4_addr[4 * 4]; /* (4 * 3 decimal digits), 3 dots and trailing zero */
+       char temp[3];   /* hold each IP quad in reverse order */
+       char *p = ip4_addr;
+       int i, digits;
+
+       for (i = 0; i < 4; i++) {
+               digits = put_dec_trunc(temp, addr[i]) - temp;
+               /* reverse the digits in the quad */
+               while (digits--)
+                       *p++ = temp[digits];
+               if (i != 3)
+                       *p++ = '.';
+       }
+       *p = '\0';
+
+       return string(buf, end, ip4_addr, field_width, precision, flags & ~SPECIAL);
+}
+
 /*
  * Show a '%p' thing.  A kernel extension is that the '%p' is followed
  * by an extra set of alphanumeric characters that are extended format
@@ -592,6 +648,12 @@ static char *resource_string(char *buf, char *end, struct resource *res, int fie
  * - 'S' For symbolic direct pointers
  * - 'R' For a struct resource pointer, it prints the range of
  *       addresses (not the name nor the flags)
+ * - 'M' For a 6-byte MAC address, it prints the address in the
+ *       usual colon-separated hex notation
+ * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way (dot-separated
+ *       decimal for v4 and colon separated network-order 16 bit hex for v6)
+ * - 'i' [46] for 'raw' IPv4/IPv6 addresses, IPv6 omits the colons, IPv4 is
+ *       currently the same
  *
  * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
  * function pointers are really function descriptors, which contain a
@@ -607,6 +669,18 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field
                return symbol_string(buf, end, ptr, field_width, precision, flags);
        case 'R':
                return resource_string(buf, end, ptr, field_width, precision, flags);
+       case 'M':
+               return mac_address_string(buf, end, ptr, field_width, precision, flags);
+       case 'i':
+               flags |= SPECIAL;
+               /* Fallthrough */
+       case 'I':
+               if (fmt[1] == '6')
+                       return ip6_addr_string(buf, end, ptr, field_width, precision, flags);
+               if (fmt[1] == '4')
+                       return ip4_addr_string(buf, end, ptr, field_width, precision, flags);
+               flags &= ~SPECIAL;
+               break;
        }
        flags |= SMALL;
        if (field_width == -1) {
index 18c66475d8c39f8cd9c28a4d5ea0a0b5bc84491e..158150fee462fdbca4a2fa2175532b71dd2f862d 100644 (file)
@@ -285,10 +285,7 @@ void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,
                if(entry)
                {
 #if TR_SR_DEBUG
-{
-DECLARE_MAC_BUF(mac);
-printk("source routing for %s\n",print_mac(mac, trh->daddr));
-}
+printk("source routing for %pM\n", trh->daddr);
 #endif
                        if(!entry->local_ring && (ntohs(entry->rcf) & TR_RCF_LEN_MASK) >> 8)
                        {
@@ -370,9 +367,8 @@ static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev)
        if(entry==NULL)
        {
 #if TR_SR_DEBUG
-               DECLARE_MAC_BUF(mac);
-               printk("adding rif_entry: addr:%s rcf:%04X\n",
-                      print_mac(mac, trh->saddr), ntohs(trh->rcf));
+               printk("adding rif_entry: addr:%pM rcf:%04X\n",
+                      trh->saddr, ntohs(trh->rcf));
 #endif
                /*
                 *      Allocate our new entry. A failure to allocate loses
@@ -417,11 +413,8 @@ static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev)
                         !(trh->rcf & htons(TR_RCF_BROADCAST_MASK)))
                    {
 #if TR_SR_DEBUG
-{
-DECLARE_MAC_BUF(mac);
-printk("updating rif_entry: addr:%s rcf:%04X\n",
-               print_mac(mac, trh->saddr), ntohs(trh->rcf));
-}
+printk("updating rif_entry: addr:%pM rcf:%04X\n",
+               trh->saddr, ntohs(trh->rcf));
 #endif
                            entry->rcf = trh->rcf & htons((unsigned short)~TR_RCF_BROADCAST_MASK);
                            memcpy(&(entry->rseg[0]),&(trh->rseg[0]),8*sizeof(unsigned short));
@@ -532,7 +525,6 @@ static int rif_seq_show(struct seq_file *seq, void *v)
 {
        int j, rcf_len, segment, brdgnmb;
        struct rif_cache *entry = v;
-       DECLARE_MAC_BUF(mac);
 
        if (v == SEQ_START_TOKEN)
                seq_puts(seq,
@@ -542,9 +534,9 @@ static int rif_seq_show(struct seq_file *seq, void *v)
                long ttl = (long) (entry->last_used + sysctl_tr_rif_timeout)
                                - (long) jiffies;
 
-               seq_printf(seq, "%s %s %7li ",
+               seq_printf(seq, "%s %pM %7li ",
                           dev?dev->name:"?",
-                          print_mac(mac, entry->addr),
+                          entry->addr,
                           ttl/HZ);
 
                        if (entry->local_ring)
@@ -643,7 +635,7 @@ static struct ctl_table tr_table[] = {
                .data           = &sysctl_tr_rif_timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        { 0 },
 };
index f0e335aa20df43370d947ebbee52a23013491ae3..72326b9c759c7cfbdacc5d27ac7adcbe1a00a9fc 100644 (file)
@@ -46,10 +46,10 @@ int vlan_net_id;
 /* Our listing of VLAN group(s) */
 static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE];
 
-static char vlan_fullname[] = "802.1Q VLAN Support";
-static char vlan_version[] = DRV_VERSION;
-static char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>";
-static char vlan_buggyright[] = "David S. Miller <davem@redhat.com>";
+const char vlan_fullname[] = "802.1Q VLAN Support";
+const char vlan_version[] = DRV_VERSION;
+static const char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>";
+static const char vlan_buggyright[] = "David S. Miller <davem@redhat.com>";
 
 static struct packet_type vlan_packet_type = {
        .type = __constant_htons(ETH_P_8021Q),
index a6603a4d917f850f9aead87eecaf6ce99cfc4803..82570bc2a18034058dfba13d0ab9765f63ae3d32 100644 (file)
@@ -108,8 +108,10 @@ static inline int vlan_gvrp_init(void) { return 0; }
 static inline void vlan_gvrp_uninit(void) {}
 #endif
 
-int vlan_netlink_init(void);
-void vlan_netlink_fini(void);
+extern const char vlan_fullname[];
+extern const char vlan_version[];
+extern int vlan_netlink_init(void);
+extern void vlan_netlink_fini(void);
 
 extern struct rtnl_link_ops vlan_link_ops;
 
index 68ced4bf158c7558977e3c4a44ef4567157e80d5..dd86a1dc4cd00f597ceb58cccefe2625bb1541fa 100644 (file)
@@ -47,8 +47,6 @@ int vlan_hwaccel_do_receive(struct sk_buff *skb)
        skb->priority = vlan_get_ingress_priority(dev, skb->vlan_tci);
        skb->vlan_tci = 0;
 
-       dev->last_rx = jiffies;
-
        stats = &dev->stats;
        stats->rx_packets++;
        stats->rx_bytes += skb->len;
index 8883e9c8a2230ccb993cd4bcc86131e6babbaece..e4bf39f87032af3eea40659a1075b74e4017585f 100644 (file)
@@ -163,8 +163,6 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
                goto err_unlock;
        }
 
-       skb->dev->last_rx = jiffies;
-
        stats = &skb->dev->stats;
        stats->rx_packets++;
        stats->rx_bytes += skb->len;
@@ -648,6 +646,26 @@ static void vlan_dev_uninit(struct net_device *dev)
        }
 }
 
+static int vlan_ethtool_get_settings(struct net_device *dev,
+                                    struct ethtool_cmd *cmd)
+{
+       const struct vlan_dev_info *vlan = vlan_dev_info(dev);
+       struct net_device *real_dev = vlan->real_dev;
+
+       if (!real_dev->ethtool_ops->get_settings)
+               return -EOPNOTSUPP;
+
+       return real_dev->ethtool_ops->get_settings(real_dev, cmd);
+}
+
+static void vlan_ethtool_get_drvinfo(struct net_device *dev,
+                                    struct ethtool_drvinfo *info)
+{
+       strcpy(info->driver, vlan_fullname);
+       strcpy(info->version, vlan_version);
+       strcpy(info->fw_version, "N/A");
+}
+
 static u32 vlan_ethtool_get_rx_csum(struct net_device *dev)
 {
        const struct vlan_dev_info *vlan = vlan_dev_info(dev);
@@ -672,6 +690,8 @@ static u32 vlan_ethtool_get_flags(struct net_device *dev)
 }
 
 static const struct ethtool_ops vlan_ethtool_ops = {
+       .get_settings           = vlan_ethtool_get_settings,
+       .get_drvinfo            = vlan_ethtool_get_drvinfo,
        .get_link               = ethtool_op_get_link,
        .get_rx_csum            = vlan_ethtool_get_rx_csum,
        .get_flags              = vlan_ethtool_get_flags,
index d789d79551ae4207d37e0b386a3db743dde05611..8c3d97ca0d96527f7c0375b5fb3c2ecac56ab3ae 100644 (file)
@@ -27,7 +27,7 @@ menu "Networking options"
 config NET_NS
        bool "Network namespace support"
        default n
-       depends on EXPERIMENTAL && !SYSFS && NAMESPACES
+       depends on EXPERIMENTAL && NAMESPACES
        help
          Allow user space to create what appear to be multiple instances
          of the network stack.
index b25c1e909d14fdabadf150693dd80252345f4f26..b03ff58e9308666f1dc0dec54c8aabde99b0e263 100644 (file)
@@ -995,7 +995,6 @@ static int aarp_seq_show(struct seq_file *seq, void *v)
        struct aarp_iter_state *iter = seq->private;
        struct aarp_entry *entry = v;
        unsigned long now = jiffies;
-       DECLARE_MAC_BUF(mac);
 
        if (v == SEQ_START_TOKEN)
                seq_puts(seq,
@@ -1006,7 +1005,7 @@ static int aarp_seq_show(struct seq_file *seq, void *v)
                           ntohs(entry->target_addr.s_net),
                           (unsigned int) entry->target_addr.s_node,
                           entry->dev ? entry->dev->name : "????");
-               seq_printf(seq, "%s", print_mac(mac, entry->hwaddr));
+               seq_printf(seq, "%pM", entry->hwaddr);
                seq_printf(seq, " %8s",
                           dt2str((long)entry->expires_at - (long)now));
                if (iter->table == unresolved)
index d3134e7e6ee8e3a6960806259ce4266fabdb6a82..c3f0027173789c56ef5af3ef9a98536449e0b7e1 100644 (file)
@@ -1284,7 +1284,7 @@ static int handle_ip_over_ddp(struct sk_buff *skb)
        skb->dev   = dev;
        skb_reset_transport_header(skb);
 
-       stats = dev->priv;
+       stats = netdev_priv(dev);
        stats->rx_packets++;
        stats->rx_bytes += skb->len + 13;
        netif_rx(skb);  /* Send the SKB up to a higher place. */
index 621805dfa2f4a4f84c9c0264dfc027935f2a85ac..8d237b15183b8acdf8a71fba259dc0c58fceb4cf 100644 (file)
@@ -17,8 +17,8 @@ static struct ctl_table atalk_table[] = {
                .data           = &sysctl_aarp_expiry_time,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies,
        },
        {
                .ctl_name       = NET_ATALK_AARP_TICK_TIME,
@@ -26,8 +26,8 @@ static struct ctl_table atalk_table[] = {
                .data           = &sysctl_aarp_tick_time,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies,
        },
        {
                .ctl_name       = NET_ATALK_AARP_RETRANSMIT_LIMIT,
@@ -35,7 +35,7 @@ static struct ctl_table atalk_table[] = {
                .data           = &sysctl_aarp_retransmit_limit,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_ATALK_AARP_RESOLVE_TIME,
@@ -43,8 +43,8 @@ static struct ctl_table atalk_table[] = {
                .data           = &sysctl_aarp_resolve_time,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies,
        },
        { 0 },
 };
index 1b88311f2130b57598bc13ee82dc74bab3cc3fc2..b5674dc2083d6766bbe4754d3951439fde141c0c 100644 (file)
@@ -149,7 +149,7 @@ int atm_register_sysfs(struct atm_dev *adev)
        cdev->class = &atm_class;
        dev_set_drvdata(cdev, adev);
 
-       snprintf(cdev->bus_id, BUS_ID_SIZE, "%s%d", adev->type, adev->number);
+       dev_set_name(cdev, "%s%d", adev->type, adev->number);
        err = device_register(cdev);
        if (err < 0)
                return err;
index 280de481edc7e0dd64f03112bfcb90105074f38e..ea9438fc6855fb3a569e7e25a2064d5191a14989 100644 (file)
@@ -101,7 +101,7 @@ static LIST_HEAD(br2684_devs);
 
 static inline struct br2684_dev *BRPRIV(const struct net_device *net_dev)
 {
-       return (struct br2684_dev *)net_dev->priv;
+       return (struct br2684_dev *)netdev_priv(net_dev);
 }
 
 static inline struct net_device *list_entry_brdev(const struct list_head *le)
@@ -698,12 +698,11 @@ static int br2684_seq_show(struct seq_file *seq, void *v)
                                                    br2684_devs);
        const struct net_device *net_dev = brdev->net_dev;
        const struct br2684_vcc *brvcc;
-       DECLARE_MAC_BUF(mac);
 
-       seq_printf(seq, "dev %.16s: num=%d, mac=%s (%s)\n",
+       seq_printf(seq, "dev %.16s: num=%d, mac=%pM (%s)\n",
                   net_dev->name,
                   brdev->number,
-                  print_mac(mac, net_dev->dev_addr),
+                  net_dev->dev_addr,
                   brdev->mac_was_set ? "set" : "auto");
 
        list_for_each_entry(brvcc, &brdev->brvccs, brvccs) {
index 5b5b96344ce60fba334fb291a8fe21393aa8bb26..2d33a83be799c36dec054340553610d64e61070c 100644 (file)
@@ -822,8 +822,8 @@ static void atmarp_info(struct seq_file *seq, struct net_device *dev,
        seq_printf(seq, "%-6s%-4s%-4s%5ld ",
                   dev->name, svc ? "SVC" : "PVC", llc ? "LLC" : "NULL", exp);
 
-       off = scnprintf(buf, sizeof(buf) - 1, "%d.%d.%d.%d",
-                       NIPQUAD(entry->ip));
+       off = scnprintf(buf, sizeof(buf) - 1, "%pI4",
+                       &entry->ip);
        while (off < 16)
                buf[off++] = ' ';
        buf[off] = '\0';
index 8f701cde5945b0f8ee7d9c6d6a3412130ce840a8..e5e301550e8a72ce7897fce6729bd2a82f844ea0 100644 (file)
@@ -152,7 +152,7 @@ static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev)
                buff += 4;
                mesg->content.normal.flag = *buff & 0x01;       /* 0x01 is topology change */
 
-               priv = (struct lec_priv *)dev->priv;
+               priv = netdev_priv(dev);
                atm_force_charge(priv->lecd, skb2->truesize);
                sk = sk_atm(priv->lecd);
                skb_queue_tail(&sk->sk_receive_queue, skb2);
@@ -218,7 +218,7 @@ static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc)
 
 static int lec_open(struct net_device *dev)
 {
-       struct lec_priv *priv = (struct lec_priv *)dev->priv;
+       struct lec_priv *priv = netdev_priv(dev);
 
        netif_start_queue(dev);
        memset(&priv->stats, 0, sizeof(struct net_device_stats));
@@ -252,7 +252,7 @@ static void lec_tx_timeout(struct net_device *dev)
 static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct sk_buff *skb2;
-       struct lec_priv *priv = (struct lec_priv *)dev->priv;
+       struct lec_priv *priv = netdev_priv(dev);
        struct lecdatahdr_8023 *lec_h;
        struct atm_vcc *vcc;
        struct lec_arp_table *entry;
@@ -373,19 +373,13 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
                if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) {
                        pr_debug("%s:lec_start_xmit: queuing packet, ",
                                dev->name);
-                       pr_debug("MAC address " MAC_FMT "\n",
-                                lec_h->h_dest[0], lec_h->h_dest[1],
-                                lec_h->h_dest[2], lec_h->h_dest[3],
-                                lec_h->h_dest[4], lec_h->h_dest[5]);
+                       pr_debug("MAC address %pM\n", lec_h->h_dest);
                        skb_queue_tail(&entry->tx_wait, skb);
                } else {
                        pr_debug
                            ("%s:lec_start_xmit: tx queue full or no arp entry, dropping, ",
                             dev->name);
-                       pr_debug("MAC address " MAC_FMT "\n",
-                                lec_h->h_dest[0], lec_h->h_dest[1],
-                                lec_h->h_dest[2], lec_h->h_dest[3],
-                                lec_h->h_dest[4], lec_h->h_dest[5]);
+                       pr_debug("MAC address %pM\n", lec_h->h_dest);
                        priv->stats.tx_dropped++;
                        dev_kfree_skb(skb);
                }
@@ -397,10 +391,7 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) {
                pr_debug("lec.c: emptying tx queue, ");
-               pr_debug("MAC address " MAC_FMT "\n",
-                        lec_h->h_dest[0], lec_h->h_dest[1],
-                        lec_h->h_dest[2], lec_h->h_dest[3],
-                        lec_h->h_dest[4], lec_h->h_dest[5]);
+               pr_debug("MAC address %pM\n", lec_h->h_dest);
                lec_send(vcc, skb2, priv);
        }
 
@@ -442,14 +433,14 @@ static int lec_close(struct net_device *dev)
  */
 static struct net_device_stats *lec_get_stats(struct net_device *dev)
 {
-       return &((struct lec_priv *)dev->priv)->stats;
+       return &((struct lec_priv *)netdev_priv(dev))->stats;
 }
 
 static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
 {
        unsigned long flags;
        struct net_device *dev = (struct net_device *)vcc->proto_data;
-       struct lec_priv *priv = (struct lec_priv *)dev->priv;
+       struct lec_priv *priv = netdev_priv(dev);
        struct atmlec_msg *mesg;
        struct lec_arp_table *entry;
        int i;
@@ -539,15 +530,8 @@ static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
                {
                        struct net_bridge_fdb_entry *f;
 
-                       pr_debug
-                           ("%s: bridge zeppelin asks about " MAC_FMT "\n",
-                            dev->name,
-                            mesg->content.proxy.mac_addr[0],
-                            mesg->content.proxy.mac_addr[1],
-                            mesg->content.proxy.mac_addr[2],
-                            mesg->content.proxy.mac_addr[3],
-                            mesg->content.proxy.mac_addr[4],
-                            mesg->content.proxy.mac_addr[5]);
+                       pr_debug("%s: bridge zeppelin asks about %pM\n",
+                                dev->name, mesg->content.proxy.mac_addr);
 
                        if (br_fdb_get_hook == NULL || dev->br_port == NULL)
                                break;
@@ -596,7 +580,7 @@ static void lec_atm_close(struct atm_vcc *vcc)
 {
        struct sk_buff *skb;
        struct net_device *dev = (struct net_device *)vcc->proto_data;
-       struct lec_priv *priv = (struct lec_priv *)dev->priv;
+       struct lec_priv *priv = netdev_priv(dev);
 
        priv->lecd = NULL;
        /* Do something needful? */
@@ -727,7 +711,7 @@ static void lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
 {
        unsigned long flags;
        struct net_device *dev = (struct net_device *)vcc->proto_data;
-       struct lec_priv *priv = (struct lec_priv *)dev->priv;
+       struct lec_priv *priv = netdev_priv(dev);
 
 #if DUMP_PACKETS >0
        int i = 0;
@@ -874,7 +858,7 @@ static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg)
        vpriv->old_pop = vcc->pop;
        vcc->user_back = vpriv;
        vcc->pop = lec_pop;
-       lec_vcc_added(dev_lec[ioc_data.dev_num]->priv,
+       lec_vcc_added(netdev_priv(dev_lec[ioc_data.dev_num]),
                      &ioc_data, vcc, vcc->push);
        vcc->proto_data = dev_lec[ioc_data.dev_num];
        vcc->push = lec_push;
@@ -886,7 +870,8 @@ static int lec_mcast_attach(struct atm_vcc *vcc, int arg)
        if (arg < 0 || arg >= MAX_LEC_ITF || !dev_lec[arg])
                return -EINVAL;
        vcc->proto_data = dev_lec[arg];
-       return (lec_mcast_make((struct lec_priv *)dev_lec[arg]->priv, vcc));
+       return lec_mcast_make((struct lec_priv *)netdev_priv(dev_lec[arg]),
+                               vcc);
 }
 
 /* Initialize device. */
@@ -928,11 +913,11 @@ static int lecd_attach(struct atm_vcc *vcc, int arg)
                        return -EINVAL;
                }
 
-               priv = dev_lec[i]->priv;
+               priv = netdev_priv(dev_lec[i]);
                priv->is_trdev = is_trdev;
                lec_init(dev_lec[i]);
        } else {
-               priv = dev_lec[i]->priv;
+               priv = netdev_priv(dev_lec[i]);
                if (priv->lecd)
                        return -EADDRINUSE;
        }
@@ -1093,7 +1078,8 @@ static void *lec_itf_walk(struct lec_state *state, loff_t *l)
        void *v;
 
        dev = state->dev ? state->dev : dev_lec[state->itf];
-       v = (dev && dev->priv) ? lec_priv_walk(state, l, dev->priv) : NULL;
+       v = (dev && netdev_priv(dev)) ?
+               lec_priv_walk(state, l, netdev_priv(dev)) : NULL;
        if (!v && dev) {
                dev_put(dev);
                /* Partial state reset for the next time we get called */
@@ -1255,7 +1241,7 @@ static void __exit lane_module_cleanup(void)
 
        for (i = 0; i < MAX_LEC_ITF; i++) {
                if (dev_lec[i] != NULL) {
-                       priv = (struct lec_priv *)dev_lec[i]->priv;
+                       priv = netdev_priv(dev_lec[i]);
                        unregister_netdev(dev_lec[i]);
                        free_netdev(dev_lec[i]);
                        dev_lec[i] = NULL;
@@ -1279,7 +1265,7 @@ static int lane2_resolve(struct net_device *dev, const u8 *dst_mac, int force,
                         u8 **tlvs, u32 *sizeoftlvs)
 {
        unsigned long flags;
-       struct lec_priv *priv = (struct lec_priv *)dev->priv;
+       struct lec_priv *priv = netdev_priv(dev);
        struct lec_arp_table *table;
        struct sk_buff *skb;
        int retval;
@@ -1326,7 +1312,7 @@ static int lane2_associate_req(struct net_device *dev, const u8 *lan_dst,
 {
        int retval;
        struct sk_buff *skb;
-       struct lec_priv *priv = (struct lec_priv *)dev->priv;
+       struct lec_priv *priv = netdev_priv(dev);
 
        if (compare_ether_addr(lan_dst, dev->dev_addr))
                return (0);     /* not our mac address */
@@ -1363,7 +1349,7 @@ static void lane2_associate_ind(struct net_device *dev, const u8 *mac_addr,
 #if 0
        int i = 0;
 #endif
-       struct lec_priv *priv = (struct lec_priv *)dev->priv;
+       struct lec_priv *priv = netdev_priv(dev);
 #if 0                          /*
                                 * Why have the TLVs in LE_ARP entries
                                 * since we do not use them? When you
index 11b16d16661c18e458c9d624b8fcc4cfe4f4a67b..12e9ea371db1818e604516f8920f0b81d24c4f39 100644 (file)
@@ -232,8 +232,8 @@ void atm_mpoa_disp_qos(struct seq_file *m)
        seq_printf(m, "IP address\n  TX:max_pcr pcr     min_pcr max_cdv max_sdu\n  RX:max_pcr pcr     min_pcr max_cdv max_sdu\n");
 
        while (qos != NULL) {
-               seq_printf(m, "%u.%u.%u.%u\n     %-7d %-7d %-7d %-7d %-7d\n     %-7d %-7d %-7d %-7d %-7d\n",
-                               NIPQUAD(qos->ipaddr),
+               seq_printf(m, "%pI4\n     %-7d %-7d %-7d %-7d %-7d\n     %-7d %-7d %-7d %-7d %-7d\n",
+                               &qos->ipaddr,
                                qos->qos.txtp.max_pcr, qos->qos.txtp.pcr, qos->qos.txtp.min_pcr, qos->qos.txtp.max_cdv, qos->qos.txtp.max_sdu,
                                qos->qos.rxtp.max_pcr, qos->qos.rxtp.pcr, qos->qos.rxtp.min_pcr, qos->qos.rxtp.max_cdv, qos->qos.rxtp.max_sdu);
                qos = qos->next;
@@ -595,8 +595,8 @@ static int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg)
                        if (in_entry != NULL) mpc->in_ops->put(in_entry);
                        return -EINVAL;
                }
-               printk("mpoa: (%s) mpc_vcc_attach: attaching ingress SVC, entry = %u.%u.%u.%u\n",
-                      mpc->dev->name, NIPQUAD(in_entry->ctrl_info.in_dst_ip));
+               printk("mpoa: (%s) mpc_vcc_attach: attaching ingress SVC, entry = %pI4\n",
+                      mpc->dev->name, &in_entry->ctrl_info.in_dst_ip);
                in_entry->shortcut = vcc;
                mpc->in_ops->put(in_entry);
        } else {
@@ -627,8 +627,8 @@ static void mpc_vcc_close(struct atm_vcc *vcc, struct net_device *dev)
        dprintk("mpoa: (%s) mpc_vcc_close:\n", dev->name);
        in_entry = mpc->in_ops->get_by_vcc(vcc, mpc);
        if (in_entry) {
-               dprintk("mpoa: (%s) mpc_vcc_close: ingress SVC closed ip = %u.%u.%u.%u\n",
-                      mpc->dev->name, NIPQUAD(in_entry->ctrl_info.in_dst_ip));
+               dprintk("mpoa: (%s) mpc_vcc_close: ingress SVC closed ip = %pI4\n",
+                      mpc->dev->name, &in_entry->ctrl_info.in_dst_ip);
                in_entry->shortcut = NULL;
                mpc->in_ops->put(in_entry);
        }
@@ -785,7 +785,7 @@ static int atm_mpoa_mpoad_attach (struct atm_vcc *vcc, int arg)
        }
 
        if (mpc->dev) { /* check if the lec is LANE2 capable */
-               priv = (struct lec_priv *)mpc->dev->priv;
+               priv = netdev_priv(mpc->dev);
                if (priv->lane_version < 2) {
                        dev_put(mpc->dev);
                        mpc->dev = NULL;
@@ -845,7 +845,7 @@ static void mpoad_close(struct atm_vcc *vcc)
 
        mpc->mpoad_vcc = NULL;
        if (mpc->dev) {
-               struct lec_priv *priv = (struct lec_priv *)mpc->dev->priv;
+               struct lec_priv *priv = netdev_priv(mpc->dev);
                priv->lane2_ops->associate_indicator = NULL;
                stop_mpc(mpc);
                dev_put(mpc->dev);
@@ -976,7 +976,7 @@ static int mpoa_event_listener(struct notifier_block *mpoa_notifier, unsigned lo
 
        switch (event) {
        case NETDEV_REGISTER:       /* a new lec device was allocated */
-               priv = (struct lec_priv *)dev->priv;
+               priv = netdev_priv(dev);
                if (priv->lane_version < 2)
                        break;
                priv->lane2_ops->associate_indicator = lane2_assoc_ind;
@@ -1098,7 +1098,8 @@ static void check_qos_and_open_shortcut(struct k_message *msg, struct mpoa_clien
                                    entry->shortcut = eg_entry->shortcut;
                }
                if(entry->shortcut){
-                       dprintk("mpoa: (%s) using egress SVC to reach %u.%u.%u.%u\n",client->dev->name, NIPQUAD(dst_ip));
+                       dprintk("mpoa: (%s) using egress SVC to reach %pI4\n",
+                               client->dev->name, &dst_ip);
                        client->eg_ops->put(eg_entry);
                        return;
                }
@@ -1123,7 +1124,8 @@ static void MPOA_res_reply_rcvd(struct k_message *msg, struct mpoa_client *mpc)
        __be32 dst_ip = msg->content.in_info.in_dst_ip;
        in_cache_entry *entry = mpc->in_ops->get(dst_ip, mpc);
 
-       dprintk("mpoa: (%s) MPOA_res_reply_rcvd: ip %u.%u.%u.%u\n", mpc->dev->name, NIPQUAD(dst_ip));
+       dprintk("mpoa: (%s) MPOA_res_reply_rcvd: ip %pI4\n",
+               mpc->dev->name, &dst_ip);
        ddprintk("mpoa: (%s) MPOA_res_reply_rcvd() entry = %p", mpc->dev->name, entry);
        if(entry == NULL){
                printk("\nmpoa: (%s) ARGH, received res. reply for an entry that doesn't exist.\n", mpc->dev->name);
@@ -1171,14 +1173,14 @@ static void ingress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc)
        in_cache_entry *entry = mpc->in_ops->get_with_mask(dst_ip, mpc, mask);
 
        if(entry == NULL){
-               printk("mpoa: (%s) ingress_purge_rcvd: purge for a non-existing entry, ", mpc->dev->name);
-               printk("ip = %u.%u.%u.%u\n", NIPQUAD(dst_ip));
+               printk("mpoa: (%s) ingress_purge_rcvd: purge for a non-existing entry, ip = %pI4\n",
+                      mpc->dev->name, &dst_ip);
                return;
        }
 
        do {
-               dprintk("mpoa: (%s) ingress_purge_rcvd: removing an ingress entry, ip = %u.%u.%u.%u\n" ,
-                       mpc->dev->name, NIPQUAD(dst_ip));
+               dprintk("mpoa: (%s) ingress_purge_rcvd: removing an ingress entry, ip = %pI4\n",
+                       mpc->dev->name, &dst_ip);
                write_lock_bh(&mpc->ingress_lock);
                mpc->in_ops->remove_entry(entry, mpc);
                write_unlock_bh(&mpc->ingress_lock);
@@ -1322,7 +1324,7 @@ static void set_mpc_ctrl_addr_rcvd(struct k_message *mesg, struct mpoa_client *m
        dprintk("\n");
 
        if (mpc->dev) {
-               priv = (struct lec_priv *)mpc->dev->priv;
+               priv = netdev_priv(mpc->dev);
                retval = priv->lane2_ops->associate_req(mpc->dev, mpc->dev->dev_addr, tlv, sizeof(tlv));
                if (retval == 0)
                        printk("mpoa: (%s) MPOA device type TLV association failed\n", mpc->dev->name);
@@ -1472,7 +1474,7 @@ static void __exit atm_mpoa_cleanup(void)
                tmp = mpc->next;
                if (mpc->dev != NULL) {
                        stop_mpc(mpc);
-                       priv = (struct lec_priv *)mpc->dev->priv;
+                       priv = netdev_priv(mpc->dev);
                        if (priv->lane2_ops != NULL)
                                priv->lane2_ops->associate_indicator = NULL;
                }
index 24799e3e78f786398e679823c3d29feea384bef8..4504a4b339bb8fb66e4c2e743815462157984c95 100644 (file)
@@ -94,7 +94,7 @@ static in_cache_entry *in_cache_add_entry(__be32 dst_ip,
                return NULL;
        }
 
-       dprintk("mpoa: mpoa_caches.c: adding an ingress entry, ip = %u.%u.%u.%u\n", NIPQUAD(dst_ip));
+       dprintk("mpoa: mpoa_caches.c: adding an ingress entry, ip = %pI4\n", &dst_ip);
 
        atomic_set(&entry->use, 1);
        dprintk("mpoa: mpoa_caches.c: new_in_cache_entry: about to lock\n");
@@ -150,7 +150,8 @@ static int cache_hit(in_cache_entry *entry, struct mpoa_client *mpc)
 
        if( entry->count > mpc->parameters.mpc_p1 &&
            entry->entry_state == INGRESS_INVALID){
-               dprintk("mpoa: (%s) mpoa_caches.c: threshold exceeded for ip %u.%u.%u.%u, sending MPOA res req\n", mpc->dev->name, NIPQUAD(entry->ctrl_info.in_dst_ip));
+               dprintk("mpoa: (%s) mpoa_caches.c: threshold exceeded for ip %pI4, sending MPOA res req\n",
+                       mpc->dev->name, &entry->ctrl_info.in_dst_ip);
                entry->entry_state = INGRESS_RESOLVING;
                msg.type =  SND_MPOA_RES_RQST;
                memcpy(msg.MPS_ctrl, mpc->mps_ctrl_addr, ATM_ESA_LEN );
@@ -184,7 +185,8 @@ static void in_cache_remove_entry(in_cache_entry *entry,
        struct k_message msg;
 
        vcc = entry->shortcut;
-       dprintk("mpoa: mpoa_caches.c: removing an ingress entry, ip = %u.%u.%u.%u\n",NIPQUAD(entry->ctrl_info.in_dst_ip));
+       dprintk("mpoa: mpoa_caches.c: removing an ingress entry, ip = %pI4\n",
+               &entry->ctrl_info.in_dst_ip);
 
        if (entry->prev != NULL)
                entry->prev->next = entry->next;
@@ -228,7 +230,8 @@ static void clear_count_and_expired(struct mpoa_client *client)
                next_entry = entry->next;
                if((now.tv_sec - entry->tv.tv_sec)
                   > entry->ctrl_info.holding_time){
-                       dprintk("mpoa: mpoa_caches.c: holding time expired, ip = %u.%u.%u.%u\n", NIPQUAD(entry->ctrl_info.in_dst_ip));
+                       dprintk("mpoa: mpoa_caches.c: holding time expired, ip = %pI4\n",
+                               &entry->ctrl_info.in_dst_ip);
                        client->in_ops->remove_entry(entry, client);
                }
                entry = next_entry;
@@ -453,7 +456,8 @@ static eg_cache_entry *eg_cache_add_entry(struct k_message *msg, struct mpoa_cli
                return NULL;
        }
 
-       dprintk("mpoa: mpoa_caches.c: adding an egress entry, ip = %u.%u.%u.%u, this should be our IP\n", NIPQUAD(msg->content.eg_info.eg_dst_ip));
+       dprintk("mpoa: mpoa_caches.c: adding an egress entry, ip = %pI4, this should be our IP\n",
+               &msg->content.eg_info.eg_dst_ip);
 
        atomic_set(&entry->use, 1);
        dprintk("mpoa: mpoa_caches.c: new_eg_cache_entry: about to lock\n");
@@ -469,8 +473,8 @@ static eg_cache_entry *eg_cache_add_entry(struct k_message *msg, struct mpoa_cli
        do_gettimeofday(&(entry->tv));
        entry->entry_state = EGRESS_RESOLVED;
        dprintk("mpoa: mpoa_caches.c: new_eg_cache_entry cache_id %lu\n", ntohl(entry->ctrl_info.cache_id));
-       dprintk("mpoa: mpoa_caches.c: mps_ip = %u.%u.%u.%u\n",
-               NIPQUAD(entry->ctrl_info.mps_ip));
+       dprintk("mpoa: mpoa_caches.c: mps_ip = %pI4\n",
+               &entry->ctrl_info.mps_ip);
        atomic_inc(&entry->use);
 
        write_unlock_irq(&client->egress_lock);
index f288fc4aef9bcd64a16add98a0b7ed86acb232da..c1d877bb5dffff29ac36abb70bf1bf6c9ac96b7e 100644 (file)
@@ -43,8 +43,8 @@ static const ctl_table ax25_param_table[] = {
                .procname       = "ip_default_mode",
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_ipdefmode,
                .extra2         = &max_ipdefmode
        },
@@ -53,8 +53,8 @@ static const ctl_table ax25_param_table[] = {
                .procname       = "ax25_default_mode",
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_axdefmode,
                .extra2         = &max_axdefmode
        },
@@ -63,8 +63,8 @@ static const ctl_table ax25_param_table[] = {
                .procname       = "backoff_type",
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_backoff,
                .extra2         = &max_backoff
        },
@@ -73,8 +73,8 @@ static const ctl_table ax25_param_table[] = {
                .procname       = "connect_mode",
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_conmode,
                .extra2         = &max_conmode
        },
@@ -83,8 +83,8 @@ static const ctl_table ax25_param_table[] = {
                .procname       = "standard_window_size",
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_window,
                .extra2         = &max_window
        },
@@ -93,8 +93,8 @@ static const ctl_table ax25_param_table[] = {
                .procname       = "extended_window_size",
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_ewindow,
                .extra2         = &max_ewindow
        },
@@ -103,8 +103,8 @@ static const ctl_table ax25_param_table[] = {
                .procname       = "t1_timeout",
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_t1,
                .extra2         = &max_t1
        },
@@ -113,8 +113,8 @@ static const ctl_table ax25_param_table[] = {
                .procname       = "t2_timeout",
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_t2,
                .extra2         = &max_t2
        },
@@ -123,8 +123,8 @@ static const ctl_table ax25_param_table[] = {
                .procname       = "t3_timeout",
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_t3,
                .extra2         = &max_t3
        },
@@ -133,8 +133,8 @@ static const ctl_table ax25_param_table[] = {
                .procname       = "idle_timeout",
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_idle,
                .extra2         = &max_idle
        },
@@ -143,8 +143,8 @@ static const ctl_table ax25_param_table[] = {
                .procname       = "maximum_retry_count",
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_n2,
                .extra2         = &max_n2
        },
@@ -153,8 +153,8 @@ static const ctl_table ax25_param_table[] = {
                .procname       = "maximum_packet_length",
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_paclen,
                .extra2         = &max_paclen
        },
@@ -163,8 +163,8 @@ static const ctl_table ax25_param_table[] = {
                .procname       = "protocol",
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_proto,
                .extra2         = &max_proto
        },
@@ -174,8 +174,8 @@ static const ctl_table ax25_param_table[] = {
                .procname       = "dama_slave_timeout",
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_ds_timeout,
                .extra2         = &max_ds_timeout
        },
index 80ba30cf4b682556252587e2ed57468f6663efa0..f8efaf35293c6a7e2808c0e9db91314a7bb851f8 100644 (file)
@@ -311,7 +311,6 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
        struct sk_buff *nskb;
        u8 type;
 
-       dev->last_rx = jiffies;
        s->stats.rx_bytes += skb->len;
 
        type = *(u8 *) skb->data; skb_pull(skb, 1);
@@ -566,7 +565,7 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
                goto failed;
        }
 
-       s = dev->priv;
+       s = netdev_priv(dev);
 
        /* This is rx header therefore addresses are swapped.
         * ie eh.h_dest is our local address. */
index d9fa0ab2c87f42cacf1dc91199a1b982ae07da2c..47e179f62e820a72d28e5539da96ad55210f9346 100644 (file)
@@ -62,14 +62,14 @@ static int bnep_net_close(struct net_device *dev)
 
 static struct net_device_stats *bnep_net_get_stats(struct net_device *dev)
 {
-       struct bnep_session *s = dev->priv;
+       struct bnep_session *s = netdev_priv(dev);
        return &s->stats;
 }
 
 static void bnep_net_set_mc_list(struct net_device *dev)
 {
 #ifdef CONFIG_BT_BNEP_MC_FILTER
-       struct bnep_session *s = dev->priv;
+       struct bnep_session *s = netdev_priv(dev);
        struct sock *sk = s->sock->sk;
        struct bnep_set_filter_req *r;
        struct sk_buff *skb;
@@ -183,7 +183,7 @@ static inline int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session
 
 static int bnep_net_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct bnep_session *s = dev->priv;
+       struct bnep_session *s = netdev_priv(dev);
        struct sock *sk = s->sock->sk;
 
        BT_DBG("skb %p, dev %p", skb, dev);
index f4f6615cad9f910c55f1cc70db8e633e010ce6eb..f2bbb2f654349445a13bc03a57cf48acd2c31ed9 100644 (file)
@@ -113,8 +113,7 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
        conn->dev.class = bt_class;
        conn->dev.parent = &hdev->dev;
 
-       snprintf(conn->dev.bus_id, BUS_ID_SIZE, "%s:%d",
-                                       hdev->name, conn->handle);
+       dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
 
        dev_set_drvdata(&conn->dev, conn);
 
@@ -132,7 +131,7 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
  */
 static int __match_tty(struct device *dev, void *data)
 {
-       return !strncmp(dev->bus_id, "rfcomm", 6);
+       return !strncmp(dev_name(dev), "rfcomm", 6);
 }
 
 static void del_conn(struct work_struct *work)
@@ -421,7 +420,7 @@ int hci_register_sysfs(struct hci_dev *hdev)
        dev->class = bt_class;
        dev->parent = hdev->parent;
 
-       strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE);
+       dev_set_name(dev, hdev->name);
 
        dev_set_drvdata(dev, hdev);
 
index 0a09ccf68c1c16e6362f895ba389f7287520594e..ee3a8dd13f55d8eea7e5fc252dd2533556f52162 100644 (file)
@@ -460,7 +460,7 @@ void br_net_exit(struct net *net)
 restart:
        for_each_netdev(net, dev) {
                if (dev->priv_flags & IFF_EBRIDGE) {
-                       del_br(dev->priv);
+                       del_br(netdev_priv(dev));
                        goto restart;
                }
        }
index fa5cda4e552ab0088901a2820f4267d31b303030..db6176d96e7140253ce092567376677124b902cc 100644 (file)
@@ -938,35 +938,35 @@ static ctl_table brnf_table[] = {
                .data           = &brnf_call_arptables,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &brnf_sysctl_call_tables,
+               .proc_handler   = brnf_sysctl_call_tables,
        },
        {
                .procname       = "bridge-nf-call-iptables",
                .data           = &brnf_call_iptables,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &brnf_sysctl_call_tables,
+               .proc_handler   = brnf_sysctl_call_tables,
        },
        {
                .procname       = "bridge-nf-call-ip6tables",
                .data           = &brnf_call_ip6tables,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &brnf_sysctl_call_tables,
+               .proc_handler   = brnf_sysctl_call_tables,
        },
        {
                .procname       = "bridge-nf-filter-vlan-tagged",
                .data           = &brnf_filter_vlan_tagged,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &brnf_sysctl_call_tables,
+               .proc_handler   = brnf_sysctl_call_tables,
        },
        {
                .procname       = "bridge-nf-filter-pppoe-tagged",
                .data           = &brnf_filter_pppoe_tagged,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &brnf_sysctl_call_tables,
+               .proc_handler   = brnf_sysctl_call_tables,
        },
        { .ctl_name = 0 }
 };
index 158dee8b4965307c045d6fec2d5a930070a4cd68..603d89248e7148e1a830146953dfbfdcb54491bd 100644 (file)
@@ -22,7 +22,7 @@
 #include "br_private.h"
 
 #define to_dev(obj)    container_of(obj, struct device, kobj)
-#define to_bridge(cd)  ((struct net_bridge *)(to_net_dev(cd)->priv))
+#define to_bridge(cd)  ((struct net_bridge *)netdev_priv(to_net_dev(cd)))
 
 /*
  * Common code for storing bridge parameters.
index 3d33c608906aeadddaa0a0361372d34430121d97..d44cbf8c374af41d54bb0d7cd0727fa06d30052a 100644 (file)
@@ -79,7 +79,6 @@ print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
        }
 }
 
-#define myNIPQUAD(a) a[0], a[1], a[2], a[3]
 static void
 ebt_log_packet(u_int8_t pf, unsigned int hooknum,
    const struct sk_buff *skb, const struct net_device *in,
@@ -113,9 +112,8 @@ ebt_log_packet(u_int8_t pf, unsigned int hooknum,
                        printk(" INCOMPLETE IP header");
                        goto out;
                }
-               printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u, IP "
-                      "tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr),
-                      NIPQUAD(ih->daddr), ih->tos, ih->protocol);
+               printk(" IP SRC=%pI4 IP DST=%pI4, IP tos=0x%02X, IP proto=%d",
+                      &ih->saddr, &ih->daddr, ih->tos, ih->protocol);
                print_ports(skb, ih->protocol, ih->ihl*4);
                goto out;
        }
@@ -133,10 +131,8 @@ ebt_log_packet(u_int8_t pf, unsigned int hooknum,
                        printk(" INCOMPLETE IPv6 header");
                        goto out;
                }
-               printk(" IPv6 SRC=%x:%x:%x:%x:%x:%x:%x:%x "
-                      "IPv6 DST=%x:%x:%x:%x:%x:%x:%x:%x, IPv6 "
-                      "priority=0x%01X, Next Header=%d", NIP6(ih->saddr),
-                      NIP6(ih->daddr), ih->priority, ih->nexthdr);
+               printk(" IPv6 SRC=%pI6 IPv6 DST=%pI6, IPv6 priority=0x%01X, Next Header=%d",
+                      &ih->saddr, &ih->daddr, ih->priority, ih->nexthdr);
                nexthdr = ih->nexthdr;
                offset_ph = ipv6_skip_exthdr(skb, sizeof(_iph), &nexthdr);
                if (offset_ph == -1)
@@ -177,12 +173,10 @@ ebt_log_packet(u_int8_t pf, unsigned int hooknum,
                        }
                        printk(" ARP MAC SRC=");
                        print_MAC(ap->mac_src);
-                       printk(" ARP IP SRC=%u.%u.%u.%u",
-                              myNIPQUAD(ap->ip_src));
+                       printk(" ARP IP SRC=%pI4", ap->ip_src);
                        printk(" ARP MAC DST=");
                        print_MAC(ap->mac_dst);
-                       printk(" ARP IP DST=%u.%u.%u.%u",
-                              myNIPQUAD(ap->ip_dst));
+                       printk(" ARP IP DST=%pI4", ap->ip_dst);
                }
        }
 out:
index ee631843c2f533de37101e92d05d447f85cf4d1f..5e2ac0c4b07cfdab7b2a5a2c74e2c2ddcd337328 100644 (file)
@@ -209,7 +209,7 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
 void skb_free_datagram(struct sock *sk, struct sk_buff *skb)
 {
        kfree_skb(skb);
-       sk_mem_reclaim(sk);
+       sk_mem_reclaim_partial(sk);
 }
 
 /**
@@ -248,8 +248,7 @@ int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags)
                spin_unlock_bh(&sk->sk_receive_queue.lock);
        }
 
-       kfree_skb(skb);
-       sk_mem_reclaim(sk);
+       skb_free_datagram(sk, skb);
        return err;
 }
 
index 9174c77d3112c65237cbbd2e063eb55b03b5c39e..e08c0fcd603bbe7d8d550b0f9ded5b9969014917 100644 (file)
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/module.h>
-#include <linux/kallsyms.h>
 #include <linux/netpoll.h>
 #include <linux/rcupdate.h>
 #include <linux/delay.h>
@@ -924,10 +923,15 @@ int dev_change_name(struct net_device *dev, const char *newname)
                strlcpy(dev->name, newname, IFNAMSIZ);
 
 rollback:
-       ret = device_rename(&dev->dev, dev->name);
-       if (ret) {
-               memcpy(dev->name, oldname, IFNAMSIZ);
-               return ret;
+       /* For now only devices in the initial network namespace
+        * are in sysfs.
+        */
+       if (net == &init_net) {
+               ret = device_rename(&dev->dev, dev->name);
+               if (ret) {
+                       memcpy(dev->name, oldname, IFNAMSIZ);
+                       return ret;
+               }
        }
 
        write_lock_bh(&dev_base_lock);
@@ -2251,8 +2255,10 @@ int netif_receive_skb(struct sk_buff *skb)
        rcu_read_lock();
 
        /* Don't receive packets in an exiting network namespace */
-       if (!net_alive(dev_net(skb->dev)))
+       if (!net_alive(dev_net(skb->dev))) {
+               kfree_skb(skb);
                goto out;
+       }
 
 #ifdef CONFIG_NET_CLS_ACT
        if (skb->tc_verd & TC_NCLS) {
@@ -2371,7 +2377,7 @@ EXPORT_SYMBOL(__napi_schedule);
 static void net_rx_action(struct softirq_action *h)
 {
        struct list_head *list = &__get_cpu_var(softnet_data).poll_list;
-       unsigned long start_time = jiffies;
+       unsigned long time_limit = jiffies + 2;
        int budget = netdev_budget;
        void *have;
 
@@ -2382,13 +2388,10 @@ static void net_rx_action(struct softirq_action *h)
                int work, weight;
 
                /* If softirq window is exhuasted then punt.
-                *
-                * Note that this is a slight policy change from the
-                * previous NAPI code, which would allow up to 2
-                * jiffies to pass before breaking out.  The test
-                * used to be "jiffies - start_time > 1".
+                * Allow this to run for 2 jiffies since which will allow
+                * an average latency of 1.5/HZ.
                 */
-               if (unlikely(budget <= 0 || jiffies != start_time))
+               if (unlikely(budget <= 0 || time_after(jiffies, time_limit)))
                        goto softnet_break;
 
                local_irq_enable();
@@ -2797,31 +2800,6 @@ static void ptype_seq_stop(struct seq_file *seq, void *v)
        rcu_read_unlock();
 }
 
-static void ptype_seq_decode(struct seq_file *seq, void *sym)
-{
-#ifdef CONFIG_KALLSYMS
-       unsigned long offset = 0, symsize;
-       const char *symname;
-       char *modname;
-       char namebuf[128];
-
-       symname = kallsyms_lookup((unsigned long)sym, &symsize, &offset,
-                                 &modname, namebuf);
-
-       if (symname) {
-               char *delim = ":";
-
-               if (!modname)
-                       modname = delim = "";
-               seq_printf(seq, "%s%s%s%s+0x%lx", delim, modname, delim,
-                          symname, offset);
-               return;
-       }
-#endif
-
-       seq_printf(seq, "[%p]", sym);
-}
-
 static int ptype_seq_show(struct seq_file *seq, void *v)
 {
        struct packet_type *pt = v;
@@ -2834,10 +2812,8 @@ static int ptype_seq_show(struct seq_file *seq, void *v)
                else
                        seq_printf(seq, "%04x", ntohs(pt->type));
 
-               seq_printf(seq, " %-8s ",
-                          pt->dev ? pt->dev->name : "");
-               ptype_seq_decode(seq,  pt->func);
-               seq_putc(seq, '\n');
+               seq_printf(seq, " %-8s %pF\n",
+                          pt->dev ? pt->dev->name : "", pt->func);
        }
 
        return 0;
@@ -4463,6 +4439,15 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
        if (dev->features & NETIF_F_NETNS_LOCAL)
                goto out;
 
+#ifdef CONFIG_SYSFS
+       /* Don't allow real devices to be moved when sysfs
+        * is enabled.
+        */
+       err = -EINVAL;
+       if (dev->dev.parent)
+               goto out;
+#endif
+
        /* Ensure the device has been registrered */
        err = -EINVAL;
        if (dev->reg_state != NETREG_REGISTERED)
@@ -4520,6 +4505,8 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
         */
        dev_addr_discard(dev);
 
+       netdev_unregister_kobject(dev);
+
        /* Actually switch the network namespace */
        dev_net_set(dev, net);
 
@@ -4536,7 +4523,6 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
        }
 
        /* Fixup kobjects */
-       netdev_unregister_kobject(dev);
        err = netdev_register_kobject(dev);
        WARN_ON(err);
 
@@ -4843,6 +4829,12 @@ static void __net_exit default_device_exit(struct net *net)
                if (dev->features & NETIF_F_NETNS_LOCAL)
                        continue;
 
+               /* Delete virtual devices */
+               if (dev->rtnl_link_ops && dev->rtnl_link_ops->dellink) {
+                       dev->rtnl_link_ops->dellink(dev);
+                       continue;
+               }
+
                /* Push remaing network devices to init_net */
                snprintf(fb_name, IFNAMSIZ, "dev%d", dev->ifindex);
                err = dev_change_net_namespace(dev, &init_net, fb_name);
@@ -4889,9 +4881,6 @@ static int __init net_dev_init(void)
        if (register_pernet_subsys(&netdev_net_ops))
                goto out;
 
-       if (register_pernet_device(&default_device_ops))
-               goto out;
-
        /*
         *      Initialise the packet receive queues.
         */
@@ -4908,10 +4897,25 @@ static int __init net_dev_init(void)
                queue->backlog.weight = weight_p;
        }
 
-       netdev_dma_register();
-
        dev_boot_phase = 0;
 
+       /* The loopback device is special if any other network devices
+        * is present in a network namespace the loopback device must
+        * be present. Since we now dynamically allocate and free the
+        * loopback device ensure this invariant is maintained by
+        * keeping the loopback device as the first device on the
+        * list of network devices.  Ensuring the loopback devices
+        * is the first device that appears and the last network device
+        * that disappears.
+        */
+       if (register_pernet_device(&loopback_net_ops))
+               goto out;
+
+       if (register_pernet_device(&default_device_ops))
+               goto out;
+
+       netdev_dma_register();
+
        open_softirq(NET_TX_SOFTIRQ, net_tx_action);
        open_softirq(NET_RX_SOFTIRQ, net_rx_action);
 
index 09c1530f46814d287929a37ce948885d44f8bb03..57bc4d5b8d084c053cded6ebddfe66bf6255d9f5 100644 (file)
@@ -263,9 +263,11 @@ again:
 void dst_release(struct dst_entry *dst)
 {
        if (dst) {
-               WARN_ON(atomic_read(&dst->__refcnt) < 1);
+               int newrefcnt;
+
                smp_mb__before_atomic_dec();
-               atomic_dec(&dst->__refcnt);
+               newrefcnt = atomic_dec_return(&dst->__refcnt);
+               WARN_ON(newrefcnt < 0);
        }
 }
 EXPORT_SYMBOL(dst_release);
index 79de3b14a8d13256f54aaea43d1e3c6c9092833c..32b3a0152d7adba2079e5a1bc5f5ba9001037996 100644 (file)
@@ -664,17 +664,18 @@ static int __init fib_rules_init(void)
        rtnl_register(PF_UNSPEC, RTM_DELRULE, fib_nl_delrule, NULL);
        rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, fib_nl_dumprule);
 
-       err = register_netdevice_notifier(&fib_rules_notifier);
+       err = register_pernet_subsys(&fib_rules_net_ops);
        if (err < 0)
                goto fail;
 
-       err = register_pernet_subsys(&fib_rules_net_ops);
+       err = register_netdevice_notifier(&fib_rules_notifier);
        if (err < 0)
                goto fail_unregister;
+
        return 0;
 
 fail_unregister:
-       unregister_netdevice_notifier(&fib_rules_notifier);
+       unregister_pernet_subsys(&fib_rules_net_ops);
 fail:
        rtnl_unregister(PF_UNSPEC, RTM_NEWRULE);
        rtnl_unregister(PF_UNSPEC, RTM_DELRULE);
index 5cf81052d044ef91710d51ff7ab2ec162bdd3be6..d323388dd1ba9d9673663349ca61f7e857dacb9b 100644 (file)
@@ -307,7 +307,7 @@ void flow_cache_flush(void)
        put_online_cpus();
 }
 
-static void __devinit flow_cache_cpu_prepare(int cpu)
+static void __init flow_cache_cpu_prepare(int cpu)
 {
        struct tasklet_struct *tasklet;
        unsigned long order;
index 1dc728b38589699d4b85b215208bf6f0bde154f9..cca6a55909ebbf6cde921a3db6dea67cb5725326 100644 (file)
@@ -531,9 +531,7 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl,
        if (!n)
                goto out;
 
-#ifdef CONFIG_NET_NS
-       n->net = hold_net(net);
-#endif
+       write_pnet(&n->net, hold_net(net));
        memcpy(n->key, pkey, key_len);
        n->dev = dev;
        if (dev)
@@ -1340,7 +1338,6 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
        if (p) {
                p->tbl            = tbl;
                atomic_set(&p->refcnt, 1);
-               INIT_RCU_HEAD(&p->rcu_head);
                p->reachable_time =
                                neigh_rand_reach_time(p->base_reachable_time);
 
@@ -1351,9 +1348,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
 
                dev_hold(dev);
                p->dev = dev;
-#ifdef CONFIG_NET_NS
-               p->net = hold_net(net);
-#endif
+               write_pnet(&p->net, hold_net(net));
                p->sysctl_table = NULL;
                write_lock_bh(&tbl->lock);
                p->next         = tbl->parms.next;
@@ -1408,11 +1403,8 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl)
        unsigned long now = jiffies;
        unsigned long phsize;
 
-#ifdef CONFIG_NET_NS
-       tbl->parms.net = &init_net;
-#endif
+       write_pnet(&tbl->parms.net, &init_net);
        atomic_set(&tbl->parms.refcnt, 1);
-       INIT_RCU_HEAD(&tbl->parms.rcu_head);
        tbl->parms.reachable_time =
                          neigh_rand_reach_time(tbl->parms.base_reachable_time);
 
@@ -1426,9 +1418,8 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl)
                panic("cannot create neighbour cache statistics");
 
 #ifdef CONFIG_PROC_FS
-       tbl->pde = proc_create_data(tbl->id, 0, init_net.proc_net_stat,
-                                   &neigh_stat_seq_fops, tbl);
-       if (!tbl->pde)
+       if (!proc_create_data(tbl->id, 0, init_net.proc_net_stat,
+                             &neigh_stat_seq_fops, tbl))
                panic("cannot create neighbour proc dir entry");
 #endif
 
@@ -2568,128 +2559,128 @@ static struct neigh_sysctl_table {
                        .procname       = "mcast_solicit",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
+                       .proc_handler   = proc_dointvec,
                },
                {
                        .ctl_name       = NET_NEIGH_UCAST_SOLICIT,
                        .procname       = "ucast_solicit",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
+                       .proc_handler   = proc_dointvec,
                },
                {
                        .ctl_name       = NET_NEIGH_APP_SOLICIT,
                        .procname       = "app_solicit",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
+                       .proc_handler   = proc_dointvec,
                },
                {
                        .procname       = "retrans_time",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec_userhz_jiffies,
+                       .proc_handler   = proc_dointvec_userhz_jiffies,
                },
                {
                        .ctl_name       = NET_NEIGH_REACHABLE_TIME,
                        .procname       = "base_reachable_time",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec_jiffies,
-                       .strategy       = &sysctl_jiffies,
+                       .proc_handler   = proc_dointvec_jiffies,
+                       .strategy       = sysctl_jiffies,
                },
                {
                        .ctl_name       = NET_NEIGH_DELAY_PROBE_TIME,
                        .procname       = "delay_first_probe_time",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec_jiffies,
-                       .strategy       = &sysctl_jiffies,
+                       .proc_handler   = proc_dointvec_jiffies,
+                       .strategy       = sysctl_jiffies,
                },
                {
                        .ctl_name       = NET_NEIGH_GC_STALE_TIME,
                        .procname       = "gc_stale_time",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec_jiffies,
-                       .strategy       = &sysctl_jiffies,
+                       .proc_handler   = proc_dointvec_jiffies,
+                       .strategy       = sysctl_jiffies,
                },
                {
                        .ctl_name       = NET_NEIGH_UNRES_QLEN,
                        .procname       = "unres_qlen",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
+                       .proc_handler   = proc_dointvec,
                },
                {
                        .ctl_name       = NET_NEIGH_PROXY_QLEN,
                        .procname       = "proxy_qlen",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
+                       .proc_handler   = proc_dointvec,
                },
                {
                        .procname       = "anycast_delay",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec_userhz_jiffies,
+                       .proc_handler   = proc_dointvec_userhz_jiffies,
                },
                {
                        .procname       = "proxy_delay",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec_userhz_jiffies,
+                       .proc_handler   = proc_dointvec_userhz_jiffies,
                },
                {
                        .procname       = "locktime",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec_userhz_jiffies,
+                       .proc_handler   = proc_dointvec_userhz_jiffies,
                },
                {
                        .ctl_name       = NET_NEIGH_RETRANS_TIME_MS,
                        .procname       = "retrans_time_ms",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec_ms_jiffies,
-                       .strategy       = &sysctl_ms_jiffies,
+                       .proc_handler   = proc_dointvec_ms_jiffies,
+                       .strategy       = sysctl_ms_jiffies,
                },
                {
                        .ctl_name       = NET_NEIGH_REACHABLE_TIME_MS,
                        .procname       = "base_reachable_time_ms",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec_ms_jiffies,
-                       .strategy       = &sysctl_ms_jiffies,
+                       .proc_handler   = proc_dointvec_ms_jiffies,
+                       .strategy       = sysctl_ms_jiffies,
                },
                {
                        .ctl_name       = NET_NEIGH_GC_INTERVAL,
                        .procname       = "gc_interval",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec_jiffies,
-                       .strategy       = &sysctl_jiffies,
+                       .proc_handler   = proc_dointvec_jiffies,
+                       .strategy       = sysctl_jiffies,
                },
                {
                        .ctl_name       = NET_NEIGH_GC_THRESH1,
                        .procname       = "gc_thresh1",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
+                       .proc_handler   = proc_dointvec,
                },
                {
                        .ctl_name       = NET_NEIGH_GC_THRESH2,
                        .procname       = "gc_thresh2",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
+                       .proc_handler   = proc_dointvec,
                },
                {
                        .ctl_name       = NET_NEIGH_GC_THRESH3,
                        .procname       = "gc_thresh3",
                        .maxlen         = sizeof(int),
                        .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
+                       .proc_handler   = proc_dointvec,
                },
                {},
        },
index 92d6b946731430ddb9b5533498bc6e04c104c3c0..146dcfeb060e75c5090efdb12bf11ff6216cc12b 100644 (file)
@@ -476,6 +476,10 @@ void netdev_unregister_kobject(struct net_device * net)
        struct device *dev = &(net->dev);
 
        kobject_get(&dev->kobj);
+
+       if (dev_net(net) != &init_net)
+               return;
+
        device_del(dev);
 }
 
@@ -490,7 +494,7 @@ int netdev_register_kobject(struct net_device *net)
        dev->groups = groups;
 
        BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ);
-       strlcpy(dev->bus_id, net->name, BUS_ID_SIZE);
+       dev_set_name(dev, net->name);
 
 #ifdef CONFIG_SYSFS
        *groups++ = &netstat_group;
@@ -501,6 +505,9 @@ int netdev_register_kobject(struct net_device *net)
 #endif
 #endif /* CONFIG_SYSFS */
 
+       if (dev_net(net) != &init_net)
+               return 0;
+
        return device_add(dev);
 }
 
index 1895a4ca9c4f7878467afee19ab714f072c76d57..55cffad2f328349f8c5363a89a55f0e503beba85 100644 (file)
@@ -47,7 +47,6 @@ static __net_init int setup_net(struct net *net)
                goto out;
 
        ng->len = INITIAL_NET_GEN_PTRS;
-       INIT_RCU_HEAD(&ng->rcu);
        rcu_assign_pointer(net->gen, ng);
 
        error = 0;
@@ -478,7 +477,6 @@ int net_assign_generic(struct net *net, int id, void *data)
         */
 
        ng->len = id;
-       INIT_RCU_HEAD(&ng->rcu);
        memcpy(&ng->ptr, &old_ng->ptr, old_ng->len);
 
        rcu_assign_pointer(net->gen, ng);
index 6c7af390be0a515cfb1d09d2db79f16776e0dbe4..34f5d072f1688040d62ddcce0fff6ce02645311e 100644 (file)
@@ -553,7 +553,6 @@ out:
 
 void netpoll_print_options(struct netpoll *np)
 {
-       DECLARE_MAC_BUF(mac);
        printk(KERN_INFO "%s: local port %d\n",
                         np->name, np->local_port);
        printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",
@@ -564,8 +563,8 @@ void netpoll_print_options(struct netpoll *np)
                         np->name, np->remote_port);
        printk(KERN_INFO "%s: remote IP %d.%d.%d.%d\n",
                         np->name, HIPQUAD(np->remote_ip));
-       printk(KERN_INFO "%s: remote ethernet address %s\n",
-                        np->name, print_mac(mac, np->remote_mac));
+       printk(KERN_INFO "%s: remote ethernet address %pM\n",
+                        np->name, np->remote_mac);
 }
 
 int netpoll_parse_options(struct netpoll *np, char *opt)
index a47f5bad110dc99ae7218df0a034a72459ef9e31..a4f5ad1ab35220b9df2ee9e57dcf913f6091dd82 100644 (file)
@@ -422,6 +422,7 @@ static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
                                          const char *ifname);
 static int pktgen_device_event(struct notifier_block *, unsigned long, void *);
 static void pktgen_run_all_threads(void);
+static void pktgen_reset_all_threads(void);
 static void pktgen_stop_all_threads_ifs(void);
 static int pktgen_stop_device(struct pktgen_dev *pkt_dev);
 static void pktgen_stop(struct pktgen_thread *t);
@@ -480,6 +481,9 @@ static ssize_t pgctrl_write(struct file *file, const char __user * buf,
        else if (!strcmp(data, "start"))
                pktgen_run_all_threads();
 
+       else if (!strcmp(data, "reset"))
+               pktgen_reset_all_threads();
+
        else
                printk(KERN_WARNING "pktgen: Unknown command: %s\n", data);
 
@@ -509,7 +513,6 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
        __u64 sa;
        __u64 stopped;
        __u64 now = getCurUs();
-       DECLARE_MAC_BUF(mac);
 
        seq_printf(seq,
                   "Params: count %llu  min_pkt_size: %u  max_pkt_size: %u\n",
@@ -554,12 +557,12 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
 
        seq_puts(seq, "     src_mac: ");
 
-       seq_printf(seq, "%s ",
-                  print_mac(mac, is_zero_ether_addr(pkt_dev->src_mac) ?
-                            pkt_dev->odev->dev_addr : pkt_dev->src_mac));
+       seq_printf(seq, "%pM ",
+                  is_zero_ether_addr(pkt_dev->src_mac) ?
+                            pkt_dev->odev->dev_addr : pkt_dev->src_mac);
 
        seq_printf(seq, "dst_mac: ");
-       seq_printf(seq, "%s\n", print_mac(mac, pkt_dev->dst_mac));
+       seq_printf(seq, "%pM\n", pkt_dev->dst_mac);
 
        seq_printf(seq,
                   "     udp_src_min: %d  udp_src_max: %d  udp_dst_min: %d  udp_dst_max: %d\n",
@@ -3174,6 +3177,24 @@ static void pktgen_run_all_threads(void)
        pktgen_wait_all_threads_run();
 }
 
+static void pktgen_reset_all_threads(void)
+{
+       struct pktgen_thread *t;
+
+       pr_debug("pktgen: entering pktgen_reset_all_threads.\n");
+
+       mutex_lock(&pktgen_thread_lock);
+
+       list_for_each_entry(t, &pktgen_threads, th_list)
+               t->control |= (T_REMDEVALL);
+
+       mutex_unlock(&pktgen_thread_lock);
+
+       schedule_timeout_interruptible(msecs_to_jiffies(125));  /* Propagate thread->control  */
+
+       pktgen_wait_all_threads_run();
+}
+
 static void show_results(struct pktgen_dev *pkt_dev, int nr_frags)
 {
        __u64 total_us, bps, mbps, pps, idle;
index d49ef8301b5bd5de20d1b8a6e57aa5144ffff28a..267185a848f624d27383ff7ef6815932a203fec7 100644 (file)
@@ -501,7 +501,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
        new->network_header     = old->network_header;
        new->mac_header         = old->mac_header;
        new->dst                = dst_clone(old->dst);
-#ifdef CONFIG_INET
+#ifdef CONFIG_XFRM
        new->sp                 = secpath_get(old->sp);
 #endif
        memcpy(new->cb, old->cb, sizeof(old->cb));
@@ -556,6 +556,7 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
        C(truesize);
 #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
        C(do_not_encrypt);
+       C(requeue);
 #endif
        atomic_set(&n->users, 1);
 
index 341e39456952abc106b9b7c9ec5eaa04e8de208f..5a6fe4dfad4602781ea5db3cc4b8b4125decb677 100644 (file)
@@ -2040,7 +2040,8 @@ int proto_register(struct proto *prot, int alloc_slab)
 
        if (alloc_slab) {
                prot->slab = kmem_cache_create(prot->name, prot->obj_size, 0,
-                                              SLAB_HWCACHE_ALIGN, NULL);
+                                       SLAB_HWCACHE_ALIGN | prot->slab_flags,
+                                       NULL);
 
                if (prot->slab == NULL) {
                        printk(KERN_CRIT "%s: Can't create sock SLAB cache!\n",
@@ -2079,7 +2080,9 @@ int proto_register(struct proto *prot, int alloc_slab)
                        prot->twsk_prot->twsk_slab =
                                kmem_cache_create(timewait_sock_slab_name,
                                                  prot->twsk_prot->twsk_obj_size,
-                                                 0, SLAB_HWCACHE_ALIGN,
+                                                 0,
+                                                 SLAB_HWCACHE_ALIGN |
+                                                       prot->slab_flags,
                                                  NULL);
                        if (prot->twsk_prot->twsk_slab == NULL)
                                goto out_free_timewait_sock_slab_name;
index f686467ff12ba085f12b140f340a639699a7e049..2bc0384b0448d9d3ab67a53b31de78f4929623a2 100644 (file)
@@ -22,7 +22,7 @@ static struct ctl_table net_core_table[] = {
                .data           = &sysctl_wmem_max,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_CORE_RMEM_MAX,
@@ -30,7 +30,7 @@ static struct ctl_table net_core_table[] = {
                .data           = &sysctl_rmem_max,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_CORE_WMEM_DEFAULT,
@@ -38,7 +38,7 @@ static struct ctl_table net_core_table[] = {
                .data           = &sysctl_wmem_default,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_CORE_RMEM_DEFAULT,
@@ -46,7 +46,7 @@ static struct ctl_table net_core_table[] = {
                .data           = &sysctl_rmem_default,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_CORE_DEV_WEIGHT,
@@ -54,7 +54,7 @@ static struct ctl_table net_core_table[] = {
                .data           = &weight_p,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_CORE_MAX_BACKLOG,
@@ -62,7 +62,7 @@ static struct ctl_table net_core_table[] = {
                .data           = &netdev_max_backlog,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_CORE_MSG_COST,
@@ -70,8 +70,8 @@ static struct ctl_table net_core_table[] = {
                .data           = &net_ratelimit_state.interval,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies,
        },
        {
                .ctl_name       = NET_CORE_MSG_BURST,
@@ -79,7 +79,7 @@ static struct ctl_table net_core_table[] = {
                .data           = &net_ratelimit_state.burst,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_CORE_OPTMEM_MAX,
@@ -87,7 +87,7 @@ static struct ctl_table net_core_table[] = {
                .data           = &sysctl_optmem_max,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
 #ifdef CONFIG_XFRM
        {
@@ -96,7 +96,7 @@ static struct ctl_table net_core_table[] = {
                .data           = &sysctl_xfrm_aevent_etime,
                .maxlen         = sizeof(u32),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_CORE_AEVENT_RSEQTH,
@@ -104,7 +104,7 @@ static struct ctl_table net_core_table[] = {
                .data           = &sysctl_xfrm_aevent_rseqth,
                .maxlen         = sizeof(u32),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = CTL_UNNUMBERED,
@@ -112,7 +112,7 @@ static struct ctl_table net_core_table[] = {
                .data           = &sysctl_xfrm_larval_drop,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = CTL_UNNUMBERED,
@@ -120,7 +120,7 @@ static struct ctl_table net_core_table[] = {
                .data           = &sysctl_xfrm_acq_expires,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
 #endif /* CONFIG_XFRM */
 #endif /* CONFIG_NET */
@@ -130,7 +130,7 @@ static struct ctl_table net_core_table[] = {
                .data           = &netdev_budget,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_CORE_WARNINGS,
@@ -138,7 +138,7 @@ static struct ctl_table net_core_table[] = {
                .data           = &net_msg_warn,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        { .ctl_name = 0 }
 };
@@ -150,7 +150,7 @@ static struct ctl_table netns_core_table[] = {
                .data           = &init_net.core.sysctl_somaxconn,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        { .ctl_name = 0 }
 };
index 8fe931a3d7a1b1b7240a3421b7af0c404afae375..647cb0614f843752ec64106bb179ecc3a44c9db6 100644 (file)
 
 #include "ccid.h"
 
+static u8 builtin_ccids[] = {
+       DCCPC_CCID2,            /* CCID2 is supported by default */
+#if defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE)
+       DCCPC_CCID3,
+#endif
+};
+
 static struct ccid_operations *ccids[CCID_MAX];
 #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
 static atomic_t ccids_lockct = ATOMIC_INIT(0);
@@ -86,6 +93,47 @@ static void ccid_kmem_cache_destroy(struct kmem_cache *slab)
        }
 }
 
+/* check that up to @array_len members in @ccid_array are supported */
+bool ccid_support_check(u8 const *ccid_array, u8 array_len)
+{
+       u8 i, j, found;
+
+       for (i = 0, found = 0; i < array_len; i++, found = 0) {
+               for (j = 0; !found && j < ARRAY_SIZE(builtin_ccids); j++)
+                       found = (ccid_array[i] == builtin_ccids[j]);
+               if (!found)
+                       return false;
+       }
+       return true;
+}
+
+/**
+ * ccid_get_builtin_ccids  -  Provide copy of `builtin' CCID array
+ * @ccid_array: pointer to copy into
+ * @array_len: value to return length into
+ * This function allocates memory - caller must see that it is freed after use.
+ */
+int ccid_get_builtin_ccids(u8 **ccid_array, u8 *array_len)
+{
+       *ccid_array = kmemdup(builtin_ccids, sizeof(builtin_ccids), gfp_any());
+       if (*ccid_array == NULL)
+               return -ENOBUFS;
+       *array_len = ARRAY_SIZE(builtin_ccids);
+       return 0;
+}
+
+int ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
+                                   char __user *optval, int __user *optlen)
+{
+       if (len < sizeof(builtin_ccids))
+               return -EINVAL;
+
+       if (put_user(sizeof(builtin_ccids), optlen) ||
+           copy_to_user(optval, builtin_ccids, sizeof(builtin_ccids)))
+               return -EFAULT;
+       return 0;
+}
+
 int ccid_register(struct ccid_operations *ccid_ops)
 {
        int err = -ENOBUFS;
index fdeae7b5731950ed3caa776cf82a0d35f2771012..259f5469d7d04ceacf42d7ff07b260d76a26df1d 100644 (file)
@@ -103,6 +103,11 @@ static inline void *ccid_priv(const struct ccid *ccid)
        return (void *)ccid->ccid_priv;
 }
 
+extern bool ccid_support_check(u8 const *ccid_array, u8 array_len);
+extern int  ccid_get_builtin_ccids(u8 **ccid_array, u8 *array_len);
+extern int  ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
+                                         char __user *, int __user *);
+
 extern struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx,
                             gfp_t gfp);
 
index 9a430734530c6d8bd2079ca7c1662d03b221ad73..c9ea19a4d85e10b0ba8c5a2a4d8c27b2496bc79b 100644 (file)
@@ -25,7 +25,7 @@
 /*
  * This implementation should follow RFC 4341
  */
-
+#include "../feat.h"
 #include "../ccid.h"
 #include "../dccp.h"
 #include "ccid2.h"
@@ -147,8 +147,8 @@ static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val)
                DCCP_WARN("Limiting Ack Ratio (%u) to %u\n", val, max_ratio);
                val = max_ratio;
        }
-       if (val > 0xFFFF)               /* RFC 4340, 11.3 */
-               val = 0xFFFF;
+       if (val > DCCPF_ACK_RATIO_MAX)
+               val = DCCPF_ACK_RATIO_MAX;
 
        if (val == dp->dccps_l_ack_ratio)
                return;
index b4bc6e095a0e5b367275582ce4ab4e78823e3a84..031ce350d3c1b97867e5cf53988312bc2f122d27 100644 (file)
@@ -98,7 +98,6 @@ extern int  sysctl_dccp_retries2;
 extern int  sysctl_dccp_feat_sequence_window;
 extern int  sysctl_dccp_feat_rx_ccid;
 extern int  sysctl_dccp_feat_tx_ccid;
-extern int  sysctl_dccp_feat_ack_ratio;
 extern int  sysctl_dccp_feat_send_ack_vector;
 extern int  sysctl_dccp_feat_send_ndp_count;
 extern int  sysctl_dccp_tx_qlen;
@@ -252,7 +251,8 @@ extern const char *dccp_state_name(const int state);
 extern void dccp_set_state(struct sock *sk, const int state);
 extern void dccp_done(struct sock *sk);
 
-extern void dccp_reqsk_init(struct request_sock *req, struct sk_buff *skb);
+extern int  dccp_reqsk_init(struct request_sock *rq, struct dccp_sock const *dp,
+                           struct sk_buff const *skb);
 
 extern int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb);
 
@@ -441,6 +441,10 @@ static inline int dccp_ack_pending(const struct sock *sk)
               inet_csk_ack_scheduled(sk);
 }
 
+extern int  dccp_feat_finalise_settings(struct dccp_sock *dp);
+extern int  dccp_feat_server_ccid_dependencies(struct dccp_request_sock *dreq);
+extern void dccp_feat_list_purge(struct list_head *fn_list);
+
 extern int dccp_insert_options(struct sock *sk, struct sk_buff *skb);
 extern int dccp_insert_options_rsk(struct dccp_request_sock*, struct sk_buff*);
 extern int dccp_insert_option_elapsed_time(struct sock *sk,
index 933a0ecf8d463b0649fd69f78335533d86950517..47ce9abaf72b8a5d652120e70e957a2b020efc20 100644 (file)
@@ -6,6 +6,8 @@
  *
  *  ASSUMPTIONS
  *  -----------
+ *  o Feature negotiation is coordinated with connection setup (as in TCP), wild
+ *    changes of parameters of an established connection are not supported.
  *  o All currently known SP features have 1-byte quantities. If in the future
  *    extensions of RFCs 4340..42 define features with item lengths larger than
  *    one byte, a feature-specific extension of the code will be required.
 
 #define DCCP_FEAT_SP_NOAGREE (-123)
 
-int dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature,
-                    u8 *val, u8 len, gfp_t gfp)
+static const struct {
+       u8                      feat_num;               /* DCCPF_xxx */
+       enum dccp_feat_type     rxtx;                   /* RX or TX  */
+       enum dccp_feat_type     reconciliation;         /* SP or NN  */
+       u8                      default_value;          /* as in 6.4 */
+/*
+ *    Lookup table for location and type of features (from RFC 4340/4342)
+ *  +--------------------------+----+-----+----+----+---------+-----------+
+ *  | Feature                  | Location | Reconc. | Initial |  Section  |
+ *  |                          | RX | TX  | SP | NN |  Value  | Reference |
+ *  +--------------------------+----+-----+----+----+---------+-----------+
+ *  | DCCPF_CCID               |    |  X  | X  |    |   2     | 10        |
+ *  | DCCPF_SHORT_SEQNOS       |    |  X  | X  |    |   0     |  7.6.1    |
+ *  | DCCPF_SEQUENCE_WINDOW    |    |  X  |    | X  | 100     |  7.5.2    |
+ *  | DCCPF_ECN_INCAPABLE      | X  |     | X  |    |   0     | 12.1      |
+ *  | DCCPF_ACK_RATIO          |    |  X  |    | X  |   2     | 11.3      |
+ *  | DCCPF_SEND_ACK_VECTOR    | X  |     | X  |    |   0     | 11.5      |
+ *  | DCCPF_SEND_NDP_COUNT     |    |  X  | X  |    |   0     |  7.7.2    |
+ *  | DCCPF_MIN_CSUM_COVER     | X  |     | X  |    |   0     |  9.2.1    |
+ *  | DCCPF_DATA_CHECKSUM      | X  |     | X  |    |   0     |  9.3.1    |
+ *  | DCCPF_SEND_LEV_RATE      | X  |     | X  |    |   0     | 4342/8.4  |
+ *  +--------------------------+----+-----+----+----+---------+-----------+
+ */
+} dccp_feat_table[] = {
+       { DCCPF_CCID,            FEAT_AT_TX, FEAT_SP, 2 },
+       { DCCPF_SHORT_SEQNOS,    FEAT_AT_TX, FEAT_SP, 0 },
+       { DCCPF_SEQUENCE_WINDOW, FEAT_AT_TX, FEAT_NN, 100 },
+       { DCCPF_ECN_INCAPABLE,   FEAT_AT_RX, FEAT_SP, 0 },
+       { DCCPF_ACK_RATIO,       FEAT_AT_TX, FEAT_NN, 2 },
+       { DCCPF_SEND_ACK_VECTOR, FEAT_AT_RX, FEAT_SP, 0 },
+       { DCCPF_SEND_NDP_COUNT,  FEAT_AT_TX, FEAT_SP, 0 },
+       { DCCPF_MIN_CSUM_COVER,  FEAT_AT_RX, FEAT_SP, 0 },
+       { DCCPF_DATA_CHECKSUM,   FEAT_AT_RX, FEAT_SP, 0 },
+       { DCCPF_SEND_LEV_RATE,   FEAT_AT_RX, FEAT_SP, 0 },
+};
+#define DCCP_FEAT_SUPPORTED_MAX                ARRAY_SIZE(dccp_feat_table)
+
+/**
+ * dccp_feat_index  -  Hash function to map feature number into array position
+ * Returns consecutive array index or -1 if the feature is not understood.
+ */
+static int dccp_feat_index(u8 feat_num)
 {
-       struct dccp_opt_pend *opt;
+       /* The first 9 entries are occupied by the types from RFC 4340, 6.4 */
+       if (feat_num > DCCPF_RESERVED && feat_num <= DCCPF_DATA_CHECKSUM)
+               return feat_num - 1;
 
-       dccp_feat_debug(type, feature, *val);
+       /*
+        * Other features: add cases for new feature types here after adding
+        * them to the above table.
+        */
+       switch (feat_num) {
+       case DCCPF_SEND_LEV_RATE:
+                       return DCCP_FEAT_SUPPORTED_MAX - 1;
+       }
+       return -1;
+}
 
-       if (len > 3) {
-               DCCP_WARN("invalid length %d\n", len);
-               return -EINVAL;
+static u8 dccp_feat_type(u8 feat_num)
+{
+       int idx = dccp_feat_index(feat_num);
+
+       if (idx < 0)
+               return FEAT_UNKNOWN;
+       return dccp_feat_table[idx].reconciliation;
+}
+
+static int dccp_feat_default_value(u8 feat_num)
+{
+       int idx = dccp_feat_index(feat_num);
+       /*
+        * There are no default values for unknown features, so encountering a
+        * negative index here indicates a serious problem somewhere else.
+        */
+       DCCP_BUG_ON(idx < 0);
+
+       return idx < 0 ? 0 : dccp_feat_table[idx].default_value;
+}
+
+/* copy constructor, fval must not already contain allocated memory */
+static int dccp_feat_clone_sp_val(dccp_feat_val *fval, u8 const *val, u8 len)
+{
+       fval->sp.len = len;
+       if (fval->sp.len > 0) {
+               fval->sp.vec = kmemdup(val, len, gfp_any());
+               if (fval->sp.vec == NULL) {
+                       fval->sp.len = 0;
+                       return -ENOBUFS;
+               }
        }
-       /* XXX add further sanity checks */
+       return 0;
+}
 
-       /* check if that feature is already being negotiated */
-       list_for_each_entry(opt, &dmsk->dccpms_pending, dccpop_node) {
-               /* ok we found a negotiation for this option already */
-               if (opt->dccpop_feat == feature && opt->dccpop_type == type) {
-                       dccp_pr_debug("Replacing old\n");
-                       /* replace */
-                       BUG_ON(opt->dccpop_val == NULL);
-                       kfree(opt->dccpop_val);
-                       opt->dccpop_val  = val;
-                       opt->dccpop_len  = len;
-                       opt->dccpop_conf = 0;
-                       return 0;
+static void dccp_feat_val_destructor(u8 feat_num, dccp_feat_val *val)
+{
+       if (unlikely(val == NULL))
+               return;
+       if (dccp_feat_type(feat_num) == FEAT_SP)
+               kfree(val->sp.vec);
+       memset(val, 0, sizeof(*val));
+}
+
+static struct dccp_feat_entry *
+             dccp_feat_clone_entry(struct dccp_feat_entry const *original)
+{
+       struct dccp_feat_entry *new;
+       u8 type = dccp_feat_type(original->feat_num);
+
+       if (type == FEAT_UNKNOWN)
+               return NULL;
+
+       new = kmemdup(original, sizeof(struct dccp_feat_entry), gfp_any());
+       if (new == NULL)
+               return NULL;
+
+       if (type == FEAT_SP && dccp_feat_clone_sp_val(&new->val,
+                                                     original->val.sp.vec,
+                                                     original->val.sp.len)) {
+               kfree(new);
+               return NULL;
+       }
+       return new;
+}
+
+static void dccp_feat_entry_destructor(struct dccp_feat_entry *entry)
+{
+       if (entry != NULL) {
+               dccp_feat_val_destructor(entry->feat_num, &entry->val);
+               kfree(entry);
+       }
+}
+
+/*
+ * List management functions
+ *
+ * Feature negotiation lists rely on and maintain the following invariants:
+ * - each feat_num in the list is known, i.e. we know its type and default value
+ * - each feat_num/is_local combination is unique (old entries are overwritten)
+ * - SP values are always freshly allocated
+ * - list is sorted in increasing order of feature number (faster lookup)
+ */
+static struct dccp_feat_entry *dccp_feat_list_lookup(struct list_head *fn_list,
+                                                    u8 feat_num, bool is_local)
+{
+       struct dccp_feat_entry *entry;
+
+       list_for_each_entry(entry, fn_list, node)
+               if (entry->feat_num == feat_num && entry->is_local == is_local)
+                       return entry;
+               else if (entry->feat_num > feat_num)
+                       break;
+       return NULL;
+}
+
+/**
+ * dccp_feat_entry_new  -  Central list update routine (called by all others)
+ * @head:  list to add to
+ * @feat:  feature number
+ * @local: whether the local (1) or remote feature with number @feat is meant
+ * This is the only constructor and serves to ensure the above invariants.
+ */
+static struct dccp_feat_entry *
+             dccp_feat_entry_new(struct list_head *head, u8 feat, bool local)
+{
+       struct dccp_feat_entry *entry;
+
+       list_for_each_entry(entry, head, node)
+               if (entry->feat_num == feat && entry->is_local == local) {
+                       dccp_feat_val_destructor(entry->feat_num, &entry->val);
+                       return entry;
+               } else if (entry->feat_num > feat) {
+                       head = &entry->node;
+                       break;
                }
+
+       entry = kmalloc(sizeof(*entry), gfp_any());
+       if (entry != NULL) {
+               entry->feat_num = feat;
+               entry->is_local = local;
+               list_add_tail(&entry->node, head);
        }
+       return entry;
+}
 
-       /* negotiation for a new feature */
-       opt = kmalloc(sizeof(*opt), gfp);
-       if (opt == NULL)
+/**
+ * dccp_feat_push_change  -  Add/overwrite a Change option in the list
+ * @fn_list: feature-negotiation list to update
+ * @feat: one of %dccp_feature_numbers
+ * @local: whether local (1) or remote (0) @feat_num is meant
+ * @needs_mandatory: whether to use Mandatory feature negotiation options
+ * @fval: pointer to NN/SP value to be inserted (will be copied)
+ */
+static int dccp_feat_push_change(struct list_head *fn_list, u8 feat, u8 local,
+                                u8 mandatory, dccp_feat_val *fval)
+{
+       struct dccp_feat_entry *new = dccp_feat_entry_new(fn_list, feat, local);
+
+       if (new == NULL)
                return -ENOMEM;
 
-       opt->dccpop_type = type;
-       opt->dccpop_feat = feature;
-       opt->dccpop_len  = len;
-       opt->dccpop_val  = val;
-       opt->dccpop_conf = 0;
-       opt->dccpop_sc   = NULL;
+       new->feat_num        = feat;
+       new->is_local        = local;
+       new->state           = FEAT_INITIALISING;
+       new->needs_confirm   = 0;
+       new->empty_confirm   = 0;
+       new->val             = *fval;
+       new->needs_mandatory = mandatory;
 
-       BUG_ON(opt->dccpop_val == NULL);
+       return 0;
+}
+
+static inline void dccp_feat_list_pop(struct dccp_feat_entry *entry)
+{
+       list_del(&entry->node);
+       dccp_feat_entry_destructor(entry);
+}
+
+void dccp_feat_list_purge(struct list_head *fn_list)
+{
+       struct dccp_feat_entry *entry, *next;
+
+       list_for_each_entry_safe(entry, next, fn_list, node)
+               dccp_feat_entry_destructor(entry);
+       INIT_LIST_HEAD(fn_list);
+}
+EXPORT_SYMBOL_GPL(dccp_feat_list_purge);
 
-       list_add_tail(&opt->dccpop_node, &dmsk->dccpms_pending);
+/* generate @to as full clone of @from - @to must not contain any nodes */
+int dccp_feat_clone_list(struct list_head const *from, struct list_head *to)
+{
+       struct dccp_feat_entry *entry, *new;
+
+       INIT_LIST_HEAD(to);
+       list_for_each_entry(entry, from, node) {
+               new = dccp_feat_clone_entry(entry);
+               if (new == NULL)
+                       goto cloning_failed;
+               list_add_tail(&new->node, to);
+       }
        return 0;
+
+cloning_failed:
+       dccp_feat_list_purge(to);
+       return -ENOMEM;
+}
+
+static u8 dccp_feat_is_valid_nn_val(u8 feat_num, u64 val)
+{
+       switch (feat_num) {
+       case DCCPF_ACK_RATIO:
+               return val <= DCCPF_ACK_RATIO_MAX;
+       case DCCPF_SEQUENCE_WINDOW:
+               return val >= DCCPF_SEQ_WMIN && val <= DCCPF_SEQ_WMAX;
+       }
+       return 0;       /* feature unknown - so we can't tell */
 }
 
-EXPORT_SYMBOL_GPL(dccp_feat_change);
+/* check that SP values are within the ranges defined in RFC 4340 */
+static u8 dccp_feat_is_valid_sp_val(u8 feat_num, u8 val)
+{
+       switch (feat_num) {
+       case DCCPF_CCID:
+               return val == DCCPC_CCID2 || val == DCCPC_CCID3;
+       /* Type-check Boolean feature values: */
+       case DCCPF_SHORT_SEQNOS:
+       case DCCPF_ECN_INCAPABLE:
+       case DCCPF_SEND_ACK_VECTOR:
+       case DCCPF_SEND_NDP_COUNT:
+       case DCCPF_DATA_CHECKSUM:
+       case DCCPF_SEND_LEV_RATE:
+               return val < 2;
+       case DCCPF_MIN_CSUM_COVER:
+               return val < 16;
+       }
+       return 0;                       /* feature unknown */
+}
+
+static u8 dccp_feat_sp_list_ok(u8 feat_num, u8 const *sp_list, u8 sp_len)
+{
+       if (sp_list == NULL || sp_len < 1)
+               return 0;
+       while (sp_len--)
+               if (!dccp_feat_is_valid_sp_val(feat_num, *sp_list++))
+                       return 0;
+       return 1;
+}
+
+/**
+ * __feat_register_nn  -  Register new NN value on socket
+ * @fn: feature-negotiation list to register with
+ * @feat: an NN feature from %dccp_feature_numbers
+ * @mandatory: use Mandatory option if 1
+ * @nn_val: value to register (restricted to 4 bytes)
+ * Note that NN features are local by definition (RFC 4340, 6.3.2).
+ */
+static int __feat_register_nn(struct list_head *fn, u8 feat,
+                             u8 mandatory, u64 nn_val)
+{
+       dccp_feat_val fval = { .nn = nn_val };
+
+       if (dccp_feat_type(feat) != FEAT_NN ||
+           !dccp_feat_is_valid_nn_val(feat, nn_val))
+               return -EINVAL;
+
+       /* Don't bother with default values, they will be activated anyway. */
+       if (nn_val - (u64)dccp_feat_default_value(feat) == 0)
+               return 0;
+
+       return dccp_feat_push_change(fn, feat, 1, mandatory, &fval);
+}
+
+/**
+ * __feat_register_sp  -  Register new SP value/list on socket
+ * @fn: feature-negotiation list to register with
+ * @feat: an SP feature from %dccp_feature_numbers
+ * @is_local: whether the local (1) or the remote (0) @feat is meant
+ * @mandatory: use Mandatory option if 1
+ * @sp_val: SP value followed by optional preference list
+ * @sp_len: length of @sp_val in bytes
+ */
+static int __feat_register_sp(struct list_head *fn, u8 feat, u8 is_local,
+                             u8 mandatory, u8 const *sp_val, u8 sp_len)
+{
+       dccp_feat_val fval;
+
+       if (dccp_feat_type(feat) != FEAT_SP ||
+           !dccp_feat_sp_list_ok(feat, sp_val, sp_len))
+               return -EINVAL;
+
+       /* Avoid negotiating alien CCIDs by only advertising supported ones */
+       if (feat == DCCPF_CCID && !ccid_support_check(sp_val, sp_len))
+               return -EOPNOTSUPP;
+
+       if (dccp_feat_clone_sp_val(&fval, sp_val, sp_len))
+               return -ENOMEM;
+
+       return dccp_feat_push_change(fn, feat, is_local, mandatory, &fval);
+}
+
+/**
+ * dccp_feat_register_sp  -  Register requests to change SP feature values
+ * @sk: client or listening socket
+ * @feat: one of %dccp_feature_numbers
+ * @is_local: whether the local (1) or remote (0) @feat is meant
+ * @list: array of preferred values, in descending order of preference
+ * @len: length of @list in bytes
+ */
+int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
+                         u8 const *list, u8 len)
+{       /* any changes must be registered before establishing the connection */
+       if (sk->sk_state != DCCP_CLOSED)
+               return -EISCONN;
+       if (dccp_feat_type(feat) != FEAT_SP)
+               return -EINVAL;
+       return __feat_register_sp(&dccp_sk(sk)->dccps_featneg, feat, is_local,
+                                 0, list, len);
+}
+
+/* Analogous to dccp_feat_register_sp(), but for non-negotiable values */
+int dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val)
+{
+       /* any changes must be registered before establishing the connection */
+       if (sk->sk_state != DCCP_CLOSED)
+               return -EISCONN;
+       if (dccp_feat_type(feat) != FEAT_NN)
+               return -EINVAL;
+       return __feat_register_nn(&dccp_sk(sk)->dccps_featneg, feat, 0, val);
+}
+
+/*
+ *     Tracking features whose value depend on the choice of CCID
+ *
+ * This is designed with an extension in mind so that a list walk could be done
+ * before activating any features. However, the existing framework was found to
+ * work satisfactorily up until now, the automatic verification is left open.
+ * When adding new CCIDs, add a corresponding dependency table here.
+ */
+static const struct ccid_dependency *dccp_feat_ccid_deps(u8 ccid, bool is_local)
+{
+       static const struct ccid_dependency ccid2_dependencies[2][2] = {
+               /*
+                * CCID2 mandates Ack Vectors (RFC 4341, 4.): as CCID is a TX
+                * feature and Send Ack Vector is an RX feature, `is_local'
+                * needs to be reversed.
+                */
+               {       /* Dependencies of the receiver-side (remote) CCID2 */
+                       {
+                               .dependent_feat = DCCPF_SEND_ACK_VECTOR,
+                               .is_local       = true,
+                               .is_mandatory   = true,
+                               .val            = 1
+                       },
+                       { 0, 0, 0, 0 }
+               },
+               {       /* Dependencies of the sender-side (local) CCID2 */
+                       {
+                               .dependent_feat = DCCPF_SEND_ACK_VECTOR,
+                               .is_local       = false,
+                               .is_mandatory   = true,
+                               .val            = 1
+                       },
+                       { 0, 0, 0, 0 }
+               }
+       };
+       static const struct ccid_dependency ccid3_dependencies[2][5] = {
+               {       /*
+                        * Dependencies of the receiver-side CCID3
+                        */
+                       {       /* locally disable Ack Vectors */
+                               .dependent_feat = DCCPF_SEND_ACK_VECTOR,
+                               .is_local       = true,
+                               .is_mandatory   = false,
+                               .val            = 0
+                       },
+                       {       /* see below why Send Loss Event Rate is on */
+                               .dependent_feat = DCCPF_SEND_LEV_RATE,
+                               .is_local       = true,
+                               .is_mandatory   = true,
+                               .val            = 1
+                       },
+                       {       /* NDP Count is needed as per RFC 4342, 6.1.1 */
+                               .dependent_feat = DCCPF_SEND_NDP_COUNT,
+                               .is_local       = false,
+                               .is_mandatory   = true,
+                               .val            = 1
+                       },
+                       { 0, 0, 0, 0 },
+               },
+               {       /*
+                        * CCID3 at the TX side: we request that the HC-receiver
+                        * will not send Ack Vectors (they will be ignored, so
+                        * Mandatory is not set); we enable Send Loss Event Rate
+                        * (Mandatory since the implementation does not support
+                        * the Loss Intervals option of RFC 4342, 8.6).
+                        * The last two options are for peer's information only.
+                       */
+                       {
+                               .dependent_feat = DCCPF_SEND_ACK_VECTOR,
+                               .is_local       = false,
+                               .is_mandatory   = false,
+                               .val            = 0
+                       },
+                       {
+                               .dependent_feat = DCCPF_SEND_LEV_RATE,
+                               .is_local       = false,
+                               .is_mandatory   = true,
+                               .val            = 1
+                       },
+                       {       /* this CCID does not support Ack Ratio */
+                               .dependent_feat = DCCPF_ACK_RATIO,
+                               .is_local       = true,
+                               .is_mandatory   = false,
+                               .val            = 0
+                       },
+                       {       /* tell receiver we are sending NDP counts */
+                               .dependent_feat = DCCPF_SEND_NDP_COUNT,
+                               .is_local       = true,
+                               .is_mandatory   = false,
+                               .val            = 1
+                       },
+                       { 0, 0, 0, 0 }
+               }
+       };
+       switch (ccid) {
+       case DCCPC_CCID2:
+               return ccid2_dependencies[is_local];
+       case DCCPC_CCID3:
+               return ccid3_dependencies[is_local];
+       default:
+               return NULL;
+       }
+}
+
+/**
+ * dccp_feat_propagate_ccid - Resolve dependencies of features on choice of CCID
+ * @fn: feature-negotiation list to update
+ * @id: CCID number to track
+ * @is_local: whether TX CCID (1) or RX CCID (0) is meant
+ * This function needs to be called after registering all other features.
+ */
+static int dccp_feat_propagate_ccid(struct list_head *fn, u8 id, bool is_local)
+{
+       const struct ccid_dependency *table = dccp_feat_ccid_deps(id, is_local);
+       int i, rc = (table == NULL);
+
+       for (i = 0; rc == 0 && table[i].dependent_feat != DCCPF_RESERVED; i++)
+               if (dccp_feat_type(table[i].dependent_feat) == FEAT_SP)
+                       rc = __feat_register_sp(fn, table[i].dependent_feat,
+                                                   table[i].is_local,
+                                                   table[i].is_mandatory,
+                                                   &table[i].val, 1);
+               else
+                       rc = __feat_register_nn(fn, table[i].dependent_feat,
+                                                   table[i].is_mandatory,
+                                                   table[i].val);
+       return rc;
+}
+
+/**
+ * dccp_feat_finalise_settings  -  Finalise settings before starting negotiation
+ * @dp: client or listening socket (settings will be inherited)
+ * This is called after all registrations (socket initialisation, sysctls, and
+ * sockopt calls), and before sending the first packet containing Change options
+ * (ie. client-Request or server-Response), to ensure internal consistency.
+ */
+int dccp_feat_finalise_settings(struct dccp_sock *dp)
+{
+       struct list_head *fn = &dp->dccps_featneg;
+       struct dccp_feat_entry *entry;
+       int i = 2, ccids[2] = { -1, -1 };
+
+       /*
+        * Propagating CCIDs:
+        * 1) not useful to propagate CCID settings if this host advertises more
+        *    than one CCID: the choice of CCID  may still change - if this is
+        *    the client, or if this is the server and the client sends
+        *    singleton CCID values.
+        * 2) since is that propagate_ccid changes the list, we defer changing
+        *    the sorted list until after the traversal.
+        */
+       list_for_each_entry(entry, fn, node)
+               if (entry->feat_num == DCCPF_CCID && entry->val.sp.len == 1)
+                       ccids[entry->is_local] = entry->val.sp.vec[0];
+       while (i--)
+               if (ccids[i] > 0 && dccp_feat_propagate_ccid(fn, ccids[i], i))
+                       return -1;
+       return 0;
+}
+
+/**
+ * dccp_feat_server_ccid_dependencies  -  Resolve CCID-dependent features
+ * It is the server which resolves the dependencies once the CCID has been
+ * fully negotiated. If no CCID has been negotiated, it uses the default CCID.
+ */
+int dccp_feat_server_ccid_dependencies(struct dccp_request_sock *dreq)
+{
+       struct list_head *fn = &dreq->dreq_featneg;
+       struct dccp_feat_entry *entry;
+       u8 is_local, ccid;
+
+       for (is_local = 0; is_local <= 1; is_local++) {
+               entry = dccp_feat_list_lookup(fn, DCCPF_CCID, is_local);
+
+               if (entry != NULL && !entry->empty_confirm)
+                       ccid = entry->val.sp.vec[0];
+               else
+                       ccid = dccp_feat_default_value(DCCPF_CCID);
+
+               if (dccp_feat_propagate_ccid(fn, ccid, is_local))
+                       return -1;
+       }
+       return 0;
+}
 
 static int dccp_feat_update_ccid(struct sock *sk, u8 type, u8 new_ccid_nr)
 {
@@ -377,6 +885,9 @@ int dccp_feat_change_recv(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
 {
        int rc;
 
+       /* Ignore Change requests other than during connection setup */
+       if (sk->sk_state != DCCP_LISTEN && sk->sk_state != DCCP_REQUESTING)
+               return 0;
        dccp_feat_debug(type, feature, *val);
 
        /* figure out if it's SP or NN feature */
@@ -426,6 +937,9 @@ int dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
        int found = 0;
        int all_confirmed = 1;
 
+       /* Ignore Confirm options other than during connection setup */
+       if (sk->sk_state != DCCP_LISTEN && sk->sk_state != DCCP_REQUESTING)
+               return 0;
        dccp_feat_debug(type, feature, *val);
 
        /* locate our change request */
@@ -460,17 +974,6 @@ int dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
                        all_confirmed = 0;
        }
 
-       /* fix re-transmit timer */
-       /* XXX gotta make sure that no option negotiation occurs during
-        * connection shutdown.  Consider that the CLOSEREQ is sent and timer is
-        * on.  if all options are confirmed it might kill timer which should
-        * remain alive until close is received.
-        */
-       if (all_confirmed) {
-               dccp_pr_debug("clear feat negotiation timer %p\n", sk);
-               inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
-       }
-
        if (!found)
                dccp_pr_debug("%s(%d, ...) never requested\n",
                              dccp_feat_typename(type), feature);
@@ -564,42 +1067,30 @@ out_clean:
 
 EXPORT_SYMBOL_GPL(dccp_feat_clone);
 
-static int __dccp_feat_init(struct dccp_minisock *dmsk, u8 type, u8 feat,
-                           u8 *val, u8 len)
-{
-       int rc = -ENOMEM;
-       u8 *copy = kmemdup(val, len, GFP_KERNEL);
-
-       if (copy != NULL) {
-               rc = dccp_feat_change(dmsk, type, feat, copy, len, GFP_KERNEL);
-               if (rc)
-                       kfree(copy);
-       }
-       return rc;
-}
-
-int dccp_feat_init(struct dccp_minisock *dmsk)
+int dccp_feat_init(struct sock *sk)
 {
+       struct dccp_sock *dp = dccp_sk(sk);
+       struct dccp_minisock *dmsk = dccp_msk(sk);
        int rc;
 
-       INIT_LIST_HEAD(&dmsk->dccpms_pending);
-       INIT_LIST_HEAD(&dmsk->dccpms_conf);
+       INIT_LIST_HEAD(&dmsk->dccpms_pending);  /* XXX no longer used */
+       INIT_LIST_HEAD(&dmsk->dccpms_conf);     /* XXX no longer used */
 
        /* CCID L */
-       rc = __dccp_feat_init(dmsk, DCCPO_CHANGE_L, DCCPF_CCID,
-                             &dmsk->dccpms_tx_ccid, 1);
+       rc = __feat_register_sp(&dp->dccps_featneg, DCCPF_CCID, 1, 0,
+                               &dmsk->dccpms_tx_ccid, 1);
        if (rc)
                goto out;
 
        /* CCID R */
-       rc = __dccp_feat_init(dmsk, DCCPO_CHANGE_R, DCCPF_CCID,
-                             &dmsk->dccpms_rx_ccid, 1);
+       rc = __feat_register_sp(&dp->dccps_featneg, DCCPF_CCID, 0, 0,
+                               &dmsk->dccpms_rx_ccid, 1);
        if (rc)
                goto out;
 
        /* Ack ratio */
-       rc = __dccp_feat_init(dmsk, DCCPO_CHANGE_L, DCCPF_ACK_RATIO,
-                             &dmsk->dccpms_ack_ratio, 1);
+       rc = __feat_register_nn(&dp->dccps_featneg, DCCPF_ACK_RATIO, 0,
+                               dp->dccps_l_ack_ratio);
 out:
        return rc;
 }
@@ -639,6 +1130,8 @@ const char *dccp_feat_name(const u8 feat)
        if (feat > DCCPF_DATA_CHECKSUM && feat < DCCPF_MIN_CCID_SPECIFIC)
                return feature_names[DCCPF_RESERVED];
 
+       if (feat ==  DCCPF_SEND_LEV_RATE)
+               return "Send Loss Event Rate";
        if (feat >= DCCPF_MIN_CCID_SPECIFIC)
                return "CCID-specific";
 
index e272222c7ace353951cf5cade968a54663a5e443..4d172822df178c8e8a8a0e5064d805ae6c0db6db 100644 (file)
 #include <linux/types.h>
 #include "dccp.h"
 
+/*
+ * Known limit values
+ */
+/* Ack Ratio takes 2-byte integer values (11.3) */
+#define DCCPF_ACK_RATIO_MAX    0xFFFF
+/* Wmin=32 and Wmax=2^46-1 from 7.5.2 */
+#define DCCPF_SEQ_WMIN         32
+#define DCCPF_SEQ_WMAX         0x3FFFFFFFFFFFull
+
+enum dccp_feat_type {
+       FEAT_AT_RX   = 1,       /* located at RX side of half-connection  */
+       FEAT_AT_TX   = 2,       /* located at TX side of half-connection  */
+       FEAT_SP      = 4,       /* server-priority reconciliation (6.3.1) */
+       FEAT_NN      = 8,       /* non-negotiable reconciliation (6.3.2)  */
+       FEAT_UNKNOWN = 0xFF     /* not understood or invalid feature      */
+};
+
+enum dccp_feat_state {
+       FEAT_DEFAULT = 0,       /* using default values from 6.4 */
+       FEAT_INITIALISING,      /* feature is being initialised  */
+       FEAT_CHANGING,          /* Change sent but not confirmed yet */
+       FEAT_UNSTABLE,          /* local modification in state CHANGING */
+       FEAT_STABLE             /* both ends (think they) agree */
+};
+
+/**
+ * dccp_feat_val  -  Container for SP or NN feature values
+ * @nn:     single NN value
+ * @sp.vec: single SP value plus optional preference list
+ * @sp.len: length of @sp.vec in bytes
+ */
+typedef union {
+       u64 nn;
+       struct {
+               u8      *vec;
+               u8      len;
+       }   sp;
+} dccp_feat_val;
+
+/**
+ * struct feat_entry  -  Data structure to perform feature negotiation
+ * @val: feature's current value (SP features may have preference list)
+ * @state: feature's current state
+ * @feat_num: one of %dccp_feature_numbers
+ * @needs_mandatory: whether Mandatory options should be sent
+ * @needs_confirm: whether to send a Confirm instead of a Change
+ * @empty_confirm: whether to send an empty Confirm (depends on @needs_confirm)
+ * @is_local: feature location (1) or feature-remote (0)
+ * @node: list pointers, entries arranged in FIFO order
+ */
+struct dccp_feat_entry {
+       dccp_feat_val           val;
+       enum dccp_feat_state    state:8;
+       u8                      feat_num;
+
+       bool                    needs_mandatory,
+                               needs_confirm,
+                               empty_confirm,
+                               is_local;
+
+       struct list_head        node;
+};
+
+static inline u8 dccp_feat_genopt(struct dccp_feat_entry *entry)
+{
+       if (entry->needs_confirm)
+               return entry->is_local ? DCCPO_CONFIRM_L : DCCPO_CONFIRM_R;
+       return entry->is_local ? DCCPO_CHANGE_L : DCCPO_CHANGE_R;
+}
+
+/**
+ * struct ccid_dependency  -  Track changes resulting from choosing a CCID
+ * @dependent_feat: one of %dccp_feature_numbers
+ * @is_local: local (1) or remote (0) @dependent_feat
+ * @is_mandatory: whether presence of @dependent_feat is mission-critical or not
+ * @val: corresponding default value for @dependent_feat (u8 is sufficient here)
+ */
+struct ccid_dependency {
+       u8      dependent_feat;
+       bool    is_local:1,
+               is_mandatory:1;
+       u8      val;
+};
+
 #ifdef CONFIG_IP_DCCP_DEBUG
 extern const char *dccp_feat_typename(const u8 type);
 extern const char *dccp_feat_name(const u8 feat);
@@ -27,14 +111,16 @@ static inline void dccp_feat_debug(const u8 type, const u8 feat, const u8 val)
 #define dccp_feat_debug(type, feat, val)
 #endif /* CONFIG_IP_DCCP_DEBUG */
 
-extern int  dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature,
-                            u8 *val, u8 len, gfp_t gfp);
+extern int  dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
+                                 u8 const *list, u8 len);
+extern int  dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val);
 extern int  dccp_feat_change_recv(struct sock *sk, u8 type, u8 feature,
                                  u8 *val, u8 len);
 extern int  dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
                                   u8 *val, u8 len);
 extern void dccp_feat_clean(struct dccp_minisock *dmsk);
 extern int  dccp_feat_clone(struct sock *oldsk, struct sock *newsk);
-extern int  dccp_feat_init(struct dccp_minisock *dmsk);
+extern int  dccp_feat_clone_list(struct list_head const *, struct list_head *);
+extern int  dccp_feat_init(struct sock *sk);
 
 #endif /* _DCCP_FEAT_H */
index 779d0ed9ae94420149ef44cf8ad14fb7f8799ca4..3070015edc7535fc5c299c0b0a9f00c8af99d9dd 100644 (file)
@@ -590,8 +590,6 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                        if (inet_csk(sk)->icsk_af_ops->conn_request(sk,
                                                                    skb) < 0)
                                return 1;
-
-                       /* FIXME: do congestion control initialization */
                        goto discard;
                }
                if (dh->dccph_type == DCCP_PKT_RESET)
index e3dfddab21cc233e929ff2a6cc81a7d3a4284ce2..d1dd95289b8960bd1556e3cecbd025b4bb83ca8e 100644 (file)
@@ -545,6 +545,7 @@ out:
 
 static void dccp_v4_reqsk_destructor(struct request_sock *req)
 {
+       dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg);
        kfree(inet_rsk(req)->opt);
 }
 
@@ -595,7 +596,8 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
        if (req == NULL)
                goto drop;
 
-       dccp_reqsk_init(req, skb);
+       if (dccp_reqsk_init(req, dccp_sk(sk), skb))
+               goto drop_and_free;
 
        dreq = dccp_rsk(req);
        if (dccp_parse_options(sk, dreq, skb))
@@ -792,12 +794,10 @@ static int dccp_v4_rcv(struct sk_buff *skb)
        DCCP_SKB_CB(skb)->dccpd_seq  = dccp_hdr_seq(dh);
        DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type;
 
-       dccp_pr_debug("%8.8s "
-                     "src=%u.%u.%u.%u@%-5d "
-                     "dst=%u.%u.%u.%u@%-5d seq=%llu",
+       dccp_pr_debug("%8.8s src=%pI4@%-5d dst=%pI4@%-5d seq=%llu",
                      dccp_packet_name(dh->dccph_type),
-                     NIPQUAD(iph->saddr), ntohs(dh->dccph_sport),
-                     NIPQUAD(iph->daddr), ntohs(dh->dccph_dport),
+                     &iph->saddr, ntohs(dh->dccph_sport),
+                     &iph->daddr, ntohs(dh->dccph_dport),
                      (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq);
 
        if (dccp_packet_without_ack(skb)) {
@@ -938,6 +938,7 @@ static struct proto dccp_v4_prot = {
        .orphan_count           = &dccp_orphan_count,
        .max_header             = MAX_DCCP_HEADER,
        .obj_size               = sizeof(struct dccp_sock),
+       .slab_flags             = SLAB_DESTROY_BY_RCU,
        .rsk_prot               = &dccp_request_sock_ops,
        .twsk_prot              = &dccp_timewait_sock_ops,
        .h.hashinfo             = &dccp_hashinfo,
index d4ce1224e008f13ee4da674cec0c6047a3a9f25f..f033e845bb076aa2c911e7ccac4bcb8dc1f46856 100644 (file)
@@ -304,6 +304,7 @@ done:
 
 static void dccp_v6_reqsk_destructor(struct request_sock *req)
 {
+       dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg);
        if (inet6_rsk(req)->pktopts != NULL)
                kfree_skb(inet6_rsk(req)->pktopts);
 }
@@ -426,7 +427,8 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        if (req == NULL)
                goto drop;
 
-       dccp_reqsk_init(req, skb);
+       if (dccp_reqsk_init(req, dccp_sk(sk), skb))
+               goto drop_and_free;
 
        dreq = dccp_rsk(req);
        if (dccp_parse_options(sk, dreq, skb))
@@ -1138,6 +1140,7 @@ static struct proto dccp_v6_prot = {
        .orphan_count      = &dccp_orphan_count,
        .max_header        = MAX_DCCP_HEADER,
        .obj_size          = sizeof(struct dccp6_sock),
+       .slab_flags        = SLAB_DESTROY_BY_RCU,
        .rsk_prot          = &dccp6_request_sock_ops,
        .twsk_prot         = &dccp6_timewait_sock_ops,
        .h.hashinfo        = &dccp_hashinfo,
index e6bf99e3e41a169aec04880e52d60adb41dc8b62..ed61bc58e41eaee79002c53ce0d3a43c0e068976 100644 (file)
@@ -47,7 +47,6 @@ void dccp_minisock_init(struct dccp_minisock *dmsk)
        dmsk->dccpms_sequence_window = sysctl_dccp_feat_sequence_window;
        dmsk->dccpms_rx_ccid         = sysctl_dccp_feat_rx_ccid;
        dmsk->dccpms_tx_ccid         = sysctl_dccp_feat_tx_ccid;
-       dmsk->dccpms_ack_ratio       = sysctl_dccp_feat_ack_ratio;
        dmsk->dccpms_send_ack_vector = sysctl_dccp_feat_send_ack_vector;
        dmsk->dccpms_send_ndp_count  = sysctl_dccp_feat_send_ndp_count;
 }
@@ -125,6 +124,7 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
                newdp->dccps_timestamp_time = dreq->dreq_timestamp_time;
                newicsk->icsk_rto           = DCCP_TIMEOUT_INIT;
 
+               INIT_LIST_HEAD(&newdp->dccps_featneg);
                if (dccp_feat_clone(sk, newsk))
                        goto out_free;
 
@@ -304,7 +304,8 @@ void dccp_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
 
 EXPORT_SYMBOL_GPL(dccp_reqsk_send_ack);
 
-void dccp_reqsk_init(struct request_sock *req, struct sk_buff *skb)
+int dccp_reqsk_init(struct request_sock *req,
+                   struct dccp_sock const *dp, struct sk_buff const *skb)
 {
        struct dccp_request_sock *dreq = dccp_rsk(req);
 
@@ -313,6 +314,9 @@ void dccp_reqsk_init(struct request_sock *req, struct sk_buff *skb)
        inet_rsk(req)->acked      = 0;
        req->rcv_wnd              = sysctl_dccp_feat_sequence_window;
        dreq->dreq_timestamp_echo = 0;
+
+       /* inherit feature negotiation options from listening socket */
+       return dccp_feat_clone_list(&dp->dccps_featneg, &dreq->dreq_featneg);
 }
 
 EXPORT_SYMBOL_GPL(dccp_reqsk_init);
index 0809b63cb055a204a0eccbb05d28af88d73ef022..515ad45013adc1baaf1f6a09f00c7884f6b04925 100644 (file)
@@ -26,7 +26,6 @@
 int sysctl_dccp_feat_sequence_window = DCCPF_INITIAL_SEQUENCE_WINDOW;
 int sysctl_dccp_feat_rx_ccid         = DCCPF_INITIAL_CCID;
 int sysctl_dccp_feat_tx_ccid         = DCCPF_INITIAL_CCID;
-int sysctl_dccp_feat_ack_ratio       = DCCPF_INITIAL_ACK_RATIO;
 int sysctl_dccp_feat_send_ack_vector = DCCPF_INITIAL_SEND_ACK_VECTOR;
 int sysctl_dccp_feat_send_ndp_count  = DCCPF_INITIAL_SEND_NDP_COUNT;
 
@@ -489,7 +488,6 @@ static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat,
 
 static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb)
 {
-       struct dccp_sock *dp = dccp_sk(sk);
        struct dccp_minisock *dmsk = dccp_msk(sk);
        struct dccp_opt_pend *opt, *next;
        int change = 0;
@@ -530,23 +528,6 @@ static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb)
                }
        }
 
-       /* Retransmit timer.
-        * If this is the master listening sock, we don't set a timer on it.  It
-        * should be fine because if the dude doesn't receive our RESPONSE
-        * [which will contain the CHANGE] he will send another REQUEST which
-        * will "retrnasmit" the change.
-        */
-       if (change && dp->dccps_role != DCCP_ROLE_LISTEN) {
-               dccp_pr_debug("reset feat negotiation timer %p\n", sk);
-
-               /* XXX don't reset the timer on re-transmissions.  I.e. reset it
-                * only when sending new stuff i guess.  Currently the timer
-                * never backs off because on re-transmission it just resets it!
-                */
-               inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
-                                         inet_csk(sk)->icsk_rto, DCCP_RTO_MAX);
-       }
-
        return 0;
 }
 
index 809d803d5006ec6614821b9d0d48b63cf131a31f..fea30cdc0bee00af3096859e3c07cb1355c3745e 100644 (file)
@@ -339,10 +339,12 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
        DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
        DCCP_SKB_CB(skb)->dccpd_seq  = dreq->dreq_iss;
 
-       if (dccp_insert_options_rsk(dreq, skb)) {
-               kfree_skb(skb);
-               return NULL;
-       }
+       /* Resolve feature dependencies resulting from choice of CCID */
+       if (dccp_feat_server_ccid_dependencies(dreq))
+               goto response_failed;
+
+       if (dccp_insert_options_rsk(dreq, skb))
+               goto response_failed;
 
        /* Build and checksum header */
        dh = dccp_zeroed_hdr(skb, dccp_header_size);
@@ -363,6 +365,9 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
        inet_rsk(req)->acked = 1;
        DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
        return skb;
+response_failed:
+       kfree_skb(skb);
+       return NULL;
 }
 
 EXPORT_SYMBOL_GPL(dccp_make_response);
@@ -469,6 +474,10 @@ int dccp_connect(struct sock *sk)
        struct sk_buff *skb;
        struct inet_connection_sock *icsk = inet_csk(sk);
 
+       /* do not connect if feature negotiation setup fails */
+       if (dccp_feat_finalise_settings(dccp_sk(sk)))
+               return -EPROTO;
+
        dccp_connect_init(sk);
 
        skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation);
index 81368a7f5379c9907b88e64ac03fa5f23b7313f6..49ba8d5ec4b5285ecaaef6fe5e98586fcd1cef07 100644 (file)
@@ -86,18 +86,18 @@ static int jdccp_sendmsg(struct kiocb *iocb, struct sock *sk,
        if (port == 0 || ntohs(inet->dport) == port ||
            ntohs(inet->sport) == port) {
                if (hctx)
-                       printl("%d.%d.%d.%d:%u %d.%d.%d.%d:%u %d %d %d %d %u "
+                       printl("%pI4:%u %pI4:%u %d %d %d %d %u "
                               "%llu %llu %d\n",
-                              NIPQUAD(inet->saddr), ntohs(inet->sport),
-                              NIPQUAD(inet->daddr), ntohs(inet->dport), size,
+                              &inet->saddr, ntohs(inet->sport),
+                              &inet->daddr, ntohs(inet->dport), size,
                               hctx->ccid3hctx_s, hctx->ccid3hctx_rtt,
                               hctx->ccid3hctx_p, hctx->ccid3hctx_x_calc,
                               hctx->ccid3hctx_x_recv >> 6,
                               hctx->ccid3hctx_x >> 6, hctx->ccid3hctx_t_ipi);
                else
-                       printl("%d.%d.%d.%d:%u %d.%d.%d.%d:%u %d\n",
-                              NIPQUAD(inet->saddr), ntohs(inet->sport),
-                              NIPQUAD(inet->daddr), ntohs(inet->dport), size);
+                       printl("%pI4:%u %pI4:%u %d\n",
+                              &inet->saddr, ntohs(inet->sport),
+                              &inet->daddr, ntohs(inet->dport), size);
        }
 
        jprobe_return();
index d0bd34819761c0983074e54fbff360d0aed75963..bdf784c422b527c3cadf095761b7efb996f12eec 100644 (file)
@@ -193,6 +193,7 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
 
        dccp_init_xmit_timers(sk);
 
+       INIT_LIST_HEAD(&dp->dccps_featneg);
        /*
         * FIXME: We're hardcoding the CCID, and doing this at this point makes
         * the listening (master) sock get CCID control blocks, which is not
@@ -201,7 +202,7 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
         * setsockopt(CCIDs-I-want/accept). -acme
         */
        if (likely(ctl_sock_initialized)) {
-               int rc = dccp_feat_init(dmsk);
+               int rc = dccp_feat_init(sk);
 
                if (rc)
                        return rc;
@@ -267,7 +268,7 @@ void dccp_destroy_sock(struct sock *sk)
        dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
 
        /* clean up feature negotiation state */
-       dccp_feat_clean(dmsk);
+       dccp_feat_list_purge(&dp->dccps_featneg);
 }
 
 EXPORT_SYMBOL_GPL(dccp_destroy_sock);
@@ -277,6 +278,9 @@ static inline int dccp_listen_start(struct sock *sk, int backlog)
        struct dccp_sock *dp = dccp_sk(sk);
 
        dp->dccps_role = DCCP_ROLE_LISTEN;
+       /* do not start to listen if feature negotiation setup fails */
+       if (dccp_feat_finalise_settings(dp))
+               return -EPROTO;
        return inet_csk_listen_start(sk, backlog);
 }
 
@@ -466,42 +470,40 @@ static int dccp_setsockopt_service(struct sock *sk, const __be32 service,
        return 0;
 }
 
-/* byte 1 is feature.  the rest is the preference list */
-static int dccp_setsockopt_change(struct sock *sk, int type,
-                                 struct dccp_so_feat __user *optval)
+static int dccp_setsockopt_cscov(struct sock *sk, int cscov, bool rx)
 {
-       struct dccp_so_feat opt;
-       u8 *val;
-       int rc;
+       u8 *list, len;
+       int i, rc;
 
-       if (copy_from_user(&opt, optval, sizeof(opt)))
-               return -EFAULT;
+       if (cscov < 0 || cscov > 15)
+               return -EINVAL;
        /*
-        * rfc4340: 6.1. Change Options
+        * Populate a list of permissible values, in the range cscov...15. This
+        * is necessary since feature negotiation of single values only works if
+        * both sides incidentally choose the same value. Since the list starts
+        * lowest-value first, negotiation will pick the smallest shared value.
         */
-       if (opt.dccpsf_len < 1)
-               return -EINVAL;
+       if (cscov == 0)
+               return 0;
+       len = 16 - cscov;
 
-       val = kmalloc(opt.dccpsf_len, GFP_KERNEL);
-       if (!val)
-               return -ENOMEM;
+       list = kmalloc(len, GFP_KERNEL);
+       if (list == NULL)
+               return -ENOBUFS;
 
-       if (copy_from_user(val, opt.dccpsf_val, opt.dccpsf_len)) {
-               rc = -EFAULT;
-               goto out_free_val;
-       }
+       for (i = 0; i < len; i++)
+               list[i] = cscov++;
 
-       rc = dccp_feat_change(dccp_msk(sk), type, opt.dccpsf_feat,
-                             val, opt.dccpsf_len, GFP_KERNEL);
-       if (rc)
-               goto out_free_val;
+       rc = dccp_feat_register_sp(sk, DCCPF_MIN_CSUM_COVER, rx, list, len);
 
-out:
+       if (rc == 0) {
+               if (rx)
+                       dccp_sk(sk)->dccps_pcrlen = cscov;
+               else
+                       dccp_sk(sk)->dccps_pcslen = cscov;
+       }
+       kfree(list);
        return rc;
-
-out_free_val:
-       kfree(val);
-       goto out;
 }
 
 static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
@@ -510,7 +512,17 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
        struct dccp_sock *dp = dccp_sk(sk);
        int val, err = 0;
 
-       if (optlen < sizeof(int))
+       switch (optname) {
+       case DCCP_SOCKOPT_PACKET_SIZE:
+               DCCP_WARN("sockopt(PACKET_SIZE) is deprecated: fix your app\n");
+               return 0;
+       case DCCP_SOCKOPT_CHANGE_L:
+       case DCCP_SOCKOPT_CHANGE_R:
+               DCCP_WARN("sockopt(CHANGE_L/R) is deprecated: fix your app\n");
+               return 0;
+       }
+
+       if (optlen < (int)sizeof(int))
                return -EINVAL;
 
        if (get_user(val, (int __user *)optval))
@@ -521,53 +533,24 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
 
        lock_sock(sk);
        switch (optname) {
-       case DCCP_SOCKOPT_PACKET_SIZE:
-               DCCP_WARN("sockopt(PACKET_SIZE) is deprecated: fix your app\n");
-               err = 0;
-               break;
-       case DCCP_SOCKOPT_CHANGE_L:
-               if (optlen != sizeof(struct dccp_so_feat))
-                       err = -EINVAL;
-               else
-                       err = dccp_setsockopt_change(sk, DCCPO_CHANGE_L,
-                                                    (struct dccp_so_feat __user *)
-                                                    optval);
-               break;
-       case DCCP_SOCKOPT_CHANGE_R:
-               if (optlen != sizeof(struct dccp_so_feat))
-                       err = -EINVAL;
-               else
-                       err = dccp_setsockopt_change(sk, DCCPO_CHANGE_R,
-                                                    (struct dccp_so_feat __user *)
-                                                    optval);
-               break;
        case DCCP_SOCKOPT_SERVER_TIMEWAIT:
                if (dp->dccps_role != DCCP_ROLE_SERVER)
                        err = -EOPNOTSUPP;
                else
                        dp->dccps_server_timewait = (val != 0);
                break;
-       case DCCP_SOCKOPT_SEND_CSCOV:   /* sender side, RFC 4340, sec. 9.2 */
-               if (val < 0 || val > 15)
-                       err = -EINVAL;
-               else
-                       dp->dccps_pcslen = val;
+       case DCCP_SOCKOPT_SEND_CSCOV:
+               err = dccp_setsockopt_cscov(sk, val, false);
                break;
-       case DCCP_SOCKOPT_RECV_CSCOV:   /* receiver side, RFC 4340 sec. 9.2.1 */
-               if (val < 0 || val > 15)
-                       err = -EINVAL;
-               else {
-                       dp->dccps_pcrlen = val;
-                       /* FIXME: add feature negotiation,
-                        * ChangeL(MinimumChecksumCoverage, val) */
-               }
+       case DCCP_SOCKOPT_RECV_CSCOV:
+               err = dccp_setsockopt_cscov(sk, val, true);
                break;
        default:
                err = -ENOPROTOOPT;
                break;
        }
-
        release_sock(sk);
+
        return err;
 }
 
@@ -648,6 +631,8 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
        case DCCP_SOCKOPT_GET_CUR_MPS:
                val = dp->dccps_mss_cache;
                break;
+       case DCCP_SOCKOPT_AVAILABLE_CCIDS:
+               return ccid_getsockopt_builtin_ccids(sk, len, optval, optlen);
        case DCCP_SOCKOPT_SERVER_TIMEWAIT:
                val = dp->dccps_server_timewait;
                break;
@@ -1084,8 +1069,8 @@ static int __init dccp_init(void)
        }
 
        for (i = 0; i < dccp_hashinfo.ehash_size; i++) {
-               INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].chain);
-               INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].twchain);
+               INIT_HLIST_NULLS_HEAD(&dccp_hashinfo.ehash[i].chain, i);
+               INIT_HLIST_NULLS_HEAD(&dccp_hashinfo.ehash[i].twchain, i);
        }
 
        if (inet_ehash_locks_alloc(&dccp_hashinfo))
index 21295993fdb84f2dd53dea972b137eb95395aca2..f6e54f433e29993a13c610cbba3b3902bb4005a0 100644 (file)
@@ -40,13 +40,6 @@ static struct ctl_table dccp_default_table[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
        },
-       {
-               .procname       = "ack_ratio",
-               .data           = &sysctl_dccp_feat_ack_ratio,
-               .maxlen         = sizeof(sysctl_dccp_feat_ack_ratio),
-               .mode           = 0644,
-               .proc_handler   = proc_dointvec,
-       },
        {
                .procname       = "send_ackvec",
                .data           = &sysctl_dccp_feat_send_ack_vector,
index 54b3c7e9e016737eab1614fde3b22afa67456345..162d1e683c3908afc76966353f51e5dc9f769de6 100644 (file)
@@ -87,17 +87,6 @@ static void dccp_retransmit_timer(struct sock *sk)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
 
-       /* retransmit timer is used for feature negotiation throughout
-        * connection.  In this case, no packet is re-transmitted, but rather an
-        * ack is generated and pending changes are placed into its options.
-        */
-       if (sk->sk_send_head == NULL) {
-               dccp_pr_debug("feat negotiation retransmit timeout %p\n", sk);
-               if (sk->sk_state == DCCP_OPEN)
-                       dccp_send_ack(sk);
-               goto backoff;
-       }
-
        /*
         * More than than 4MSL (8 minutes) has passed, a RESET(aborted) was
         * sent, no need to retransmit, this sock is dead.
@@ -126,7 +115,6 @@ static void dccp_retransmit_timer(struct sock *sk)
                return;
        }
 
-backoff:
        icsk->icsk_backoff++;
 
        icsk->icsk_rto = min(icsk->icsk_rto << 1, DCCP_RTO_MAX);
index 821bd1cdec04d23125cbe98ca893a329bf8d844d..768df000523b8dca25122e8eb8c4a98c09e9ec30 100644 (file)
@@ -131,7 +131,6 @@ static struct dst_ops dn_dst_ops = {
        .negative_advice =      dn_dst_negative_advice,
        .link_failure =         dn_dst_link_failure,
        .update_pmtu =          dn_dst_update_pmtu,
-       .entry_size =           sizeof(struct dn_route),
        .entries =              ATOMIC_INIT(0),
 };
 
index 36400b2668967c1bb5e4eab723837f78566641f8..2f360a1e5e49c6203f97b3de3673ff535efb24a8 100644 (file)
@@ -354,8 +354,8 @@ static ctl_table dn_table[] = {
                .data = node_name,
                .maxlen = 7,
                .mode = 0644,
-               .proc_handler = &proc_dostring,
-               .strategy = &sysctl_string,
+               .proc_handler = proc_dostring,
+               .strategy = sysctl_string,
        },
        {
                .ctl_name = NET_DECNET_DEFAULT_DEVICE,
@@ -371,8 +371,8 @@ static ctl_table dn_table[] = {
                .data = &decnet_time_wait,
                .maxlen = sizeof(int),
                .mode = 0644,
-               .proc_handler = &proc_dointvec_minmax,
-               .strategy = &sysctl_intvec,
+               .proc_handler = proc_dointvec_minmax,
+               .strategy = sysctl_intvec,
                .extra1 = &min_decnet_time_wait,
                .extra2 = &max_decnet_time_wait
        },
@@ -382,8 +382,8 @@ static ctl_table dn_table[] = {
                .data = &decnet_dn_count,
                .maxlen = sizeof(int),
                .mode = 0644,
-               .proc_handler = &proc_dointvec_minmax,
-               .strategy = &sysctl_intvec,
+               .proc_handler = proc_dointvec_minmax,
+               .strategy = sysctl_intvec,
                .extra1 = &min_state_count,
                .extra2 = &max_state_count
        },
@@ -393,8 +393,8 @@ static ctl_table dn_table[] = {
                .data = &decnet_di_count,
                .maxlen = sizeof(int),
                .mode = 0644,
-               .proc_handler = &proc_dointvec_minmax,
-               .strategy = &sysctl_intvec,
+               .proc_handler = proc_dointvec_minmax,
+               .strategy = sysctl_intvec,
                .extra1 = &min_state_count,
                .extra2 = &max_state_count
        },
@@ -404,8 +404,8 @@ static ctl_table dn_table[] = {
                .data = &decnet_dr_count,
                .maxlen = sizeof(int),
                .mode = 0644,
-               .proc_handler = &proc_dointvec_minmax,
-               .strategy = &sysctl_intvec,
+               .proc_handler = proc_dointvec_minmax,
+               .strategy = sysctl_intvec,
                .extra1 = &min_state_count,
                .extra2 = &max_state_count
        },
@@ -415,8 +415,8 @@ static ctl_table dn_table[] = {
                .data = &decnet_dst_gc_interval,
                .maxlen = sizeof(int),
                .mode = 0644,
-               .proc_handler = &proc_dointvec_minmax,
-               .strategy = &sysctl_intvec,
+               .proc_handler = proc_dointvec_minmax,
+               .strategy = sysctl_intvec,
                .extra1 = &min_decnet_dst_gc_interval,
                .extra2 = &max_decnet_dst_gc_interval
        },
@@ -426,8 +426,8 @@ static ctl_table dn_table[] = {
                .data = &decnet_no_fc_max_cwnd,
                .maxlen = sizeof(int),
                .mode = 0644,
-               .proc_handler = &proc_dointvec_minmax,
-               .strategy = &sysctl_intvec,
+               .proc_handler = proc_dointvec_minmax,
+               .strategy = sysctl_intvec,
                .extra1 = &min_decnet_no_fc_max_cwnd,
                .extra2 = &max_decnet_no_fc_max_cwnd
        },
@@ -437,8 +437,8 @@ static ctl_table dn_table[] = {
                .data = &sysctl_decnet_mem,
                .maxlen = sizeof(sysctl_decnet_mem),
                .mode = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
+               .proc_handler = proc_dointvec,
+               .strategy = sysctl_intvec,
        },
        {
                .ctl_name = NET_DECNET_RMEM,
@@ -446,8 +446,8 @@ static ctl_table dn_table[] = {
                .data = &sysctl_decnet_rmem,
                .maxlen = sizeof(sysctl_decnet_rmem),
                .mode = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
+               .proc_handler = proc_dointvec,
+               .strategy = sysctl_intvec,
        },
        {
                .ctl_name = NET_DECNET_WMEM,
@@ -455,8 +455,8 @@ static ctl_table dn_table[] = {
                .data = &sysctl_decnet_wmem,
                .maxlen = sizeof(sysctl_decnet_wmem),
                .mode = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
+               .proc_handler = proc_dointvec,
+               .strategy = sysctl_intvec,
        },
        {
                .ctl_name = NET_DECNET_DEBUG_LEVEL,
@@ -464,8 +464,8 @@ static ctl_table dn_table[] = {
                .data = &decnet_debug_level,
                .maxlen = sizeof(int),
                .mode = 0644,
-               .proc_handler = &proc_dointvec,
-               .strategy = &sysctl_intvec,
+               .proc_handler = proc_dointvec,
+               .strategy = sysctl_intvec,
        },
        {0}
 };
index 1af5a79309e9c2b1e38a4fbf039fb5d0c4d90284..a3a410d20da07ad44100defd79562f8c6d9ded3f 100644 (file)
@@ -352,7 +352,7 @@ dsa_slave_create(struct dsa_switch *ds, struct device *parent,
        netif_carrier_off(slave_dev);
 
        if (p->phy != NULL) {
-               phy_attach(slave_dev, p->phy->dev.bus_id,
+               phy_attach(slave_dev, dev_name(&p->phy->dev),
                           0, PHY_INTERFACE_MODE_GMII);
 
                p->phy->autoneg = AUTONEG_ENABLE;
index 31866543332ea4c130d47eb9f6539cf5f0f11d94..f99a019b939ed7e2b15e90bcfa5be1716accd1b9 100644 (file)
@@ -162,7 +162,6 @@ static int dsa_rcv(struct sk_buff *skb, struct net_device *dev,
        skb->pkt_type = PACKET_HOST;
        skb->protocol = eth_type_trans(skb, skb->dev);
 
-       skb->dev->last_rx = jiffies;
        skb->dev->stats.rx_packets++;
        skb->dev->stats.rx_bytes += skb->len;
 
index 9f4ce55eae5952b9cd3c5e6606189d10028002f7..328ec957f7864a670ce7ad841ae43010fa2d2e35 100644 (file)
@@ -181,7 +181,6 @@ static int edsa_rcv(struct sk_buff *skb, struct net_device *dev,
        skb->pkt_type = PACKET_HOST;
        skb->protocol = eth_type_trans(skb, skb->dev);
 
-       skb->dev->last_rx = jiffies;
        skb->dev->stats.rx_packets++;
        skb->dev->stats.rx_bytes += skb->len;
 
index efd26697e716a22b6fb8713a5285b88a20fab2ab..b59132878ad1c45ce54271213d5b4909d5113809 100644 (file)
@@ -98,7 +98,6 @@ static int trailer_rcv(struct sk_buff *skb, struct net_device *dev,
        skb->pkt_type = PACKET_HOST;
        skb->protocol = eth_type_trans(skb, skb->dev);
 
-       skb->dev->last_rx = jiffies;
        skb->dev->stats.rx_packets++;
        skb->dev->stats.rx_bytes += skb->len;
 
index 94ed7d3cd9dab45e54e292d3c674992c87026cd8..d2282bb2e4f17d910635720f05389dbcdcb92640 100644 (file)
@@ -1,12 +1,24 @@
 config IEEE80211
-       tristate "Generic IEEE 802.11 Networking Stack (DEPRECATED)"
+       tristate
+       select WIRELESS_EXT
+       select CRYPTO
+       select CRYPTO_ARC4
+       select CRYPTO_ECB
+       select CRYPTO_AES
+       select CRYPTO_MICHAEL_MIC
+       select CRYPTO_ECB
+       select CRC32
+       select IEEE80211_CRYPT_WEP
+       select IEEE80211_CRYPT_TKIP
+       select IEEE80211_CRYPT_CCMP
+       select LIB80211
        ---help---
        This option enables the hardware independent IEEE 802.11
        networking stack.  This component is deprecated in favor of the
        mac80211 component.
 
 config IEEE80211_DEBUG
-       bool "Enable full debugging output"
+       bool "Full debugging output for the old IEEE80211 stack"
        depends on IEEE80211
        ---help---
          This option will enable debug tracing output for the
@@ -29,45 +41,10 @@ config IEEE80211_DEBUG
          subsystem, you most likely want to say N here.
 
 config IEEE80211_CRYPT_WEP
-       tristate "IEEE 802.11 WEP encryption (802.1x)"
-       depends on IEEE80211
-       select CRYPTO
-       select CRYPTO_ARC4
-       select CRYPTO_ECB
-       select CRC32
-       ---help---
-       Include software based cipher suites in support of IEEE
-       802.11's WEP.  This is needed for WEP as well as 802.1x.
-
-       This can be compiled as a module and it will be called
-       "ieee80211_crypt_wep".
+       tristate
 
 config IEEE80211_CRYPT_CCMP
-       tristate "IEEE 802.11i CCMP support"
-       depends on IEEE80211
-       select CRYPTO
-       select CRYPTO_AES
-       ---help---
-       Include software based cipher suites in support of IEEE 802.11i
-       (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with CCMP enabled
-       networks.
-
-       This can be compiled as a module and it will be called
-       "ieee80211_crypt_ccmp".
+       tristate
 
 config IEEE80211_CRYPT_TKIP
-       tristate "IEEE 802.11i TKIP encryption"
-       depends on IEEE80211
-       select WIRELESS_EXT
-       select CRYPTO
-       select CRYPTO_MICHAEL_MIC
-       select CRYPTO_ECB
-       select CRC32
-       ---help---
-       Include software based cipher suites in support of IEEE 802.11i
-       (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with TKIP enabled
-       networks.
-
-       This can be compiled as a module and it will be called
-       "ieee80211_crypt_tkip".
-
+       tristate
index 208bf35b55463d10d95222f36e38c11bedf8c18a..bea04af0b482031f60b72cadd947f44dabf4a7ba 100644 (file)
@@ -296,7 +296,6 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
        int i, blocks, last, len;
        size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
        u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
-       DECLARE_MAC_BUF(mac);
 
        if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
                key->dot11RSNAStatsCCMPFormatErrors++;
@@ -309,7 +308,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
        if (!(keyidx & (1 << 5))) {
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "CCMP: received packet without ExtIV"
-                              " flag from %s\n", print_mac(mac, hdr->addr2));
+                              " flag from %pM\n", hdr->addr2);
                }
                key->dot11RSNAStatsCCMPFormatErrors++;
                return -2;
@@ -322,9 +321,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
        }
        if (!key->key_set) {
                if (net_ratelimit()) {
-                       printk(KERN_DEBUG "CCMP: received packet from %s"
+                       printk(KERN_DEBUG "CCMP: received packet from %pM"
                               " with keyid=%d that does not have a configured"
-                              " key\n", print_mac(mac, hdr->addr2), keyidx);
+                              " key\n", hdr->addr2, keyidx);
                }
                return -3;
        }
@@ -339,10 +338,10 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 
        if (ccmp_replay_check(pn, key->rx_pn)) {
                if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) {
-                       IEEE80211_DEBUG_DROP("CCMP: replay detected: STA=%s "
+                       IEEE80211_DEBUG_DROP("CCMP: replay detected: STA=%pM "
                                 "previous PN %02x%02x%02x%02x%02x%02x "
                                 "received PN %02x%02x%02x%02x%02x%02x\n",
-                                print_mac(mac, hdr->addr2),
+                                hdr->addr2,
                                 key->rx_pn[0], key->rx_pn[1], key->rx_pn[2],
                                 key->rx_pn[3], key->rx_pn[4], key->rx_pn[5],
                                 pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]);
@@ -373,7 +372,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
        if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "CCMP: decrypt failed: STA="
-                              "%s\n", print_mac(mac, hdr->addr2));
+                              "%pM\n", hdr->addr2);
                }
                key->dot11RSNAStatsCCMPDecryptErrors++;
                return -5;
index bba0152e2d713b5798e6501711312e59a4267cef..d12da1da6328bd3810803fe66af1f0ee48b307b5 100644 (file)
@@ -359,15 +359,13 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
        u8 rc4key[16], *pos, *icv;
        u32 crc;
        struct scatterlist sg;
-       DECLARE_MAC_BUF(mac);
 
        if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
                if (net_ratelimit()) {
                        struct ieee80211_hdr_4addr *hdr =
                            (struct ieee80211_hdr_4addr *)skb->data;
                        printk(KERN_DEBUG ": TKIP countermeasures: dropped "
-                              "TX packet to %s\n",
-                              print_mac(mac, hdr->addr1));
+                              "TX packet to %pM\n", hdr->addr1);
                }
                return -1;
        }
@@ -420,15 +418,13 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
        u32 crc;
        struct scatterlist sg;
        int plen;
-       DECLARE_MAC_BUF(mac);
 
        hdr = (struct ieee80211_hdr_4addr *)skb->data;
 
        if (tkey->flags & IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) {
                if (net_ratelimit()) {
                        printk(KERN_DEBUG ": TKIP countermeasures: dropped "
-                              "received packet from %s\n",
-                              print_mac(mac, hdr->addr2));
+                              "received packet from %pM\n", hdr->addr2);
                }
                return -1;
        }
@@ -441,7 +437,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
        if (!(keyidx & (1 << 5))) {
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "TKIP: received packet without ExtIV"
-                              " flag from %s\n", print_mac(mac, hdr->addr2));
+                              " flag from %pM\n", hdr->addr2);
                }
                return -2;
        }
@@ -453,9 +449,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
        }
        if (!tkey->key_set) {
                if (net_ratelimit()) {
-                       printk(KERN_DEBUG "TKIP: received packet from %s"
+                       printk(KERN_DEBUG "TKIP: received packet from %pM"
                               " with keyid=%d that does not have a configured"
-                              " key\n", print_mac(mac, hdr->addr2), keyidx);
+                              " key\n", hdr->addr2, keyidx);
                }
                return -3;
        }
@@ -465,9 +461,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 
        if (tkip_replay_check(iv32, iv16, tkey->rx_iv32, tkey->rx_iv16)) {
                if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) {
-                       IEEE80211_DEBUG_DROP("TKIP: replay detected: STA=%s"
+                       IEEE80211_DEBUG_DROP("TKIP: replay detected: STA=%pM"
                               " previous TSC %08x%04x received TSC "
-                              "%08x%04x\n", print_mac(mac, hdr->addr2),
+                              "%08x%04x\n", hdr->addr2,
                               tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
                }
                tkey->dot11RSNAStatsTKIPReplays++;
@@ -487,8 +483,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
        if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
                if (net_ratelimit()) {
                        printk(KERN_DEBUG ": TKIP: failed to decrypt "
-                              "received packet from %s\n",
-                              print_mac(mac, hdr->addr2));
+                              "received packet from %pM\n",
+                              hdr->addr2);
                }
                return -7;
        }
@@ -506,7 +502,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
                }
                if (ieee80211_ratelimit_debug(IEEE80211_DL_DROP)) {
                        IEEE80211_DEBUG_DROP("TKIP: ICV error detected: STA="
-                              "%s\n", print_mac(mac, hdr->addr2));
+                              "%pM\n", hdr->addr2);
                }
                tkey->dot11RSNAStatsTKIPICVErrors++;
                return -5;
@@ -633,7 +629,6 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
 {
        struct ieee80211_tkip_data *tkey = priv;
        u8 mic[8];
-       DECLARE_MAC_BUF(mac);
 
        if (!tkey->key_set)
                return -1;
@@ -646,8 +641,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
                struct ieee80211_hdr_4addr *hdr;
                hdr = (struct ieee80211_hdr_4addr *)skb->data;
                printk(KERN_DEBUG "%s: Michael MIC verification failed for "
-                      "MSDU from %s keyidx=%d\n",
-                      skb->dev ? skb->dev->name : "N/A", print_mac(mac, hdr->addr2),
+                      "MSDU from %pM keyidx=%d\n",
+                      skb->dev ? skb->dev->name : "N/A", hdr->addr2,
                       keyidx);
                if (skb->dev)
                        ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
index 949772a5a7dc15bd35152c3ada3df912681acfd7..d34d4e79b6f72d0c68955edd1ab7fa27b6aeeb62 100644 (file)
@@ -308,31 +308,5 @@ MODULE_PARM_DESC(debug, "debug output mask");
 module_exit(ieee80211_exit);
 module_init(ieee80211_init);
 
-const char *escape_essid(const char *essid, u8 essid_len)
-{
-       static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
-       const char *s = essid;
-       char *d = escaped;
-
-       if (ieee80211_is_empty_essid(essid, essid_len)) {
-               memcpy(escaped, "<hidden>", sizeof("<hidden>"));
-               return escaped;
-       }
-
-       essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
-       while (essid_len--) {
-               if (*s == '\0') {
-                       *d++ = '\\';
-                       *d++ = '0';
-                       s++;
-               } else {
-                       *d++ = *s++;
-               }
-       }
-       *d = '\0';
-       return escaped;
-}
-
 EXPORT_SYMBOL(alloc_ieee80211);
 EXPORT_SYMBOL(free_ieee80211);
-EXPORT_SYMBOL(escape_essid);
index 69dbc342a4649271341946341b6231495e293c91..3dd58b594f6ab5533605919a94420f9aef7d4d38 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/uaccess.h>
 #include <linux/ctype.h>
 
+#include <net/lib80211.h>
 #include <net/ieee80211.h>
 
 static void ieee80211_monitor_rx(struct ieee80211_device *ieee,
@@ -39,7 +40,7 @@ static void ieee80211_monitor_rx(struct ieee80211_device *ieee,
                                        struct ieee80211_rx_stats *rx_stats)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       u16 fc = le16_to_cpu(hdr->frame_ctl);
+       u16 fc = le16_to_cpu(hdr->frame_control);
 
        skb->dev = ieee->dev;
        skb_reset_mac_header(skb);
@@ -282,12 +283,8 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
        res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
        atomic_dec(&crypt->refcnt);
        if (res < 0) {
-               IEEE80211_DEBUG_DROP("decryption failed (SA=" MAC_FMT
-                                    ") res=%d\n",
-                                    hdr->addr2[0], hdr->addr2[1],
-                                    hdr->addr2[2], hdr->addr2[3],
-                                    hdr->addr2[4], hdr->addr2[5],
-                                    res);
+               IEEE80211_DEBUG_DROP("decryption failed (SA=%pM) res=%d\n",
+                                    hdr->addr2, res);
                if (res == -2)
                        IEEE80211_DEBUG_DROP("Decryption failed ICV "
                                             "mismatch (key %d)\n",
@@ -319,11 +316,7 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
        atomic_dec(&crypt->refcnt);
        if (res < 0) {
                printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
-                      " (SA=" MAC_FMT " keyidx=%d)\n",
-                      ieee->dev->name,
-                      hdr->addr2[0], hdr->addr2[1],
-                      hdr->addr2[2], hdr->addr2[3],
-                      hdr->addr2[4], hdr->addr2[5],
+                      " (SA=%pM keyidx=%d)\n", ieee->dev->name, hdr->addr2,
                       keyidx);
                return -1;
        }
@@ -358,7 +351,6 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
        struct ieee80211_crypt_data *crypt = NULL;
        int keyidx = 0;
        int can_be_decrypted = 0;
-       DECLARE_MAC_BUF(mac);
 
        hdr = (struct ieee80211_hdr_4addr *)skb->data;
        stats = &ieee->stats;
@@ -468,10 +460,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                         * frames silently instead of filling system log with
                         * these reports. */
                        IEEE80211_DEBUG_DROP("Decryption failed (not set)"
-                                            " (SA=" MAC_FMT ")\n",
-                                            hdr->addr2[0], hdr->addr2[1],
-                                            hdr->addr2[2], hdr->addr2[3],
-                                            hdr->addr2[4], hdr->addr2[5]);
+                                            " (SA=%pM)\n", hdr->addr2);
                        ieee->ieee_stats.rx_discards_undecryptable++;
                        goto rx_dropped;
                }
@@ -482,10 +471,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                    fc & IEEE80211_FCTL_PROTECTED && ieee->host_decrypt &&
                    (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0) {
                        printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
-                              "from " MAC_FMT "\n", dev->name,
-                              hdr->addr2[0], hdr->addr2[1],
-                              hdr->addr2[2], hdr->addr2[3],
-                              hdr->addr2[4], hdr->addr2[5]);
+                              "from %pM\n", dev->name, hdr->addr2);
                        /* TODO: could inform hostapd about this so that it
                         * could send auth failure report */
                        goto rx_dropped;
@@ -547,8 +533,6 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
        }
 #endif
 
-       dev->last_rx = jiffies;
-
 #ifdef NOT_YET
        if ((ieee->iw_mode == IW_MODE_MASTER ||
             ieee->iw_mode == IW_MODE_REPEAT) && !from_assoc_ap) {
@@ -663,11 +647,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                         * configured */
                } else {
                        IEEE80211_DEBUG_DROP("encryption configured, but RX "
-                                            "frame not encrypted (SA="
-                                            MAC_FMT ")\n",
-                                            hdr->addr2[0], hdr->addr2[1],
-                                            hdr->addr2[2], hdr->addr2[3],
-                                            hdr->addr2[4], hdr->addr2[5]);
+                                            "frame not encrypted (SA=%pM)\n",
+                                            hdr->addr2);
                        goto rx_dropped;
                }
        }
@@ -675,11 +656,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
        if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep &&
            !ieee80211_is_eapol_frame(ieee, skb)) {
                IEEE80211_DEBUG_DROP("dropped unencrypted RX data "
-                                    "frame from " MAC_FMT
-                                    " (drop_unencrypted=1)\n",
-                                    hdr->addr2[0], hdr->addr2[1],
-                                    hdr->addr2[2], hdr->addr2[3],
-                                    hdr->addr2[4], hdr->addr2[5]);
+                                    "frame from %pM (drop_unencrypted=1)\n",
+                                    hdr->addr2);
                goto rx_dropped;
        }
 
@@ -1144,6 +1122,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
                                      *info_element, u16 length,
                                      struct ieee80211_network *network)
 {
+       DECLARE_SSID_BUF(ssid);
        u8 i;
 #ifdef CONFIG_IEEE80211_DEBUG
        char rates_str[64];
@@ -1166,12 +1145,6 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
 
                switch (info_element->id) {
                case MFIE_TYPE_SSID:
-                       if (ieee80211_is_empty_essid(info_element->data,
-                                                    info_element->len)) {
-                               network->flags |= NETWORK_EMPTY_ESSID;
-                               break;
-                       }
-
                        network->ssid_len = min(info_element->len,
                                                (u8) IW_ESSID_MAX_SIZE);
                        memcpy(network->ssid, info_element->data,
@@ -1181,7 +1154,9 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
                                       IW_ESSID_MAX_SIZE - network->ssid_len);
 
                        IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
-                                            network->ssid, network->ssid_len);
+                                            print_ssid(ssid, network->ssid,
+                                                       network->ssid_len),
+                                            network->ssid_len);
                        break;
 
                case MFIE_TYPE_RATES:
@@ -1411,9 +1386,6 @@ static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct iee
                        network->mode |= IEEE_B;
        }
 
-       if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
-               network->flags |= NETWORK_EMPTY_ESSID;
-
        memcpy(&network->stats, stats, sizeof(network->stats));
 
        if (ieee->handle_assoc_response != NULL)
@@ -1429,7 +1401,7 @@ static int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee8021
                                         struct ieee80211_network *network,
                                         struct ieee80211_rx_stats *stats)
 {
-       DECLARE_MAC_BUF(mac);
+       DECLARE_SSID_BUF(ssid);
 
        network->qos_data.active = 0;
        network->qos_data.supported = 0;
@@ -1477,17 +1449,14 @@ static int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee8021
        }
 
        if (network->mode == 0) {
-               IEEE80211_DEBUG_SCAN("Filtered out '%s (%s)' "
+               IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
                                     "network.\n",
-                                    escape_essid(network->ssid,
-                                                 network->ssid_len),
-                                    print_mac(mac, network->bssid));
+                                    print_ssid(ssid, network->ssid,
+                                                network->ssid_len),
+                                    network->bssid);
                return 1;
        }
 
-       if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
-               network->flags |= NETWORK_EMPTY_ESSID;
-
        memcpy(&network->stats, stats, sizeof(network->stats));
 
        return 0;
@@ -1510,7 +1479,6 @@ static void update_network(struct ieee80211_network *dst,
 {
        int qos_active;
        u8 old_param;
-       DECLARE_MAC_BUF(mac);
 
        ieee80211_network_reset(dst);
        dst->ibss_dfs = src->ibss_dfs;
@@ -1524,8 +1492,8 @@ static void update_network(struct ieee80211_network *dst,
                memcpy(&dst->stats, &src->stats,
                       sizeof(struct ieee80211_rx_stats));
        else
-               IEEE80211_DEBUG_SCAN("Network %s info received "
-                       "off channel (%d vs. %d)\n", print_mac(mac, src->bssid),
+               IEEE80211_DEBUG_SCAN("Network %pM info received "
+                       "off channel (%d vs. %d)\n", src->bssid,
                        dst->channel, src->stats.received_channel);
 
        dst->capability = src->capability;
@@ -1597,12 +1565,12 @@ static void ieee80211_process_probe_response(struct ieee80211_device
        struct ieee80211_info_element *info_element = beacon->info_element;
 #endif
        unsigned long flags;
-       DECLARE_MAC_BUF(mac);
+       DECLARE_SSID_BUF(ssid);
 
-       IEEE80211_DEBUG_SCAN("'%s' (%s"
+       IEEE80211_DEBUG_SCAN("'%s' (%pM"
                     "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
-                    escape_essid(info_element->data, info_element->len),
-                    print_mac(mac, beacon->header.addr3),
+                    print_ssid(ssid, info_element->data, info_element->len),
+                    beacon->header.addr3,
                     (beacon->capability & cpu_to_le16(1 << 0xf)) ? '1' : '0',
                     (beacon->capability & cpu_to_le16(1 << 0xe)) ? '1' : '0',
                     (beacon->capability & cpu_to_le16(1 << 0xd)) ? '1' : '0',
@@ -1621,10 +1589,10 @@ static void ieee80211_process_probe_response(struct ieee80211_device
                     (beacon->capability & cpu_to_le16(1 << 0x0)) ? '1' : '0');
 
        if (ieee80211_network_init(ieee, beacon, &network, stats)) {
-               IEEE80211_DEBUG_SCAN("Dropped '%s' (%s) via %s.\n",
-                                    escape_essid(info_element->data,
-                                                 info_element->len),
-                                    print_mac(mac, beacon->header.addr3),
+               IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
+                                    print_ssid(ssid, info_element->data,
+                                                info_element->len),
+                                    beacon->header.addr3,
                                     is_beacon(beacon->header.frame_ctl) ?
                                     "BEACON" : "PROBE RESPONSE");
                return;
@@ -1658,11 +1626,11 @@ static void ieee80211_process_probe_response(struct ieee80211_device
                        /* If there are no more slots, expire the oldest */
                        list_del(&oldest->list);
                        target = oldest;
-                       IEEE80211_DEBUG_SCAN("Expired '%s' (%s) from "
+                       IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
                                             "network list.\n",
-                                            escape_essid(target->ssid,
-                                                         target->ssid_len),
-                                            print_mac(mac, target->bssid));
+                                            print_ssid(ssid, target->ssid,
+                                                        target->ssid_len),
+                                            target->bssid);
                        ieee80211_network_reset(target);
                } else {
                        /* Otherwise just pull from the free list */
@@ -1672,10 +1640,10 @@ static void ieee80211_process_probe_response(struct ieee80211_device
                }
 
 #ifdef CONFIG_IEEE80211_DEBUG
-               IEEE80211_DEBUG_SCAN("Adding '%s' (%s) via %s.\n",
-                                    escape_essid(network.ssid,
-                                                 network.ssid_len),
-                                    print_mac(mac, network.bssid),
+               IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
+                                    print_ssid(ssid, network.ssid,
+                                                network.ssid_len),
+                                    network.bssid,
                                     is_beacon(beacon->header.frame_ctl) ?
                                     "BEACON" : "PROBE RESPONSE");
 #endif
@@ -1683,10 +1651,10 @@ static void ieee80211_process_probe_response(struct ieee80211_device
                network.ibss_dfs = NULL;
                list_add_tail(&target->list, &ieee->network_list);
        } else {
-               IEEE80211_DEBUG_SCAN("Updating '%s' (%s) via %s.\n",
-                                    escape_essid(target->ssid,
-                                                 target->ssid_len),
-                                    print_mac(mac, target->bssid),
+               IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
+                                    print_ssid(ssid, target->ssid,
+                                                target->ssid_len),
+                                    target->bssid,
                                     is_beacon(beacon->header.frame_ctl) ?
                                     "BEACON" : "PROBE RESPONSE");
                update_network(target, &network);
index 973832dd7faf6a56c189290f89a1d33e87184871..7cc4e5ee3660faf47c978ed014ac06a5472131d4 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/module.h>
 #include <linux/jiffies.h>
 
+#include <net/lib80211.h>
 #include <net/ieee80211.h>
 #include <linux/wireless.h>
 
@@ -65,15 +66,9 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
        /* Add the ESSID */
        iwe.cmd = SIOCGIWESSID;
        iwe.u.data.flags = 1;
-       if (network->flags & NETWORK_EMPTY_ESSID) {
-               iwe.u.data.length = sizeof("<hidden>");
-               start = iwe_stream_add_point(info, start, stop,
-                                            &iwe, "<hidden>");
-       } else {
-               iwe.u.data.length = min(network->ssid_len, (u8) 32);
-               start = iwe_stream_add_point(info, start, stop,
-                                            &iwe, network->ssid);
-       }
+       iwe.u.data.length = min(network->ssid_len, (u8) 32);
+       start = iwe_stream_add_point(info, start, stop,
+                                    &iwe, network->ssid);
 
        /* Add the protocol name */
        iwe.cmd = SIOCGIWNAME;
@@ -264,7 +259,7 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
        char *ev = extra;
        char *stop = ev + wrqu->data.length;
        int i = 0;
-       DECLARE_MAC_BUF(mac);
+       DECLARE_SSID_BUF(ssid);
 
        IEEE80211_DEBUG_WX("Getting scan\n");
 
@@ -283,10 +278,10 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
                                                      info);
                else
                        IEEE80211_DEBUG_SCAN("Not showing network '%s ("
-                                            "%s)' due to age (%dms).\n",
-                                            escape_essid(network->ssid,
-                                                         network->ssid_len),
-                                            print_mac(mac, network->bssid),
+                                            "%pM)' due to age (%dms).\n",
+                                            print_ssid(ssid, network->ssid,
+                                                        network->ssid_len),
+                                            network->bssid,
                                             jiffies_to_msecs(jiffies -
                                                              network->
                                                              last_scanned));
@@ -314,6 +309,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
        int i, key, key_provided, len;
        struct ieee80211_crypt_data **crypt;
        int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv;
+       DECLARE_SSID_BUF(ssid);
 
        IEEE80211_DEBUG_WX("SET_ENCODE\n");
 
@@ -403,13 +399,17 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
 
        /* If a new key was provided, set it up */
        if (erq->length > 0) {
+#ifdef CONFIG_IEEE80211_DEBUG
+               DECLARE_SSID_BUF(ssid);
+#endif
+
                len = erq->length <= 5 ? 5 : 13;
                memcpy(sec.keys[key], keybuf, erq->length);
                if (len > erq->length)
                        memset(sec.keys[key] + erq->length, 0,
                               len - erq->length);
                IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
-                                  key, escape_essid(sec.keys[key], len),
+                                  key, print_ssid(ssid, sec.keys[key], len),
                                   erq->length, len);
                sec.key_sizes[key] = len;
                if (*crypt)
index 1fbff5fa424101fb463905be71d1cc06299fa74c..e3286814c8d971ef57a840378603d15fa82d2206 100644 (file)
@@ -1070,11 +1070,8 @@ static int inet_sk_reselect_saddr(struct sock *sk)
                return 0;
 
        if (sysctl_ip_dynaddr > 1) {
-               printk(KERN_INFO "%s(): shifting inet->"
-                                "saddr from " NIPQUAD_FMT " to " NIPQUAD_FMT "\n",
-                      __func__,
-                      NIPQUAD(old_saddr),
-                      NIPQUAD(new_saddr));
+               printk(KERN_INFO "%s(): shifting inet->saddr from %pI4 to %pI4\n",
+                      __func__, &old_saddr, &new_saddr);
        }
 
        inet->saddr = inet->rcv_saddr = new_saddr;
index 8219b7e0968d1df51a315b2880bf35be09888ab3..3f205181712d3f7b901ef7bf43476e410a588633 100644 (file)
@@ -201,8 +201,8 @@ out:
 
 static void ah4_err(struct sk_buff *skb, u32 info)
 {
-       struct iphdr *iph = (struct iphdr*)skb->data;
-       struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+(iph->ihl<<2));
+       struct iphdr *iph = (struct iphdr *)skb->data;
+       struct ip_auth_hdr *ah = (struct ip_auth_hdr *)(skb->data+(iph->ihl<<2));
        struct xfrm_state *x;
 
        if (icmp_hdr(skb)->type != ICMP_DEST_UNREACH ||
index 1a9dd66511fccfadf9e1240334e7dcc2a3f073b0..29a74c01d8de54857fa3ef4a82184dc8a03b91cd 100644 (file)
@@ -506,7 +506,7 @@ int arp_bind_neighbour(struct dst_entry *dst)
        if (dev == NULL)
                return -EINVAL;
        if (n == NULL) {
-               __be32 nexthop = ((struct rtable*)dst)->rt_gateway;
+               __be32 nexthop = ((struct rtable *)dst)->rt_gateway;
                if (dev->flags&(IFF_LOOPBACK|IFF_POINTOPOINT))
                        nexthop = 0;
                n = __neigh_lookup_errno(
@@ -640,14 +640,14 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
        arp_ptr=(unsigned char *)(arp+1);
 
        memcpy(arp_ptr, src_hw, dev->addr_len);
-       arp_ptr+=dev->addr_len;
-       memcpy(arp_ptr, &src_ip,4);
-       arp_ptr+=4;
+       arp_ptr += dev->addr_len;
+       memcpy(arp_ptr, &src_ip, 4);
+       arp_ptr += 4;
        if (target_hw != NULL)
                memcpy(arp_ptr, target_hw, dev->addr_len);
        else
                memset(arp_ptr, 0, dev->addr_len);
-       arp_ptr+=dev->addr_len;
+       arp_ptr += dev->addr_len;
        memcpy(arp_ptr, &dest_ip, 4);
 
        return skb;
@@ -818,18 +818,18 @@ static int arp_process(struct sk_buff *skb)
                addr_type = rt->rt_type;
 
                if (addr_type == RTN_LOCAL) {
-                       n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
-                       if (n) {
-                               int dont_send = 0;
-
-                               if (!dont_send)
-                                       dont_send |= arp_ignore(in_dev,sip,tip);
-                               if (!dont_send && IN_DEV_ARPFILTER(in_dev))
-                                       dont_send |= arp_filter(sip,tip,dev);
-                               if (!dont_send)
-                                       arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);
+                       int dont_send = 0;
 
-                               neigh_release(n);
+                       if (!dont_send)
+                               dont_send |= arp_ignore(in_dev,sip,tip);
+                       if (!dont_send && IN_DEV_ARPFILTER(in_dev))
+                               dont_send |= arp_filter(sip,tip,dev);
+                       if (!dont_send) {
+                               n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
+                               if (n) {
+                                       arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);
+                                       neigh_release(n);
+                               }
                        }
                        goto out;
                } else if (IN_DEV_FORWARD(in_dev)) {
@@ -1308,7 +1308,7 @@ static void arp_format_neigh_entry(struct seq_file *seq,
 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
        }
 #endif
-       sprintf(tbuf, NIPQUAD_FMT, NIPQUAD(*(u32*)n->primary_key));
+       sprintf(tbuf, "%pI4", n->primary_key);
        seq_printf(seq, "%-16s 0x%-10x0x%-10x%s     *        %s\n",
                   tbuf, hatype, arp_state_to_flags(n), hbuffer, dev->name);
        read_unlock(&n->lock);
@@ -1321,7 +1321,7 @@ static void arp_format_pneigh_entry(struct seq_file *seq,
        int hatype = dev ? dev->type : 0;
        char tbuf[16];
 
-       sprintf(tbuf, NIPQUAD_FMT, NIPQUAD(*(u32*)n->key));
+       sprintf(tbuf, "%pI4", n->key);
        seq_printf(seq, "%-16s 0x%-10x0x%-10x%s     *        %s\n",
                   tbuf, hatype, ATF_PUBL | ATF_PERM, "00:00:00:00:00:00",
                   dev ? dev->name : "*");
index 2e78f6bd97756db7920367e5fe07ce23e6cd6eb7..e52799047a5feac1c018bc55b01bbce4ff8a8c06 100644 (file)
@@ -490,7 +490,6 @@ int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
        }
 
        atomic_set(&doi_def->refcount, 1);
-       INIT_RCU_HEAD(&doi_def->rcu);
 
        spin_lock(&cipso_v4_doi_list_lock);
        if (cipso_v4_doi_search(doi_def->doi) != NULL)
index 56fce3ab6c55263c727357ee54c18bf70221451a..309997edc8a5169546e87ed2a51e51214e4bea6f 100644 (file)
@@ -112,13 +112,7 @@ static inline void devinet_sysctl_unregister(struct in_device *idev)
 
 static struct in_ifaddr *inet_alloc_ifa(void)
 {
-       struct in_ifaddr *ifa = kzalloc(sizeof(*ifa), GFP_KERNEL);
-
-       if (ifa) {
-               INIT_RCU_HEAD(&ifa->rcu_head);
-       }
-
-       return ifa;
+       return kzalloc(sizeof(struct in_ifaddr), GFP_KERNEL);
 }
 
 static void inet_rcu_free_ifa(struct rcu_head *head)
@@ -161,7 +155,6 @@ static struct in_device *inetdev_init(struct net_device *dev)
        in_dev = kzalloc(sizeof(*in_dev), GFP_KERNEL);
        if (!in_dev)
                goto out;
-       INIT_RCU_HEAD(&in_dev->rcu_head);
        memcpy(&in_dev->cnf, dev_net(dev)->ipv4.devconf_dflt,
                        sizeof(in_dev->cnf));
        in_dev->cnf.sysctl = NULL;
@@ -1108,7 +1101,7 @@ out:
 }
 
 static struct notifier_block ip_netdev_notifier = {
-       .notifier_call =inetdev_event,
+       .notifier_call = inetdev_event,
 };
 
 static inline size_t inet_nlmsg_size(void)
@@ -1195,7 +1188,7 @@ done:
        return skb->len;
 }
 
-static void rtmsg_ifa(int event, struct in_ifaddrifa, struct nlmsghdr *nlh,
+static void rtmsg_ifa(int event, struct in_ifaddr *ifa, struct nlmsghdr *nlh,
                      u32 pid)
 {
        struct sk_buff *skb;
@@ -1262,7 +1255,7 @@ static void inet_forward_change(struct net *net)
 }
 
 static int devinet_conf_proc(ctl_table *ctl, int write,
-                            struct filefilp, void __user *buffer,
+                            struct file *filp, void __user *buffer,
                             size_t *lenp, loff_t *ppos)
 {
        int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
@@ -1334,7 +1327,7 @@ static int devinet_conf_sysctl(ctl_table *table,
 }
 
 static int devinet_sysctl_forward(ctl_table *ctl, int write,
-                                 struct filefilp, void __user *buffer,
+                                 struct file *filp, void __user *buffer,
                                  size_t *lenp, loff_t *ppos)
 {
        int *valp = ctl->data;
@@ -1363,7 +1356,7 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
 }
 
 int ipv4_doint_and_flush(ctl_table *ctl, int write,
-                        struct filefilp, void __user *buffer,
+                        struct file *filp, void __user *buffer,
                         size_t *lenp, loff_t *ppos)
 {
        int *valp = ctl->data;
index 21515d4c49eb5712c22655ba7d8166909bdcf13e..95a9c65003f89012ac2024784b51972d7f750e98 100644 (file)
@@ -413,8 +413,8 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
 
 static void esp4_err(struct sk_buff *skb, u32 info)
 {
-       struct iphdr *iph = (struct iphdr*)skb->data;
-       struct ip_esp_hdr *esph = (struct ip_esp_hdr*)(skb->data+(iph->ihl<<2));
+       struct iphdr *iph = (struct iphdr *)skb->data;
+       struct ip_esp_hdr *esph = (struct ip_esp_hdr *)(skb->data+(iph->ihl<<2));
        struct xfrm_state *x;
 
        if (icmp_hdr(skb)->type != ICMP_DEST_UNREACH ||
index 65c1503f8cc8b1caea7c9242d6e316d734b5e733..741e4fa3e4749e0285c39f65dc306e644fb4032b 100644 (file)
@@ -578,7 +578,7 @@ errout:
        return err;
 }
 
-static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdrnlh, void *arg)
+static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
        struct net *net = sock_net(skb->sk);
        struct fib_config cfg;
@@ -600,7 +600,7 @@ errout:
        return err;
 }
 
-static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdrnlh, void *arg)
+static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
        struct net *net = sock_net(skb->sk);
        struct fib_config cfg;
@@ -903,7 +903,7 @@ static void fib_disable_ip(struct net_device *dev, int force)
 
 static int fib_inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
-       struct in_ifaddr *ifa = (struct in_ifaddr*)ptr;
+       struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
        struct net_device *dev = ifa->ifa_dev->dev;
 
        switch (event) {
@@ -964,11 +964,11 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
 }
 
 static struct notifier_block fib_inetaddr_notifier = {
-       .notifier_call =fib_inetaddr_event,
+       .notifier_call = fib_inetaddr_event,
 };
 
 static struct notifier_block fib_netdev_notifier = {
-       .notifier_call =fib_netdev_event,
+       .notifier_call = fib_netdev_event,
 };
 
 static int __net_init ip_fib_net_init(struct net *net)
index c8cac6c7f881ee67e44ede59011f2e267b3ff44d..ded8c44fb848842a99f9bbe75830936eb596a48e 100644 (file)
@@ -247,7 +247,7 @@ fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
 {
        int err;
        struct fn_zone *fz;
-       struct fn_hash *t = (struct fn_hash*)tb->tb_data;
+       struct fn_hash *t = (struct fn_hash *)tb->tb_data;
 
        read_lock(&fib_hash_lock);
        for (fz = t->fn_zone_list; fz; fz = fz->fz_next) {
@@ -283,7 +283,7 @@ fn_hash_select_default(struct fib_table *tb, const struct flowi *flp, struct fib
        struct fib_node *f;
        struct fib_info *fi = NULL;
        struct fib_info *last_resort;
-       struct fn_hash *t = (struct fn_hash*)tb->tb_data;
+       struct fn_hash *t = (struct fn_hash *)tb->tb_data;
        struct fn_zone *fz = t->fn_zones[0];
 
        if (fz == NULL)
@@ -548,7 +548,7 @@ out:
 
 static int fn_hash_delete(struct fib_table *tb, struct fib_config *cfg)
 {
-       struct fn_hash *table = (struct fn_hash*)tb->tb_data;
+       struct fn_hash *table = (struct fn_hash *)tb->tb_data;
        struct fib_node *f;
        struct fib_alias *fa, *fa_to_delete;
        struct fn_zone *fz;
@@ -748,7 +748,7 @@ static int fn_hash_dump(struct fib_table *tb, struct sk_buff *skb, struct netlin
 {
        int m, s_m;
        struct fn_zone *fz;
-       struct fn_hash *table = (struct fn_hash*)tb->tb_data;
+       struct fn_hash *table = (struct fn_hash *)tb->tb_data;
 
        s_m = cb->args[2];
        read_lock(&fib_hash_lock);
@@ -845,10 +845,10 @@ static struct fib_alias *fib_get_first(struct seq_file *seq)
                        struct hlist_node *node;
                        struct fib_node *fn;
 
-                       hlist_for_each_entry(fn,node,iter->hash_head,fn_hash) {
+                       hlist_for_each_entry(fn, node, iter->hash_head, fn_hash) {
                                struct fib_alias *fa;
 
-                               list_for_each_entry(fa,&fn->fn_alias,fa_list) {
+                               list_for_each_entry(fa, &fn->fn_alias, fa_list) {
                                        iter->fn = fn;
                                        iter->fa = fa;
                                        goto out;
index ded2ae34eab15017821063de974a8792d4474d0b..4817dea3bc737225ec99a605b3b5d5681ac6e082 100644 (file)
@@ -63,16 +63,16 @@ static DEFINE_SPINLOCK(fib_multipath_lock);
 for (nhsel=0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++)
 
 #define change_nexthops(fi) { int nhsel; struct fib_nh * nh; \
-for (nhsel=0, nh = (struct fib_nh*)((fi)->fib_nh); nhsel < (fi)->fib_nhs; nh++, nhsel++)
+for (nhsel=0, nh = (struct fib_nh *)((fi)->fib_nh); nhsel < (fi)->fib_nhs; nh++, nhsel++)
 
 #else /* CONFIG_IP_ROUTE_MULTIPATH */
 
 /* Hope, that gcc will optimize it to get rid of dummy loop */
 
-#define for_nexthops(fi) { int nhsel=0; const struct fib_nh * nh = (fi)->fib_nh; \
+#define for_nexthops(fi) { int nhsel = 0; const struct fib_nh * nh = (fi)->fib_nh; \
 for (nhsel=0; nhsel < 1; nhsel++)
 
-#define change_nexthops(fi) { int nhsel=0; struct fib_nh * nh = (struct fib_nh*)((fi)->fib_nh); \
+#define change_nexthops(fi) { int nhsel = 0; struct fib_nh * nh = (struct fib_nh *)((fi)->fib_nh); \
 for (nhsel=0; nhsel < 1; nhsel++)
 
 #endif /* CONFIG_IP_ROUTE_MULTIPATH */
@@ -358,7 +358,7 @@ int fib_detect_death(struct fib_info *fi, int order,
                state = n->nud_state;
                neigh_release(n);
        }
-       if (state==NUD_REACHABLE)
+       if (state == NUD_REACHABLE)
                return 0;
        if ((state&NUD_VALID) && order != dflt)
                return 0;
index 5cb72786a8af59e290737e6e37896aeaadd4e094..ec0ae490f0b60306029126c0d848674cb2ee055d 100644 (file)
@@ -2399,8 +2399,8 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
                __be32 prf = htonl(mask_pfx(tn->key, tn->pos));
 
                seq_indent(seq, iter->depth-1);
-               seq_printf(seq, "  +-- " NIPQUAD_FMT "/%d %d %d %d\n",
-                          NIPQUAD(prf), tn->pos, tn->bits, tn->full_children,
+               seq_printf(seq, "  +-- %pI4/%d %d %d %d\n",
+                          &prf, tn->pos, tn->bits, tn->full_children,
                           tn->empty_children);
 
        } else {
@@ -2410,7 +2410,7 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
                __be32 val = htonl(l->key);
 
                seq_indent(seq, iter->depth);
-               seq_printf(seq, "  |-- " NIPQUAD_FMT "\n", NIPQUAD(val));
+               seq_printf(seq, "  |-- %pI4\n", &val);
 
                hlist_for_each_entry_rcu(li, node, &l->list, hlist) {
                        struct fib_alias *fa;
index 72b2de76f1cd1683b9dc33c957597a4556d9b36b..21e497efbd7ff7bdde5bc8b401a62cb3ce1c68e1 100644 (file)
@@ -683,10 +683,8 @@ static void icmp_unreach(struct sk_buff *skb)
                        break;
                case ICMP_FRAG_NEEDED:
                        if (ipv4_config.no_pmtu_disc) {
-                               LIMIT_NETDEBUG(KERN_INFO "ICMP: " NIPQUAD_FMT ": "
-                                                        "fragmentation needed "
-                                                        "and DF set.\n",
-                                              NIPQUAD(iph->daddr));
+                               LIMIT_NETDEBUG(KERN_INFO "ICMP: %pI4: fragmentation needed and DF set.\n",
+                                              &iph->daddr);
                        } else {
                                info = ip_rt_frag_needed(net, iph,
                                                         ntohs(icmph->un.frag.mtu),
@@ -696,9 +694,8 @@ static void icmp_unreach(struct sk_buff *skb)
                        }
                        break;
                case ICMP_SR_FAILED:
-                       LIMIT_NETDEBUG(KERN_INFO "ICMP: " NIPQUAD_FMT ": Source "
-                                                "Route Failed.\n",
-                                      NIPQUAD(iph->daddr));
+                       LIMIT_NETDEBUG(KERN_INFO "ICMP: %pI4: Source Route Failed.\n",
+                                      &iph->daddr);
                        break;
                default:
                        break;
@@ -729,12 +726,12 @@ static void icmp_unreach(struct sk_buff *skb)
        if (!net->ipv4.sysctl_icmp_ignore_bogus_error_responses &&
            inet_addr_type(net, iph->daddr) == RTN_BROADCAST) {
                if (net_ratelimit())
-                       printk(KERN_WARNING NIPQUAD_FMT " sent an invalid ICMP "
+                       printk(KERN_WARNING "%pI4 sent an invalid ICMP "
                                            "type %u, code %u "
-                                           "error to a broadcast: " NIPQUAD_FMT " on %s\n",
-                              NIPQUAD(ip_hdr(skb)->saddr),
+                                           "error to a broadcast: %pI4 on %s\n",
+                              &ip_hdr(skb)->saddr,
                               icmph->type, icmph->code,
-                              NIPQUAD(iph->daddr),
+                              &iph->daddr,
                               skb->dev->name);
                goto out;
        }
@@ -952,9 +949,8 @@ static void icmp_address_reply(struct sk_buff *skb)
                                break;
                }
                if (!ifa && net_ratelimit()) {
-                       printk(KERN_INFO "Wrong address mask " NIPQUAD_FMT " from "
-                                        "%s/" NIPQUAD_FMT "\n",
-                              NIPQUAD(*mp), dev->name, NIPQUAD(rt->rt_src));
+                       printk(KERN_INFO "Wrong address mask %pI4 from %s/%pI4\n",
+                              mp, dev->name, &rt->rt_src);
                }
        }
        rcu_read_unlock();
@@ -976,9 +972,10 @@ int icmp_rcv(struct sk_buff *skb)
        struct net *net = dev_net(rt->u.dst.dev);
 
        if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+               struct sec_path *sp = skb_sec_path(skb);
                int nh;
 
-               if (!(skb->sp && skb->sp->xvec[skb->sp->len - 1]->props.flags &
+               if (!(sp && sp->xvec[sp->len - 1]->props.flags &
                                 XFRM_STATE_ICMP))
                        goto drop;
 
index a0d86455c53e3a69fc24adc90fcfcc2e1d293571..f92733e15c9fc3300dd1aeb66bc99e2a9da37c17 100644 (file)
@@ -167,7 +167,7 @@ static __inline__ void igmp_stop_timer(struct ip_mc_list *im)
        spin_lock_bh(&im->lock);
        if (del_timer(&im->timer))
                atomic_dec(&im->refcnt);
-       im->tm_running=0;
+       im->tm_running = 0;
        im->reporter = 0;
        im->unsolicit_count = 0;
        spin_unlock_bh(&im->lock);
@@ -176,9 +176,9 @@ static __inline__ void igmp_stop_timer(struct ip_mc_list *im)
 /* It must be called with locked im->lock */
 static void igmp_start_timer(struct ip_mc_list *im, int max_delay)
 {
-       int tv=net_random() % max_delay;
+       int tv = net_random() % max_delay;
 
-       im->tm_running=1;
+       im->tm_running = 1;
        if (!mod_timer(&im->timer, jiffies+tv+2))
                atomic_inc(&im->refcnt);
 }
@@ -207,7 +207,7 @@ static void igmp_mod_timer(struct ip_mc_list *im, int max_delay)
        if (del_timer(&im->timer)) {
                if ((long)(im->timer.expires-jiffies) < max_delay) {
                        add_timer(&im->timer);
-                       im->tm_running=1;
+                       im->tm_running = 1;
                        spin_unlock_bh(&im->lock);
                        return;
                }
@@ -358,7 +358,7 @@ static int igmpv3_sendpack(struct sk_buff *skb)
 
 static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel)
 {
-       return sizeof(struct igmpv3_grec) + 4*igmp_scount(pmc,type,gdel,sdel);
+       return sizeof(struct igmpv3_grec) + 4*igmp_scount(pmc, type, gdel, sdel);
 }
 
 static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc,
@@ -653,7 +653,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
                return -1;
        }
 
-       skb=alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
+       skb = alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
        if (skb == NULL) {
                ip_rt_put(rt);
                return -1;
@@ -682,11 +682,11 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
        ((u8*)&iph[1])[3] = 0;
 
        ih = (struct igmphdr *)skb_put(skb, sizeof(struct igmphdr));
-       ih->type=type;
-       ih->code=0;
-       ih->csum=0;
-       ih->group=group;
-       ih->csum=ip_compute_csum((void *)ih, sizeof(struct igmphdr));
+       ih->type = type;
+       ih->code = 0;
+       ih->csum = 0;
+       ih->group = group;
+       ih->csum = ip_compute_csum((void *)ih, sizeof(struct igmphdr));
 
        return ip_local_out(skb);
 }
@@ -728,7 +728,7 @@ static void igmp_timer_expire(unsigned long data)
        struct in_device *in_dev = im->interface;
 
        spin_lock(&im->lock);
-       im->tm_running=0;
+       im->tm_running = 0;
 
        if (im->unsolicit_count) {
                im->unsolicit_count--;
@@ -997,7 +997,7 @@ static void ip_mc_filter_add(struct in_device *in_dev, __be32 addr)
           --ANK
           */
        if (arp_mc_map(addr, buf, dev, 0) == 0)
-               dev_mc_add(dev,buf,dev->addr_len,0);
+               dev_mc_add(dev, buf, dev->addr_len, 0);
 }
 
 /*
@@ -1010,7 +1010,7 @@ static void ip_mc_filter_del(struct in_device *in_dev, __be32 addr)
        struct net_device *dev = in_dev->dev;
 
        if (arp_mc_map(addr, buf, dev, 0) == 0)
-               dev_mc_delete(dev,buf,dev->addr_len,0);
+               dev_mc_delete(dev, buf, dev->addr_len, 0);
 }
 
 #ifdef CONFIG_IP_MULTICAST
@@ -1210,10 +1210,10 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
        if (!im)
                goto out;
 
-       im->users=1;
-       im->interface=in_dev;
+       im->users = 1;
+       im->interface = in_dev;
        in_dev_hold(in_dev);
-       im->multiaddr=addr;
+       im->multiaddr = addr;
        /* initial mode is (EX, empty) */
        im->sfmode = MCAST_EXCLUDE;
        im->sfcount[MCAST_INCLUDE] = 0;
@@ -1224,7 +1224,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
        atomic_set(&im->refcnt, 1);
        spin_lock_init(&im->lock);
 #ifdef CONFIG_IP_MULTICAST
-       im->tm_running=0;
+       im->tm_running = 0;
        setup_timer(&im->timer, &igmp_timer_expire, (unsigned long)im);
        im->unsolicit_count = IGMP_Unsolicited_Report_Count;
        im->reporter = 0;
@@ -1232,8 +1232,8 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
 #endif
        im->loaded = 0;
        write_lock_bh(&in_dev->mc_list_lock);
-       im->next=in_dev->mc_list;
-       in_dev->mc_list=im;
+       im->next = in_dev->mc_list;
+       in_dev->mc_list = im;
        in_dev->mc_count++;
        write_unlock_bh(&in_dev->mc_list_lock);
 #ifdef CONFIG_IP_MULTICAST
@@ -1279,7 +1279,7 @@ void ip_mc_dec_group(struct in_device *in_dev, __be32 addr)
        ASSERT_RTNL();
 
        for (ip=&in_dev->mc_list; (i=*ip)!=NULL; ip=&i->next) {
-               if (i->multiaddr==addr) {
+               if (i->multiaddr == addr) {
                        if (--i->users == 0) {
                                write_lock_bh(&in_dev->mc_list_lock);
                                *ip = i->next;
@@ -1738,7 +1738,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
 {
        int err;
        __be32 addr = imr->imr_multiaddr.s_addr;
-       struct ip_mc_socklist *iml=NULL, *i;
+       struct ip_mc_socklist *iml = NULL, *i;
        struct in_device *in_dev;
        struct inet_sock *inet = inet_sk(sk);
        struct net *net = sock_net(sk);
@@ -1769,7 +1769,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
        err = -ENOBUFS;
        if (count >= sysctl_igmp_max_memberships)
                goto done;
-       iml = sock_kmalloc(sk,sizeof(*iml),GFP_KERNEL);
+       iml = sock_kmalloc(sk, sizeof(*iml), GFP_KERNEL);
        if (iml == NULL)
                goto done;
 
index bd1278a2d828b30ddae3c4c9e98e06283201ceca..05af807ca9b9413efbb258d5da93102cc856d5df 100644 (file)
@@ -109,7 +109,7 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
                                        hashinfo->bhash_size)];
                        spin_lock(&head->lock);
                        inet_bind_bucket_for_each(tb, node, &head->chain)
-                               if (tb->ib_net == net && tb->port == rover)
+                               if (ib_net(tb) == net && tb->port == rover)
                                        goto next;
                        break;
                next:
@@ -137,7 +137,7 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
                                hashinfo->bhash_size)];
                spin_lock(&head->lock);
                inet_bind_bucket_for_each(tb, node, &head->chain)
-                       if (tb->ib_net == net && tb->port == snum)
+                       if (ib_net(tb) == net && tb->port == snum)
                                goto tb_found;
        }
        tb = NULL;
@@ -323,7 +323,7 @@ void inet_csk_reset_keepalive_timer(struct sock *sk, unsigned long len)
 
 EXPORT_SYMBOL(inet_csk_reset_keepalive_timer);
 
-struct dst_entryinet_csk_route_req(struct sock *sk,
+struct dst_entry *inet_csk_route_req(struct sock *sk,
                                     const struct request_sock *req)
 {
        struct rtable *rt;
index 564230dabcb8a7ff172bed468a4257dd0a11616f..41b36720e977a74ea554dda2117c26932fce1a82 100644 (file)
@@ -778,18 +778,19 @@ skip_listen_ht:
                struct inet_ehash_bucket *head = &hashinfo->ehash[i];
                rwlock_t *lock = inet_ehash_lockp(hashinfo, i);
                struct sock *sk;
-               struct hlist_node *node;
+               struct hlist_nulls_node *node;
 
                num = 0;
 
-               if (hlist_empty(&head->chain) && hlist_empty(&head->twchain))
+               if (hlist_nulls_empty(&head->chain) &&
+                       hlist_nulls_empty(&head->twchain))
                        continue;
 
                if (i > s_i)
                        s_num = 0;
 
                read_lock_bh(lock);
-               sk_for_each(sk, node, &head->chain) {
+               sk_nulls_for_each(sk, node, &head->chain) {
                        struct inet_sock *inet = inet_sk(sk);
 
                        if (num < s_num)
index 44981906fb913e7afbb4f7e03cd0192b9fdcda12..fd269cfef0ec8ff215c73dca6328064776398113 100644 (file)
@@ -35,7 +35,7 @@ struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
        struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, GFP_ATOMIC);
 
        if (tb != NULL) {
-               tb->ib_net       = hold_net(net);
+               write_pnet(&tb->ib_net, hold_net(net));
                tb->port      = snum;
                tb->fastreuse = 0;
                INIT_HLIST_HEAD(&tb->owners);
@@ -51,7 +51,7 @@ void inet_bind_bucket_destroy(struct kmem_cache *cachep, struct inet_bind_bucket
 {
        if (hlist_empty(&tb->owners)) {
                __hlist_del(&tb->node);
-               release_net(tb->ib_net);
+               release_net(ib_net(tb));
                kmem_cache_free(cachep, tb);
        }
 }
@@ -223,35 +223,65 @@ struct sock * __inet_lookup_established(struct net *net,
        INET_ADDR_COOKIE(acookie, saddr, daddr)
        const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
        struct sock *sk;
-       const struct hlist_node *node;
+       const struct hlist_nulls_node *node;
        /* Optimize here for direct hit, only listening connections can
         * have wildcards anyways.
         */
        unsigned int hash = inet_ehashfn(net, daddr, hnum, saddr, sport);
-       struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
-       rwlock_t *lock = inet_ehash_lockp(hashinfo, hash);
+       unsigned int slot = hash & (hashinfo->ehash_size - 1);
+       struct inet_ehash_bucket *head = &hashinfo->ehash[slot];
 
-       prefetch(head->chain.first);
-       read_lock(lock);
-       sk_for_each(sk, node, &head->chain) {
+       rcu_read_lock();
+begin:
+       sk_nulls_for_each_rcu(sk, node, &head->chain) {
                if (INET_MATCH(sk, net, hash, acookie,
-                                       saddr, daddr, ports, dif))
-                       goto hit; /* You sunk my battleship! */
+                                       saddr, daddr, ports, dif)) {
+                       if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt)))
+                               goto begintw;
+                       if (unlikely(!INET_MATCH(sk, net, hash, acookie,
+                               saddr, daddr, ports, dif))) {
+                               sock_put(sk);
+                               goto begin;
+                       }
+                       goto out;
+               }
        }
+       /*
+        * if the nulls value we got at the end of this lookup is
+        * not the expected one, we must restart lookup.
+        * We probably met an item that was moved to another chain.
+        */
+       if (get_nulls_value(node) != slot)
+               goto begin;
 
+begintw:
        /* Must check for a TIME_WAIT'er before going to listener hash. */
-       sk_for_each(sk, node, &head->twchain) {
+       sk_nulls_for_each_rcu(sk, node, &head->twchain) {
                if (INET_TW_MATCH(sk, net, hash, acookie,
-                                       saddr, daddr, ports, dif))
-                       goto hit;
+                                       saddr, daddr, ports, dif)) {
+                       if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) {
+                               sk = NULL;
+                               goto out;
+                       }
+                       if (unlikely(!INET_TW_MATCH(sk, net, hash, acookie,
+                                saddr, daddr, ports, dif))) {
+                               sock_put(sk);
+                               goto begintw;
+                       }
+                       goto out;
+               }
        }
+       /*
+        * if the nulls value we got at the end of this lookup is
+        * not the expected one, we must restart lookup.
+        * We probably met an item that was moved to another chain.
+        */
+       if (get_nulls_value(node) != slot)
+               goto begintw;
        sk = NULL;
 out:
-       read_unlock(lock);
+       rcu_read_unlock();
        return sk;
-hit:
-       sock_hold(sk);
-       goto out;
 }
 EXPORT_SYMBOL_GPL(__inet_lookup_established);
 
@@ -272,14 +302,14 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
        struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
        rwlock_t *lock = inet_ehash_lockp(hinfo, hash);
        struct sock *sk2;
-       const struct hlist_node *node;
+       const struct hlist_nulls_node *node;
        struct inet_timewait_sock *tw;
 
        prefetch(head->chain.first);
        write_lock(lock);
 
        /* Check TIME-WAIT sockets first. */
-       sk_for_each(sk2, node, &head->twchain) {
+       sk_nulls_for_each(sk2, node, &head->twchain) {
                tw = inet_twsk(sk2);
 
                if (INET_TW_MATCH(sk2, net, hash, acookie,
@@ -293,7 +323,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row,
        tw = NULL;
 
        /* And established part... */
-       sk_for_each(sk2, node, &head->chain) {
+       sk_nulls_for_each(sk2, node, &head->chain) {
                if (INET_MATCH(sk2, net, hash, acookie,
                                        saddr, daddr, ports, dif))
                        goto not_unique;
@@ -306,7 +336,7 @@ unique:
        inet->sport = htons(lport);
        sk->sk_hash = hash;
        WARN_ON(!sk_unhashed(sk));
-       __sk_add_node(sk, &head->chain);
+       __sk_nulls_add_node_rcu(sk, &head->chain);
        sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
        write_unlock(lock);
 
@@ -338,7 +368,7 @@ static inline u32 inet_sk_port_offset(const struct sock *sk)
 void __inet_hash_nolisten(struct sock *sk)
 {
        struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo;
-       struct hlist_head *list;
+       struct hlist_nulls_head *list;
        rwlock_t *lock;
        struct inet_ehash_bucket *head;
 
@@ -350,7 +380,7 @@ void __inet_hash_nolisten(struct sock *sk)
        lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
 
        write_lock(lock);
-       __sk_add_node(sk, list);
+       __sk_nulls_add_node_rcu(sk, list);
        sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
        write_unlock(lock);
 }
@@ -400,13 +430,15 @@ void inet_unhash(struct sock *sk)
                local_bh_disable();
                inet_listen_wlock(hashinfo);
                lock = &hashinfo->lhash_lock;
+               if (__sk_del_node_init(sk))
+                       sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
        } else {
                lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
                write_lock_bh(lock);
+               if (__sk_nulls_del_node_init_rcu(sk))
+                       sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
        }
 
-       if (__sk_del_node_init(sk))
-               sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
        write_unlock_bh(lock);
 out:
        if (sk->sk_state == TCP_LISTEN)
@@ -449,7 +481,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
                         * unique enough.
                         */
                        inet_bind_bucket_for_each(tb, node, &head->chain) {
-                               if (tb->ib_net == net && tb->port == port) {
+                               if (ib_net(tb) == net && tb->port == port) {
                                        WARN_ON(hlist_empty(&tb->owners));
                                        if (tb->fastreuse >= 0)
                                                goto next_port;
index 1c5fd38f8824a9a58cafc9220773b134c4a4b771..60689951ecdbd84d46ec4db4e8e5a72fe7e13401 100644 (file)
@@ -23,12 +23,12 @@ static void __inet_twsk_kill(struct inet_timewait_sock *tw,
        rwlock_t *lock = inet_ehash_lockp(hashinfo, tw->tw_hash);
 
        write_lock(lock);
-       if (hlist_unhashed(&tw->tw_node)) {
+       if (hlist_nulls_unhashed(&tw->tw_node)) {
                write_unlock(lock);
                return;
        }
-       __hlist_del(&tw->tw_node);
-       sk_node_init(&tw->tw_node);
+       hlist_nulls_del_rcu(&tw->tw_node);
+       sk_nulls_node_init(&tw->tw_node);
        write_unlock(lock);
 
        /* Disassociate with bind bucket. */
@@ -92,13 +92,17 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
 
        write_lock(lock);
 
-       /* Step 2: Remove SK from established hash. */
-       if (__sk_del_node_init(sk))
-               sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
-
-       /* Step 3: Hash TW into TIMEWAIT chain. */
-       inet_twsk_add_node(tw, &ehead->twchain);
+       /*
+        * Step 2: Hash TW into TIMEWAIT chain.
+        * Should be done before removing sk from established chain
+        * because readers are lockless and search established first.
+        */
        atomic_inc(&tw->tw_refcnt);
+       inet_twsk_add_node_rcu(tw, &ehead->twchain);
+
+       /* Step 3: Remove SK from established hash. */
+       if (__sk_nulls_del_node_init_rcu(sk))
+               sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
 
        write_unlock(lock);
 }
@@ -416,7 +420,7 @@ void inet_twsk_purge(struct net *net, struct inet_hashinfo *hashinfo,
 {
        struct inet_timewait_sock *tw;
        struct sock *sk;
-       struct hlist_node *node;
+       struct hlist_nulls_node *node;
        int h;
 
        local_bh_disable();
@@ -426,7 +430,7 @@ void inet_twsk_purge(struct net *net, struct inet_hashinfo *hashinfo,
                rwlock_t *lock = inet_ehash_lockp(hashinfo, h);
 restart:
                write_lock(lock);
-               sk_for_each(sk, node, &head->twchain) {
+               sk_nulls_for_each(sk, node, &head->twchain) {
 
                        tw = inet_twsk(sk);
                        if (!net_eq(twsk_net(tw), net) ||
index a456ceeac3f22519e5bac707a6c57d110c89e79a..b1fbe18feb5adf88a6bba3e1f8cdb6e4aae644f7 100644 (file)
@@ -144,7 +144,7 @@ static void unlink_from_unused(struct inet_peer *p)
  * _stack is known to be NULL or not at compile time,
  * so compiler will optimize the if (_stack) tests.
  */
-#define lookup(_daddr,_stack)                                  \
+#define lookup(_daddr, _stack)                                         \
 ({                                                             \
        struct inet_peer *u, **v;                               \
        if (_stack != NULL) {                                   \
index 450016b89a18ea04bcbbf10cfb6a8f6f0ada65d4..df3fe50bbf0dc0a76cebf690c4ec8697c7889d1d 100644 (file)
@@ -106,7 +106,7 @@ int ip_forward(struct sk_buff *skb)
         *      We now generate an ICMP HOST REDIRECT giving the route
         *      we calculated.
         */
-       if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr && !skb->sp)
+       if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr && !skb_sec_path(skb))
                ip_rt_send_redirect(skb);
 
        skb->priority = rt_tos2priority(iph->tos);
index e4f81f54befee04ad398f6e5a6e3877d388d65bf..6659ac000eeb81c72666a863177301df3ce59d7f 100644 (file)
@@ -56,7 +56,7 @@ struct ipfrag_skb_cb
        int                     offset;
 };
 
-#define FRAG_CB(skb)   ((struct ipfrag_skb_cb*)((skb)->cb))
+#define FRAG_CB(skb)   ((struct ipfrag_skb_cb *)((skb)->cb))
 
 /* Describe an entry in the "incomplete datagrams" queue. */
 struct ipq {
@@ -559,9 +559,8 @@ out_nomem:
        goto out_fail;
 out_oversize:
        if (net_ratelimit())
-               printk(KERN_INFO
-                       "Oversized IP packet from " NIPQUAD_FMT ".\n",
-                       NIPQUAD(qp->saddr));
+               printk(KERN_INFO "Oversized IP packet from %pI4.\n",
+                       &qp->saddr);
 out_fail:
        IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_REASMFAILS);
        return err;
@@ -608,7 +607,7 @@ static struct ctl_table ip4_frags_ns_ctl_table[] = {
                .data           = &init_net.ipv4.frags.high_thresh,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_IPFRAG_LOW_THRESH,
@@ -616,7 +615,7 @@ static struct ctl_table ip4_frags_ns_ctl_table[] = {
                .data           = &init_net.ipv4.frags.low_thresh,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_IPFRAG_TIME,
@@ -624,8 +623,8 @@ static struct ctl_table ip4_frags_ns_ctl_table[] = {
                .data           = &init_net.ipv4.frags.timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies
        },
        { }
 };
@@ -637,15 +636,15 @@ static struct ctl_table ip4_frags_ctl_table[] = {
                .data           = &ip4_frags.secret_interval,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies
        },
        {
                .procname       = "ipfrag_max_dist",
                .data           = &sysctl_ipfrag_max_dist,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
+               .proc_handler   = proc_dointvec_minmax,
                .extra1         = &zero
        },
        { }
index 85c487b8572b726a365e869a92e8ad00669d76b7..191ef7588134b501571d8922d96fded4697170b6 100644 (file)
@@ -371,7 +371,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
    by themself???
  */
 
-       struct iphdr *iph = (struct iphdr*)skb->data;
+       struct iphdr *iph = (struct iphdr *)skb->data;
        __be16       *p = (__be16*)(skb->data+(iph->ihl<<2));
        int grehlen = (iph->ihl<<2) + 4;
        const int type = icmp_hdr(skb)->type;
@@ -632,7 +632,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (dev->header_ops && dev->type == ARPHRD_IPGRE) {
                gre_hlen = 0;
-               tiph = (struct iphdr*)skb->data;
+               tiph = (struct iphdr *)skb->data;
        } else {
                gre_hlen = tunnel->hlen;
                tiph = &tunnel->parms.iph;
@@ -660,7 +660,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
                        if (neigh == NULL)
                                goto tx_error;
 
-                       addr6 = (struct in6_addr*)&neigh->primary_key;
+                       addr6 = (struct in6_addr *)&neigh->primary_key;
                        addr_type = ipv6_addr_type(addr6);
 
                        if (addr_type == IPV6_ADDR_ANY) {
@@ -726,7 +726,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 #ifdef CONFIG_IPV6
        else if (skb->protocol == htons(ETH_P_IPV6)) {
-               struct rt6_info *rt6 = (struct rt6_info*)skb->dst;
+               struct rt6_info *rt6 = (struct rt6_info *)skb->dst;
 
                if (rt6 && mtu < dst_mtu(skb->dst) && mtu >= IPV6_MIN_MTU) {
                        if ((tunnel->parms.iph.daddr &&
@@ -800,7 +800,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
                        iph->ttl = old_iph->ttl;
 #ifdef CONFIG_IPV6
                else if (skb->protocol == htons(ETH_P_IPV6))
-                       iph->ttl = ((struct ipv6hdr*)old_iph)->hop_limit;
+                       iph->ttl = ((struct ipv6hdr *)old_iph)->hop_limit;
 #endif
                else
                        iph->ttl = dst_metric(&rt->u.dst, RTAX_HOPLIMIT);
@@ -962,7 +962,7 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
                                        break;
                                }
                        } else {
-                               unsigned nflags=0;
+                               unsigned nflags = 0;
 
                                t = netdev_priv(dev);
 
@@ -1104,7 +1104,7 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
 
 static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr)
 {
-       struct iphdr *iph = (struct iphdr*) skb_mac_header(skb);
+       struct iphdr *iph = (struct iphdr *) skb_mac_header(skb);
        memcpy(haddr, &iph->saddr, 4);
        return 4;
 }
index cfb38ac9d698b933cc64a5cd5dbb42298ba07056..1a58a6fa1dc01d1c9eefd48dbb56c5017cec0689 100644 (file)
@@ -302,10 +302,8 @@ static inline int ip_rcv_options(struct sk_buff *skb)
                        if (!IN_DEV_SOURCE_ROUTE(in_dev)) {
                                if (IN_DEV_LOG_MARTIANS(in_dev) &&
                                    net_ratelimit())
-                                       printk(KERN_INFO "source route option "
-                                              NIPQUAD_FMT " -> " NIPQUAD_FMT "\n",
-                                              NIPQUAD(iph->saddr),
-                                              NIPQUAD(iph->daddr));
+                                       printk(KERN_INFO "source route option %pI4 -> %pI4\n",
+                                              &iph->saddr, &iph->daddr);
                                in_dev_put(in_dev);
                                goto drop;
                        }
@@ -350,9 +348,9 @@ static int ip_rcv_finish(struct sk_buff *skb)
                struct ip_rt_acct *st = per_cpu_ptr(ip_rt_acct, smp_processor_id());
                u32 idx = skb->dst->tclassid;
                st[idx&0xFF].o_packets++;
-               st[idx&0xFF].o_bytes+=skb->len;
+               st[idx&0xFF].o_bytes += skb->len;
                st[(idx>>16)&0xFF].i_packets++;
-               st[(idx>>16)&0xFF].i_bytes+=skb->len;
+               st[(idx>>16)&0xFF].i_bytes += skb->len;
        }
 #endif
 
index d2a8f8bb78a677e5be6b9e39a4f2fe7c3b181a27..46d7be233eac9132e6e023c492b36b535e9bb1df 100644 (file)
@@ -430,7 +430,7 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
  *     single device frame, and queue such a frame for sending.
  */
 
-int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
+int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 {
        struct iphdr *iph;
        int raw = 0;
@@ -720,7 +720,7 @@ static inline int ip_ufo_append_data(struct sock *sk,
                        int getfrag(void *from, char *to, int offset, int len,
                               int odd, struct sk_buff *skb),
                        void *from, int length, int hh_len, int fragheaderlen,
-                       int transhdrlen, int mtu,unsigned int flags)
+                       int transhdrlen, int mtu, unsigned int flags)
 {
        struct sk_buff *skb;
        int err;
@@ -741,7 +741,7 @@ static inline int ip_ufo_append_data(struct sock *sk,
                skb_reserve(skb, hh_len);
 
                /* create space for UDP/IP header */
-               skb_put(skb,fragheaderlen + transhdrlen);
+               skb_put(skb, fragheaderlen + transhdrlen);
 
                /* initialize network header pointer */
                skb_reset_network_header(skb);
index 465abf0a9869c768ab7b7f0832050a2a0812f05c..624b534201e2633a79519f8a8980a7130a356ac8 100644 (file)
@@ -48,6 +48,7 @@
 #define IP_CMSG_RECVOPTS       8
 #define IP_CMSG_RETOPTS                16
 #define IP_CMSG_PASSSEC                32
+#define IP_CMSG_ORIGDSTADDR     64
 
 /*
  *     SOL_IP control messages.
@@ -94,7 +95,7 @@ static void ip_cmsg_recv_opts(struct msghdr *msg, struct sk_buff *skb)
 static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb)
 {
        unsigned char optbuf[sizeof(struct ip_options) + 40];
-       struct ip_options * opt = (struct ip_options*)optbuf;
+       struct ip_options * opt = (struct ip_options *)optbuf;
 
        if (IPCB(skb)->opt.optlen == 0)
                return;
@@ -126,6 +127,27 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
        security_release_secctx(secdata, seclen);
 }
 
+void ip_cmsg_recv_dstaddr(struct msghdr *msg, struct sk_buff *skb)
+{
+       struct sockaddr_in sin;
+       struct iphdr *iph = ip_hdr(skb);
+       u16 *ports = (u16 *) skb_transport_header(skb);
+
+       if (skb_transport_offset(skb) + 4 > skb->len)
+               return;
+
+       /* All current transport protocols have the port numbers in the
+        * first four bytes of the transport header and this function is
+        * written with this assumption in mind.
+        */
+
+       sin.sin_family = AF_INET;
+       sin.sin_addr.s_addr = iph->daddr;
+       sin.sin_port = ports[1];
+       memset(sin.sin_zero, 0, sizeof(sin.sin_zero));
+
+       put_cmsg(msg, SOL_IP, IP_ORIGDSTADDR, sizeof(sin), &sin);
+}
 
 void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
 {
@@ -160,6 +182,12 @@ void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
 
        if (flags & 1)
                ip_cmsg_recv_security(msg, skb);
+
+       if ((flags>>=1) == 0)
+               return;
+       if (flags & 1)
+               ip_cmsg_recv_dstaddr(msg, skb);
+
 }
 
 int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc)
@@ -411,7 +439,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                            int optname, char __user *optval, int optlen)
 {
        struct inet_sock *inet = inet_sk(sk);
-       int val=0,err;
+       int val = 0, err;
 
        if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) |
                             (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) |
@@ -421,7 +449,8 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                             (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
                             (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) ||
            optname == IP_MULTICAST_TTL ||
-           optname == IP_MULTICAST_LOOP) {
+           optname == IP_MULTICAST_LOOP ||
+           optname == IP_RECVORIGDSTADDR) {
                if (optlen >= sizeof(int)) {
                        if (get_user(val, (int __user *) optval))
                                return -EFAULT;
@@ -437,7 +466,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
        /* If optlen==0, it is equivalent to val == 0 */
 
        if (ip_mroute_opt(optname))
-               return ip_mroute_setsockopt(sk,optname,optval,optlen);
+               return ip_mroute_setsockopt(sk, optname, optval, optlen);
 
        err = 0;
        lock_sock(sk);
@@ -509,6 +538,12 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                else
                        inet->cmsg_flags &= ~IP_CMSG_PASSSEC;
                break;
+       case IP_RECVORIGDSTADDR:
+               if (val)
+                       inet->cmsg_flags |= IP_CMSG_ORIGDSTADDR;
+               else
+                       inet->cmsg_flags &= ~IP_CMSG_ORIGDSTADDR;
+               break;
        case IP_TOS:    /* This sets both TOS and Precedence */
                if (sk->sk_type == SOCK_STREAM) {
                        val &= ~3;
@@ -549,7 +584,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                        goto e_inval;
                if (optlen<1)
                        goto e_inval;
-               if (val==-1)
+               if (val == -1)
                        val = 1;
                if (val < 0 || val > 255)
                        goto e_inval;
@@ -573,12 +608,12 @@ static int do_ip_setsockopt(struct sock *sk, int level,
 
                err = -EFAULT;
                if (optlen >= sizeof(struct ip_mreqn)) {
-                       if (copy_from_user(&mreq,optval,sizeof(mreq)))
+                       if (copy_from_user(&mreq, optval, sizeof(mreq)))
                                break;
                } else {
                        memset(&mreq, 0, sizeof(mreq));
                        if (optlen >= sizeof(struct in_addr) &&
-                           copy_from_user(&mreq.imr_address,optval,sizeof(struct in_addr)))
+                           copy_from_user(&mreq.imr_address, optval, sizeof(struct in_addr)))
                                break;
                }
 
@@ -626,11 +661,11 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                        goto e_inval;
                err = -EFAULT;
                if (optlen >= sizeof(struct ip_mreqn)) {
-                       if (copy_from_user(&mreq,optval,sizeof(mreq)))
+                       if (copy_from_user(&mreq, optval, sizeof(mreq)))
                                break;
                } else {
                        memset(&mreq, 0, sizeof(mreq));
-                       if (copy_from_user(&mreq,optval,sizeof(struct ip_mreq)))
+                       if (copy_from_user(&mreq, optval, sizeof(struct ip_mreq)))
                                break;
                }
 
@@ -808,7 +843,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                        err = -ENOBUFS;
                        break;
                }
-               gsf = kmalloc(optlen,GFP_KERNEL);
+               gsf = kmalloc(optlen, GFP_KERNEL);
                if (!gsf) {
                        err = -ENOBUFS;
                        break;
@@ -828,7 +863,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                        goto mc_msf_out;
                }
                msize = IP_MSFILTER_SIZE(gsf->gf_numsrc);
-               msf = kmalloc(msize,GFP_KERNEL);
+               msf = kmalloc(msize, GFP_KERNEL);
                if (!msf) {
                        err = -ENOBUFS;
                        goto mc_msf_out;
@@ -971,9 +1006,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
                return -EOPNOTSUPP;
 
        if (ip_mroute_opt(optname))
-               return ip_mroute_getsockopt(sk,optname,optval,optlen);
+               return ip_mroute_getsockopt(sk, optname, optval, optlen);
 
-       if (get_user(len,optlen))
+       if (get_user(len, optlen))
                return -EFAULT;
        if (len < 0)
                return -EINVAL;
@@ -984,7 +1019,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
        case IP_OPTIONS:
        {
                unsigned char optbuf[sizeof(struct ip_options)+40];
-               struct ip_options * opt = (struct ip_options*)optbuf;
+               struct ip_options * opt = (struct ip_options *)optbuf;
                opt->optlen = 0;
                if (inet->opt)
                        memcpy(optbuf, inet->opt,
@@ -1022,6 +1057,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
        case IP_PASSSEC:
                val = (inet->cmsg_flags & IP_CMSG_PASSSEC) != 0;
                break;
+       case IP_RECVORIGDSTADDR:
+               val = (inet->cmsg_flags & IP_CMSG_ORIGDSTADDR) != 0;
+               break;
        case IP_TOS:
                val = inet->tos;
                break;
@@ -1154,13 +1192,13 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
                len = 1;
                if (put_user(len, optlen))
                        return -EFAULT;
-               if (copy_to_user(optval,&ucval,1))
+               if (copy_to_user(optval, &ucval, 1))
                        return -EFAULT;
        } else {
                len = min_t(unsigned int, sizeof(int), len);
                if (put_user(len, optlen))
                        return -EFAULT;
-               if (copy_to_user(optval,&val,len))
+               if (copy_to_user(optval, &val, len))
                        return -EFAULT;
        }
        return 0;
@@ -1178,7 +1216,7 @@ int ip_getsockopt(struct sock *sk, int level,
                        !ip_mroute_opt(optname)) {
                int len;
 
-               if (get_user(len,optlen))
+               if (get_user(len, optlen))
                        return -EFAULT;
 
                lock_sock(sk);
index 38ccb6dfb02e1c755f8ec03f6d793ec16121784f..ec8264ae45c265b831cd3ddce82e5e877a69c70f 100644 (file)
@@ -39,8 +39,8 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)
                              spi, IPPROTO_COMP, AF_INET);
        if (!x)
                return;
-       NETDEBUG(KERN_DEBUG "pmtu discovery on SA IPCOMP/%08x/" NIPQUAD_FMT "\n",
-                spi, NIPQUAD(iph->daddr));
+       NETDEBUG(KERN_DEBUG "pmtu discovery on SA IPCOMP/%08x/%pI4\n",
+                spi, &iph->daddr);
        xfrm_state_put(x);
 }
 
index 42065fff46c439809c368cd84a9cb83ba5fb22c5..42a0f3dd3fd64323ac9a087895dbbaaff822e7cd 100644 (file)
@@ -374,7 +374,7 @@ static int __init ic_defaults(void)
         */
 
        if (!ic_host_name_set)
-               sprintf(init_utsname()->nodename, NIPQUAD_FMT, NIPQUAD(ic_myaddr));
+               sprintf(init_utsname()->nodename, "%pI4", &ic_myaddr);
 
        if (root_server_addr == NONE)
                root_server_addr = ic_servaddr;
@@ -387,11 +387,11 @@ static int __init ic_defaults(void)
                else if (IN_CLASSC(ntohl(ic_myaddr)))
                        ic_netmask = htonl(IN_CLASSC_NET);
                else {
-                       printk(KERN_ERR "IP-Config: Unable to guess netmask for address " NIPQUAD_FMT "\n",
-                               NIPQUAD(ic_myaddr));
+                       printk(KERN_ERR "IP-Config: Unable to guess netmask for address %pI4\n",
+                               &ic_myaddr);
                        return -1;
                }
-               printk("IP-Config: Guessing netmask " NIPQUAD_FMT "\n", NIPQUAD(ic_netmask));
+               printk("IP-Config: Guessing netmask %pI4\n", &ic_netmask);
        }
 
        return 0;
@@ -979,10 +979,8 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
                                ic_myaddr = b->your_ip;
                                ic_servaddr = server_id;
 #ifdef IPCONFIG_DEBUG
-                               printk("DHCP: Offered address " NIPQUAD_FMT,
-                                      NIPQUAD(ic_myaddr));
-                               printk(" by server " NIPQUAD_FMT "\n",
-                                      NIPQUAD(ic_servaddr));
+                               printk("DHCP: Offered address %pI4 by server %pI4\n",
+                                      &ic_myaddr, &ic_servaddr);
 #endif
                                /* The DHCP indicated server address takes
                                 * precedence over the bootp header one if
@@ -1177,11 +1175,11 @@ static int __init ic_dynamic(void)
                return -1;
        }
 
-       printk("IP-Config: Got %s answer from " NIPQUAD_FMT ", ",
+       printk("IP-Config: Got %s answer from %pI4, ",
                ((ic_got_reply & IC_RARP) ? "RARP"
                 : (ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP"),
-               NIPQUAD(ic_servaddr));
-       printk("my address is " NIPQUAD_FMT "\n", NIPQUAD(ic_myaddr));
+               &ic_servaddr);
+       printk("my address is %pI4\n", &ic_myaddr);
 
        return 0;
 }
@@ -1206,14 +1204,12 @@ static int pnp_seq_show(struct seq_file *seq, void *v)
                           "domain %s\n", ic_domain);
        for (i = 0; i < CONF_NAMESERVERS_MAX; i++) {
                if (ic_nameservers[i] != NONE)
-                       seq_printf(seq,
-                                  "nameserver " NIPQUAD_FMT "\n",
-                                  NIPQUAD(ic_nameservers[i]));
+                       seq_printf(seq, "nameserver %pI4\n",
+                                  &ic_nameservers[i]);
        }
        if (ic_servaddr != NONE)
-               seq_printf(seq,
-                          "bootserver " NIPQUAD_FMT "\n",
-                          NIPQUAD(ic_servaddr));
+               seq_printf(seq, "bootserver %pI4\n",
+                          &ic_servaddr);
        return 0;
 }
 
@@ -1387,13 +1383,13 @@ static int __init ip_auto_config(void)
         */
        printk("IP-Config: Complete:");
        printk("\n     device=%s", ic_dev->name);
-       printk(", addr=" NIPQUAD_FMT, NIPQUAD(ic_myaddr));
-       printk(", mask=" NIPQUAD_FMT, NIPQUAD(ic_netmask));
-       printk(", gw=" NIPQUAD_FMT, NIPQUAD(ic_gateway));
+       printk(", addr=%pI4", &ic_myaddr);
+       printk(", mask=%pI4", &ic_netmask);
+       printk(", gw=%pI4", &ic_gateway);
        printk(",\n     host=%s, domain=%s, nis-domain=%s",
               utsname()->nodename, ic_domain, utsname()->domainname);
-       printk(",\n     bootserver=" NIPQUAD_FMT, NIPQUAD(ic_servaddr));
-       printk(", rootserver=" NIPQUAD_FMT, NIPQUAD(root_server_addr));
+       printk(",\n     bootserver=%pI4", &ic_servaddr);
+       printk(", rootserver=%pI4", &root_server_addr);
        printk(", rootpath=%s", root_server_path);
        printk("\n");
 #endif /* !SILENT */
index 29609d29df769350e9d1683209b372a422e9cd3d..b3c3d7b0d1168ddc69f7c911d90b3f097e3b1e2a 100644 (file)
@@ -281,7 +281,7 @@ static int ipip_err(struct sk_buff *skb, u32 info)
    8 bytes of packet payload. It means, that precise relaying of
    ICMP in the real Internet is absolutely infeasible.
  */
-       struct iphdr *iph = (struct iphdr*)skb->data;
+       struct iphdr *iph = (struct iphdr *)skb->data;
        const int type = icmp_hdr(skb)->type;
        const int code = icmp_hdr(skb)->code;
        struct ip_tunnel *t;
index b42e082cc17048ddcdee7103f933c6123c663111..05ed336f798aad2782a909290d32390842aa9a26 100644 (file)
@@ -331,7 +331,7 @@ static void ipmr_destroy_unres(struct mfc_cache *c)
 
        atomic_dec(&cache_resolve_queue_len);
 
-       while ((skb=skb_dequeue(&c->mfc_un.unres.unresolved))) {
+       while ((skb = skb_dequeue(&c->mfc_un.unres.unresolved))) {
                if (ip_hdr(skb)->version == 0) {
                        struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr));
                        nlh->nlmsg_type = NLMSG_ERROR;
@@ -477,13 +477,13 @@ static int vif_add(struct vifctl *vifc, int mrtsock)
        /*
         *      Fill in the VIF structures
         */
-       v->rate_limit=vifc->vifc_rate_limit;
-       v->local=vifc->vifc_lcl_addr.s_addr;
-       v->remote=vifc->vifc_rmt_addr.s_addr;
-       v->flags=vifc->vifc_flags;
+       v->rate_limit = vifc->vifc_rate_limit;
+       v->local = vifc->vifc_lcl_addr.s_addr;
+       v->remote = vifc->vifc_rmt_addr.s_addr;
+       v->flags = vifc->vifc_flags;
        if (!mrtsock)
                v->flags |= VIFF_STATIC;
-       v->threshold=vifc->vifc_threshold;
+       v->threshold = vifc->vifc_threshold;
        v->bytes_in = 0;
        v->bytes_out = 0;
        v->pkt_in = 0;
@@ -494,7 +494,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock)
 
        /* And finish update writing critical data */
        write_lock_bh(&mrt_lock);
-       v->dev=dev;
+       v->dev = dev;
 #ifdef CONFIG_IP_PIMSM
        if (v->flags&VIFF_REGISTER)
                reg_vif_num = vifi;
@@ -507,7 +507,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock)
 
 static struct mfc_cache *ipmr_cache_find(__be32 origin, __be32 mcastgrp)
 {
-       int line=MFC_HASH(mcastgrp,origin);
+       int line = MFC_HASH(mcastgrp, origin);
        struct mfc_cache *c;
 
        for (c=mfc_cache_array[line]; c; c = c->next) {
@@ -522,8 +522,8 @@ static struct mfc_cache *ipmr_cache_find(__be32 origin, __be32 mcastgrp)
  */
 static struct mfc_cache *ipmr_cache_alloc(void)
 {
-       struct mfc_cache *c=kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
-       if (c==NULL)
+       struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
+       if (c == NULL)
                return NULL;
        c->mfc_un.res.minvif = MAXVIFS;
        return c;
@@ -531,8 +531,8 @@ static struct mfc_cache *ipmr_cache_alloc(void)
 
 static struct mfc_cache *ipmr_cache_alloc_unres(void)
 {
-       struct mfc_cache *c=kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
-       if (c==NULL)
+       struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
+       if (c == NULL)
                return NULL;
        skb_queue_head_init(&c->mfc_un.unres.unresolved);
        c->mfc_un.unres.expires = jiffies + 10*HZ;
@@ -552,7 +552,7 @@ static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c)
         *      Play the pending entries through our router
         */
 
-       while ((skb=__skb_dequeue(&uc->mfc_un.unres.unresolved))) {
+       while ((skb = __skb_dequeue(&uc->mfc_un.unres.unresolved))) {
                if (ip_hdr(skb)->version == 0) {
                        struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr));
 
@@ -637,7 +637,7 @@ static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert)
         *      Add our header
         */
 
-       igmp=(struct igmphdr *)skb_put(skb,sizeof(struct igmphdr));
+       igmp=(struct igmphdr *)skb_put(skb, sizeof(struct igmphdr));
        igmp->type      =
        msg->im_msgtype = assert;
        igmp->code      =       0;
@@ -653,7 +653,7 @@ static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert)
        /*
         *      Deliver to mrouted
         */
-       if ((ret=sock_queue_rcv_skb(mroute_socket,skb))<0) {
+       if ((ret = sock_queue_rcv_skb(mroute_socket, skb))<0) {
                if (net_ratelimit())
                        printk(KERN_WARNING "mroute: pending queue full, dropping entries.\n");
                kfree_skb(skb);
@@ -685,7 +685,7 @@ ipmr_cache_unresolved(vifi_t vifi, struct sk_buff *skb)
                 *      Create a new entry if allowable
                 */
 
-               if (atomic_read(&cache_resolve_queue_len)>=10 ||
+               if (atomic_read(&cache_resolve_queue_len) >= 10 ||
                    (c=ipmr_cache_alloc_unres())==NULL) {
                        spin_unlock_bh(&mfc_unres_lock);
 
@@ -728,7 +728,7 @@ ipmr_cache_unresolved(vifi_t vifi, struct sk_buff *skb)
                kfree_skb(skb);
                err = -ENOBUFS;
        } else {
-               skb_queue_tail(&c->mfc_un.unres.unresolved,skb);
+               skb_queue_tail(&c->mfc_un.unres.unresolved, skb);
                err = 0;
        }
 
@@ -745,7 +745,7 @@ static int ipmr_mfc_delete(struct mfcctl *mfc)
        int line;
        struct mfc_cache *c, **cp;
 
-       line=MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr);
+       line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr);
 
        for (cp=&mfc_cache_array[line]; (c=*cp) != NULL; cp = &c->next) {
                if (c->mfc_origin == mfc->mfcc_origin.s_addr &&
@@ -766,7 +766,7 @@ static int ipmr_mfc_add(struct mfcctl *mfc, int mrtsock)
        int line;
        struct mfc_cache *uc, *c, **cp;
 
-       line=MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr);
+       line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr);
 
        for (cp=&mfc_cache_array[line]; (c=*cp) != NULL; cp = &c->next) {
                if (c->mfc_origin == mfc->mfcc_origin.s_addr &&
@@ -787,13 +787,13 @@ static int ipmr_mfc_add(struct mfcctl *mfc, int mrtsock)
        if (!ipv4_is_multicast(mfc->mfcc_mcastgrp.s_addr))
                return -EINVAL;
 
-       c=ipmr_cache_alloc();
-       if (c==NULL)
+       c = ipmr_cache_alloc();
+       if (c == NULL)
                return -ENOMEM;
 
-       c->mfc_origin=mfc->mfcc_origin.s_addr;
-       c->mfc_mcastgrp=mfc->mfcc_mcastgrp.s_addr;
-       c->mfc_parent=mfc->mfcc_parent;
+       c->mfc_origin = mfc->mfcc_origin.s_addr;
+       c->mfc_mcastgrp = mfc->mfcc_mcastgrp.s_addr;
+       c->mfc_parent = mfc->mfcc_parent;
        ipmr_update_thresholds(c, mfc->mfcc_ttls);
        if (!mrtsock)
                c->mfc_flags |= MFC_STATIC;
@@ -846,7 +846,7 @@ static void mroute_clean_tables(struct sock *sk)
        /*
         *      Wipe the cache
         */
-       for (i=0;i<MFC_LINES;i++) {
+       for (i=0; i<MFC_LINES; i++) {
                struct mfc_cache *c, **cp;
 
                cp = &mfc_cache_array[i];
@@ -887,7 +887,7 @@ static void mrtsock_destruct(struct sock *sk)
                IPV4_DEVCONF_ALL(sock_net(sk), MC_FORWARDING)--;
 
                write_lock_bh(&mrt_lock);
-               mroute_socket=NULL;
+               mroute_socket = NULL;
                write_unlock_bh(&mrt_lock);
 
                mroute_clean_tables(sk);
@@ -902,7 +902,7 @@ static void mrtsock_destruct(struct sock *sk)
  *     MOSPF/PIM router set up we can clean this up.
  */
 
-int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int optlen)
+int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int optlen)
 {
        int ret;
        struct vifctl vif;
@@ -918,7 +918,7 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt
                if (sk->sk_type != SOCK_RAW ||
                    inet_sk(sk)->num != IPPROTO_IGMP)
                        return -EOPNOTSUPP;
-               if (optlen!=sizeof(int))
+               if (optlen != sizeof(int))
                        return -ENOPROTOOPT;
 
                rtnl_lock();
@@ -930,7 +930,7 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt
                ret = ip_ra_control(sk, 1, mrtsock_destruct);
                if (ret == 0) {
                        write_lock_bh(&mrt_lock);
-                       mroute_socket=sk;
+                       mroute_socket = sk;
                        write_unlock_bh(&mrt_lock);
 
                        IPV4_DEVCONF_ALL(sock_net(sk), MC_FORWARDING)++;
@@ -938,19 +938,19 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt
                rtnl_unlock();
                return ret;
        case MRT_DONE:
-               if (sk!=mroute_socket)
+               if (sk != mroute_socket)
                        return -EACCES;
                return ip_ra_control(sk, 0, NULL);
        case MRT_ADD_VIF:
        case MRT_DEL_VIF:
-               if (optlen!=sizeof(vif))
+               if (optlen != sizeof(vif))
                        return -EINVAL;
-               if (copy_from_user(&vif,optval,sizeof(vif)))
+               if (copy_from_user(&vif, optval, sizeof(vif)))
                        return -EFAULT;
                if (vif.vifc_vifi >= MAXVIFS)
                        return -ENFILE;
                rtnl_lock();
-               if (optname==MRT_ADD_VIF) {
+               if (optname == MRT_ADD_VIF) {
                        ret = vif_add(&vif, sk==mroute_socket);
                } else {
                        ret = vif_delete(vif.vifc_vifi, 0);
@@ -964,12 +964,12 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt
                 */
        case MRT_ADD_MFC:
        case MRT_DEL_MFC:
-               if (optlen!=sizeof(mfc))
+               if (optlen != sizeof(mfc))
                        return -EINVAL;
-               if (copy_from_user(&mfc,optval, sizeof(mfc)))
+               if (copy_from_user(&mfc, optval, sizeof(mfc)))
                        return -EFAULT;
                rtnl_lock();
-               if (optname==MRT_DEL_MFC)
+               if (optname == MRT_DEL_MFC)
                        ret = ipmr_mfc_delete(&mfc);
                else
                        ret = ipmr_mfc_add(&mfc, sk==mroute_socket);
@@ -1028,12 +1028,12 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt
  *     Getsock opt support for the multicast routing system.
  */
 
-int ip_mroute_getsockopt(struct sock *sk,int optname,char __user *optval,int __user *optlen)
+int ip_mroute_getsockopt(struct sock *sk, int optname, char __user *optval, int __user *optlen)
 {
        int olr;
        int val;
 
-       if (optname!=MRT_VERSION &&
+       if (optname != MRT_VERSION &&
 #ifdef CONFIG_IP_PIMSM
           optname!=MRT_PIM &&
 #endif
@@ -1047,17 +1047,17 @@ int ip_mroute_getsockopt(struct sock *sk,int optname,char __user *optval,int __u
        if (olr < 0)
                return -EINVAL;
 
-       if (put_user(olr,optlen))
+       if (put_user(olr, optlen))
                return -EFAULT;
-       if (optname==MRT_VERSION)
-               val=0x0305;
+       if (optname == MRT_VERSION)
+               val = 0x0305;
 #ifdef CONFIG_IP_PIMSM
-       else if (optname==MRT_PIM)
-               val=mroute_do_pim;
+       else if (optname == MRT_PIM)
+               val = mroute_do_pim;
 #endif
        else
-               val=mroute_do_assert;
-       if (copy_to_user(optval,&val,olr))
+               val = mroute_do_assert;
+       if (copy_to_user(optval, &val, olr))
                return -EFAULT;
        return 0;
 }
@@ -1075,27 +1075,27 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
 
        switch (cmd) {
        case SIOCGETVIFCNT:
-               if (copy_from_user(&vr,arg,sizeof(vr)))
+               if (copy_from_user(&vr, arg, sizeof(vr)))
                        return -EFAULT;
-               if (vr.vifi>=maxvif)
+               if (vr.vifi >= maxvif)
                        return -EINVAL;
                read_lock(&mrt_lock);
                vif=&vif_table[vr.vifi];
                if (VIF_EXISTS(vr.vifi))        {
-                       vr.icount=vif->pkt_in;
-                       vr.ocount=vif->pkt_out;
-                       vr.ibytes=vif->bytes_in;
-                       vr.obytes=vif->bytes_out;
+                       vr.icount = vif->pkt_in;
+                       vr.ocount = vif->pkt_out;
+                       vr.ibytes = vif->bytes_in;
+                       vr.obytes = vif->bytes_out;
                        read_unlock(&mrt_lock);
 
-                       if (copy_to_user(arg,&vr,sizeof(vr)))
+                       if (copy_to_user(arg, &vr, sizeof(vr)))
                                return -EFAULT;
                        return 0;
                }
                read_unlock(&mrt_lock);
                return -EADDRNOTAVAIL;
        case SIOCGETSGCNT:
-               if (copy_from_user(&sr,arg,sizeof(sr)))
+               if (copy_from_user(&sr, arg, sizeof(sr)))
                        return -EFAULT;
 
                read_lock(&mrt_lock);
@@ -1106,7 +1106,7 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
                        sr.wrong_if = c->mfc_un.res.wrong_if;
                        read_unlock(&mrt_lock);
 
-                       if (copy_to_user(arg,&sr,sizeof(sr)))
+                       if (copy_to_user(arg, &sr, sizeof(sr)))
                                return -EFAULT;
                        return 0;
                }
@@ -1130,15 +1130,15 @@ static int ipmr_device_event(struct notifier_block *this, unsigned long event, v
        if (event != NETDEV_UNREGISTER)
                return NOTIFY_DONE;
        v=&vif_table[0];
-       for (ct=0;ct<maxvif;ct++,v++) {
-               if (v->dev==dev)
+       for (ct=0; ct<maxvif; ct++,v++) {
+               if (v->dev == dev)
                        vif_delete(ct, 1);
        }
        return NOTIFY_DONE;
 }
 
 
-static struct notifier_block ip_mr_notifier={
+static struct notifier_block ip_mr_notifier = {
        .notifier_call = ipmr_device_event,
 };
 
@@ -1204,7 +1204,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
 #ifdef CONFIG_IP_PIMSM
        if (vif->flags & VIFF_REGISTER) {
                vif->pkt_out++;
-               vif->bytes_out+=skb->len;
+               vif->bytes_out += skb->len;
                vif->dev->stats.tx_bytes += skb->len;
                vif->dev->stats.tx_packets++;
                ipmr_cache_report(skb, vifi, IGMPMSG_WHOLEPKT);
@@ -1254,7 +1254,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
        }
 
        vif->pkt_out++;
-       vif->bytes_out+=skb->len;
+       vif->bytes_out += skb->len;
 
        dst_release(skb->dst);
        skb->dst = &rt->u.dst;
@@ -1352,7 +1352,7 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local
        }
 
        vif_table[vif].pkt_in++;
-       vif_table[vif].bytes_in+=skb->len;
+       vif_table[vif].bytes_in += skb->len;
 
        /*
         *      Forward the frame
@@ -1364,7 +1364,7 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local
                                if (skb2)
                                        ipmr_queue_xmit(skb2, cache, psend);
                        }
-                       psend=ct;
+                       psend = ct;
                }
        }
        if (psend != -1) {
@@ -1428,7 +1428,7 @@ int ip_mr_input(struct sk_buff *skb)
        /*
         *      No usable cache entry
         */
-       if (cache==NULL) {
+       if (cache == NULL) {
                int vif;
 
                if (local) {
@@ -1602,13 +1602,13 @@ ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm)
        if (dev)
                RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex);
 
-       mp_head = (struct rtattr*)skb_put(skb, RTA_LENGTH(0));
+       mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0));
 
        for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
                if (c->mfc_un.res.ttls[ct] < 255) {
                        if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4))
                                goto rtattr_failure;
-                       nhp = (struct rtnexthop*)skb_put(skb, RTA_ALIGN(sizeof(*nhp)));
+                       nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp)));
                        nhp->rtnh_flags = 0;
                        nhp->rtnh_hops = c->mfc_un.res.ttls[ct];
                        nhp->rtnh_ifindex = vif_table[ct].dev->ifindex;
@@ -1634,7 +1634,7 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait)
        read_lock(&mrt_lock);
        cache = ipmr_cache_find(rt->rt_src, rt->rt_dst);
 
-       if (cache==NULL) {
+       if (cache == NULL) {
                struct sk_buff *skb2;
                struct iphdr *iph;
                struct net_device *dev;
index 8d70d29f1ccf8b7664829f3c83a1e5cd4c579062..7ea88b61cb0dd7d854c8e46e029ec3dcb40f057c 100644 (file)
@@ -142,15 +142,15 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
                  ARPT_INV_TGTIP)) {
                dprintf("Source or target IP address mismatch.\n");
 
-               dprintf("SRC: %u.%u.%u.%u. Mask: %u.%u.%u.%u. Target: %u.%u.%u.%u.%s\n",
-                       NIPQUAD(src_ipaddr),
-                       NIPQUAD(arpinfo->smsk.s_addr),
-                       NIPQUAD(arpinfo->src.s_addr),
+               dprintf("SRC: %pI4. Mask: %pI4. Target: %pI4.%s\n",
+                       &src_ipaddr,
+                       &arpinfo->smsk.s_addr,
+                       &arpinfo->src.s_addr,
                        arpinfo->invflags & ARPT_INV_SRCIP ? " (INV)" : "");
-               dprintf("TGT: %u.%u.%u.%u Mask: %u.%u.%u.%u Target: %u.%u.%u.%u.%s\n",
-                       NIPQUAD(tgt_ipaddr),
-                       NIPQUAD(arpinfo->tmsk.s_addr),
-                       NIPQUAD(arpinfo->tgt.s_addr),
+               dprintf("TGT: %pI4 Mask: %pI4 Target: %pI4.%s\n",
+                       &tgt_ipaddr,
+                       &arpinfo->tmsk.s_addr,
+                       &arpinfo->tgt.s_addr,
                        arpinfo->invflags & ARPT_INV_TGTIP ? " (INV)" : "");
                return 0;
        }
index 213fb27debc1e583adb548b4628ad0ac782d3492..ef8b6ca068b280aabe538d58af8da7c580d09b2b 100644 (file)
@@ -94,15 +94,11 @@ ip_packet_match(const struct iphdr *ip,
                     IPT_INV_DSTIP)) {
                dprintf("Source or dest mismatch.\n");
 
-               dprintf("SRC: %u.%u.%u.%u. Mask: %u.%u.%u.%u. Target: %u.%u.%u.%u.%s\n",
-                       NIPQUAD(ip->saddr),
-                       NIPQUAD(ipinfo->smsk.s_addr),
-                       NIPQUAD(ipinfo->src.s_addr),
+               dprintf("SRC: %pI4. Mask: %pI4. Target: %pI4.%s\n",
+                       &ip->saddr, &ipinfo->smsk.s_addr, &ipinfo->src.s_addr,
                        ipinfo->invflags & IPT_INV_SRCIP ? " (INV)" : "");
-               dprintf("DST: %u.%u.%u.%u Mask: %u.%u.%u.%u Target: %u.%u.%u.%u.%s\n",
-                       NIPQUAD(ip->daddr),
-                       NIPQUAD(ipinfo->dmsk.s_addr),
-                       NIPQUAD(ipinfo->dst.s_addr),
+               dprintf("DST: %pI4 Mask: %pI4 Target: %pI4.%s\n",
+                       &ip->daddr, &ipinfo->dmsk.s_addr, &ipinfo->dst.s_addr,
                        ipinfo->invflags & IPT_INV_DSTIP ? " (INV)" : "");
                return false;
        }
index 7ac1677419a9154331dc5d81ba0973bc5383c4e8..2e4f98b85524ab6fa7baf8c945dc2017e90fcfff 100644 (file)
@@ -168,7 +168,7 @@ clusterip_config_init(const struct ipt_clusterip_tgt_info *i, __be32 ip,
                char buffer[16];
 
                /* create proc dir entry */
-               sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(ip));
+               sprintf(buffer, "%pI4", &ip);
                c->pde = proc_create_data(buffer, S_IWUSR|S_IRUSR,
                                          clusterip_procdir,
                                          &clusterip_proc_fops, c);
@@ -373,7 +373,7 @@ static bool clusterip_tg_check(const struct xt_tgchk_param *par)
        config = clusterip_config_find_get(e->ip.dst.s_addr, 1);
        if (!config) {
                if (!(cipinfo->flags & CLUSTERIP_FLAG_NEW)) {
-                       printk(KERN_WARNING "CLUSTERIP: no config found for %u.%u.%u.%u, need 'new'\n", NIPQUAD(e->ip.dst.s_addr));
+                       printk(KERN_WARNING "CLUSTERIP: no config found for %pI4, need 'new'\n", &e->ip.dst.s_addr);
                        return false;
                } else {
                        struct net_device *dev;
@@ -478,9 +478,8 @@ static void arp_print(struct arp_payload *payload)
        }
        hbuffer[--k]='\0';
 
-       printk("src %u.%u.%u.%u@%s, dst %u.%u.%u.%u\n",
-               NIPQUAD(payload->src_ip), hbuffer,
-               NIPQUAD(payload->dst_ip));
+       printk("src %pI4@%s, dst %pI4\n",
+               &payload->src_ip, hbuffer, &payload->dst_ip);
 }
 #endif
 
index fc6ce04a3e35a809049a340edbc3e10470e5f28e..4614a696f1b04dc2f3e1fd925451f660f8458b1e 100644 (file)
@@ -54,8 +54,8 @@ static void dump_packet(const struct nf_loginfo *info,
        /* Important fields:
         * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
        /* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
-       printk("SRC=%u.%u.%u.%u DST=%u.%u.%u.%u ",
-              NIPQUAD(ih->saddr), NIPQUAD(ih->daddr));
+       printk("SRC=%pI4 DST=%pI4 ",
+              &ih->saddr, &ih->daddr);
 
        /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
        printk("LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
@@ -262,8 +262,7 @@ static void dump_packet(const struct nf_loginfo *info,
                        break;
                case ICMP_REDIRECT:
                        /* Max length: 24 "GATEWAY=255.255.255.255 " */
-                       printk("GATEWAY=%u.%u.%u.%u ",
-                              NIPQUAD(ich->un.gateway));
+                       printk("GATEWAY=%pI4 ", &ich->un.gateway);
                        /* Fall through */
                case ICMP_DEST_UNREACH:
                case ICMP_SOURCE_QUENCH:
index 4a7c35275396381f787b3bef34121ee4ec7c24ef..b2141e11575ebb33cb93deec8202525a70348eb5 100644 (file)
@@ -60,9 +60,8 @@ static bool ipv4_invert_tuple(struct nf_conntrack_tuple *tuple,
 static int ipv4_print_tuple(struct seq_file *s,
                            const struct nf_conntrack_tuple *tuple)
 {
-       return seq_printf(s, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ",
-                         NIPQUAD(tuple->src.u3.ip),
-                         NIPQUAD(tuple->dst.u3.ip));
+       return seq_printf(s, "src=%pI4 dst=%pI4 ",
+                         &tuple->src.u3.ip, &tuple->dst.u3.ip);
 }
 
 static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
@@ -198,7 +197,7 @@ static ctl_table ip_ct_sysctl_table[] = {
                .data           = &nf_conntrack_max,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_NF_CONNTRACK_COUNT,
@@ -206,7 +205,7 @@ static ctl_table ip_ct_sysctl_table[] = {
                .data           = &init_net.ct.count,
                .maxlen         = sizeof(int),
                .mode           = 0444,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_NF_CONNTRACK_BUCKETS,
@@ -214,7 +213,7 @@ static ctl_table ip_ct_sysctl_table[] = {
                .data           = &nf_conntrack_htable_size,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0444,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_NF_CONNTRACK_CHECKSUM,
@@ -222,7 +221,7 @@ static ctl_table ip_ct_sysctl_table[] = {
                .data           = &init_net.ct.sysctl_checksum,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_NF_CONNTRACK_LOG_INVALID,
@@ -230,8 +229,8 @@ static ctl_table ip_ct_sysctl_table[] = {
                .data           = &init_net.ct.sysctl_log_invalid,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &log_invalid_proto_min,
                .extra2         = &log_invalid_proto_max,
        },
@@ -284,17 +283,17 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
                        .tuple.dst.u3.ip;
                memset(sin.sin_zero, 0, sizeof(sin.sin_zero));
 
-               pr_debug("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n",
-                        NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
+               pr_debug("SO_ORIGINAL_DST: %pI4 %u\n",
+                        &sin.sin_addr.s_addr, ntohs(sin.sin_port));
                nf_ct_put(ct);
                if (copy_to_user(user, &sin, sizeof(sin)) != 0)
                        return -EFAULT;
                else
                        return 0;
        }
-       pr_debug("SO_ORIGINAL_DST: Can't find %u.%u.%u.%u/%u-%u.%u.%u.%u/%u.\n",
-                NIPQUAD(tuple.src.u3.ip), ntohs(tuple.src.u.tcp.port),
-                NIPQUAD(tuple.dst.u3.ip), ntohs(tuple.dst.u.tcp.port));
+       pr_debug("SO_ORIGINAL_DST: Can't find %pI4/%u-%pI4/%u.\n",
+                &tuple.src.u3.ip, ntohs(tuple.src.u.tcp.port),
+                &tuple.dst.u3.ip, ntohs(tuple.dst.u.tcp.port));
        return -ENOENT;
 }
 
index 4e88792202226368c315c33ddda0eb9c68bbfe77..1fd3ef7718b60cfec90235220f9494c6c3f05757 100644 (file)
@@ -272,7 +272,7 @@ static struct ctl_table icmp_sysctl_table[] = {
                .data           = &nf_ct_icmp_timeout,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name = 0
@@ -285,7 +285,7 @@ static struct ctl_table icmp_compat_sysctl_table[] = {
                .data           = &nf_ct_icmp_timeout,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name = 0
index ee47bf28c82547463629288cc16249bcceb1e20c..7e8e6fc754133526abf86638b176e2c9e4d005e0 100644 (file)
@@ -119,10 +119,9 @@ static int set_sig_addr(struct sk_buff *skb, struct nf_conn *ct,
                                    (ntohl(addr.ip) & 0xff000000) == 0x7f000000)
                                        i = 0;
 
-                               pr_debug("nf_nat_ras: set signal address "
-                                        "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-                                        NIPQUAD(addr.ip), port,
-                                        NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip),
+                               pr_debug("nf_nat_ras: set signal address %pI4:%hu->%pI4:%hu\n",
+                                        &addr.ip, port,
+                                        &ct->tuplehash[!dir].tuple.dst.u3.ip,
                                         info->sig_port[!dir]);
                                return set_h225_addr(skb, data, 0, &taddr[i],
                                                     &ct->tuplehash[!dir].
@@ -131,10 +130,9 @@ static int set_sig_addr(struct sk_buff *skb, struct nf_conn *ct,
                        } else if (addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip &&
                                   port == info->sig_port[dir]) {
                                /* GK->GW */
-                               pr_debug("nf_nat_ras: set signal address "
-                                        "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-                                        NIPQUAD(addr.ip), port,
-                                        NIPQUAD(ct->tuplehash[!dir].tuple.src.u3.ip),
+                               pr_debug("nf_nat_ras: set signal address %pI4:%hu->%pI4:%hu\n",
+                                        &addr.ip, port,
+                                        &ct->tuplehash[!dir].tuple.src.u3.ip,
                                         info->sig_port[!dir]);
                                return set_h225_addr(skb, data, 0, &taddr[i],
                                                     &ct->tuplehash[!dir].
@@ -162,10 +160,9 @@ static int set_ras_addr(struct sk_buff *skb, struct nf_conn *ct,
                if (get_h225_addr(ct, *data, &taddr[i], &addr, &port) &&
                    addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
                    port == ct->tuplehash[dir].tuple.src.u.udp.port) {
-                       pr_debug("nf_nat_ras: set rasAddress "
-                                "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-                                NIPQUAD(addr.ip), ntohs(port),
-                                NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip),
+                       pr_debug("nf_nat_ras: set rasAddress %pI4:%hu->%pI4:%hu\n",
+                                &addr.ip, ntohs(port),
+                                &ct->tuplehash[!dir].tuple.dst.u3.ip,
                                 ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port));
                        return set_h225_addr(skb, data, 0, &taddr[i],
                                             &ct->tuplehash[!dir].tuple.dst.u3,
@@ -257,15 +254,15 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct,
        }
 
        /* Success */
-       pr_debug("nf_nat_h323: expect RTP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-                NIPQUAD(rtp_exp->tuple.src.u3.ip),
+       pr_debug("nf_nat_h323: expect RTP %pI4:%hu->%pI4:%hu\n",
+                &rtp_exp->tuple.src.u3.ip,
                 ntohs(rtp_exp->tuple.src.u.udp.port),
-                NIPQUAD(rtp_exp->tuple.dst.u3.ip),
+                &rtp_exp->tuple.dst.u3.ip,
                 ntohs(rtp_exp->tuple.dst.u.udp.port));
-       pr_debug("nf_nat_h323: expect RTCP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-                NIPQUAD(rtcp_exp->tuple.src.u3.ip),
+       pr_debug("nf_nat_h323: expect RTCP %pI4:%hu->%pI4:%hu\n",
+                &rtcp_exp->tuple.src.u3.ip,
                 ntohs(rtcp_exp->tuple.src.u.udp.port),
-                NIPQUAD(rtcp_exp->tuple.dst.u3.ip),
+                &rtcp_exp->tuple.dst.u3.ip,
                 ntohs(rtcp_exp->tuple.dst.u.udp.port));
 
        return 0;
@@ -307,10 +304,10 @@ static int nat_t120(struct sk_buff *skb, struct nf_conn *ct,
                return -1;
        }
 
-       pr_debug("nf_nat_h323: expect T.120 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-                NIPQUAD(exp->tuple.src.u3.ip),
+       pr_debug("nf_nat_h323: expect T.120 %pI4:%hu->%pI4:%hu\n",
+                &exp->tuple.src.u3.ip,
                 ntohs(exp->tuple.src.u.tcp.port),
-                NIPQUAD(exp->tuple.dst.u3.ip),
+                &exp->tuple.dst.u3.ip,
                 ntohs(exp->tuple.dst.u.tcp.port));
 
        return 0;
@@ -361,10 +358,10 @@ static int nat_h245(struct sk_buff *skb, struct nf_conn *ct,
                return -1;
        }
 
-       pr_debug("nf_nat_q931: expect H.245 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-                NIPQUAD(exp->tuple.src.u3.ip),
+       pr_debug("nf_nat_q931: expect H.245 %pI4:%hu->%pI4:%hu\n",
+                &exp->tuple.src.u3.ip,
                 ntohs(exp->tuple.src.u.tcp.port),
-                NIPQUAD(exp->tuple.dst.u3.ip),
+                &exp->tuple.dst.u3.ip,
                 ntohs(exp->tuple.dst.u.tcp.port));
 
        return 0;
@@ -455,10 +452,10 @@ static int nat_q931(struct sk_buff *skb, struct nf_conn *ct,
        }
 
        /* Success */
-       pr_debug("nf_nat_ras: expect Q.931 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-                NIPQUAD(exp->tuple.src.u3.ip),
+       pr_debug("nf_nat_ras: expect Q.931 %pI4:%hu->%pI4:%hu\n",
+                &exp->tuple.src.u3.ip,
                 ntohs(exp->tuple.src.u.tcp.port),
-                NIPQUAD(exp->tuple.dst.u3.ip),
+                &exp->tuple.dst.u3.ip,
                 ntohs(exp->tuple.dst.u.tcp.port));
 
        return 0;
@@ -524,11 +521,10 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct,
        }
 
        /* Success */
-       pr_debug("nf_nat_q931: expect Call Forwarding "
-                "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
-                NIPQUAD(exp->tuple.src.u3.ip),
+       pr_debug("nf_nat_q931: expect Call Forwarding %pI4:%hu->%pI4:%hu\n",
+                &exp->tuple.src.u3.ip,
                 ntohs(exp->tuple.src.u.tcp.port),
-                NIPQUAD(exp->tuple.dst.u3.ip),
+                &exp->tuple.dst.u3.ip,
                 ntohs(exp->tuple.dst.u.tcp.port));
 
        return 0;
index fe6f9cef6c854d4c13c9a8ecb5951a6f33f68b00..ea83a886b03e6ac3204f410047542a9edea8c4dc 100644 (file)
@@ -55,8 +55,8 @@ static unsigned int help(struct sk_buff *skb,
 
        ip = ntohl(exp->master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip);
        sprintf(buffer, "%u %u", ip, port);
-       pr_debug("nf_nat_irc: inserting '%s' == %u.%u.%u.%u, port %u\n",
-                buffer, NIPQUAD(ip), port);
+       pr_debug("nf_nat_irc: inserting '%s' == %pI4, port %u\n",
+                buffer, &ip, port);
 
        ret = nf_nat_mangle_tcp_packet(skb, exp->master, ctinfo,
                                       matchoff, matchlen, buffer,
index bea54a685109ed3b6fa1fe3f621fb7522ceb2de8..a4f1c3479e23eac1cad79e4eb6f39b8e7df03872 100644 (file)
@@ -98,8 +98,7 @@ static void warn_if_extra_mangle(struct net *net, __be32 dstip, __be32 srcip)
 
        if (rt->rt_src != srcip && !warned) {
                printk("NAT: no longer support implicit source local NAT\n");
-               printk("NAT: packet src %u.%u.%u.%u -> dst %u.%u.%u.%u\n",
-                      NIPQUAD(srcip), NIPQUAD(dstip));
+               printk("NAT: packet src %pI4 -> dst %pI4\n", &srcip, &dstip);
                warned = 1;
        }
        ip_rt_put(rt);
@@ -166,8 +165,7 @@ alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
        struct nf_nat_range range
                = { IP_NAT_RANGE_MAP_IPS, ip, ip, { 0 }, { 0 } };
 
-       pr_debug("Allocating NULL binding for %p (%u.%u.%u.%u)\n",
-                ct, NIPQUAD(ip));
+       pr_debug("Allocating NULL binding for %p (%pI4)\n", ct, &ip);
        return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
 }
 
index 14544320c54577233ead8b41369eedc1c65d7720..07d61a57613c6a0a21685874b497559c2a005619 100644 (file)
@@ -74,8 +74,7 @@ static int map_addr(struct sk_buff *skb,
        if (newaddr == addr->ip && newport == port)
                return 1;
 
-       buflen = sprintf(buffer, "%u.%u.%u.%u:%u",
-                        NIPQUAD(newaddr), ntohs(newport));
+       buflen = sprintf(buffer, "%pI4:%u", &newaddr, ntohs(newport));
 
        return mangle_packet(skb, dptr, datalen, matchoff, matchlen,
                             buffer, buflen);
@@ -152,8 +151,8 @@ static unsigned int ip_nat_sip(struct sk_buff *skb,
                                               &addr) > 0 &&
                    addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
                    addr.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) {
-                       __be32 ip = ct->tuplehash[!dir].tuple.dst.u3.ip;
-                       buflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(ip));
+                       buflen = sprintf(buffer, "%pI4",
+                                       &ct->tuplehash[!dir].tuple.dst.u3.ip);
                        if (!mangle_packet(skb, dptr, datalen, poff, plen,
                                           buffer, buflen))
                                return NF_DROP;
@@ -166,8 +165,8 @@ static unsigned int ip_nat_sip(struct sk_buff *skb,
                                               &addr) > 0 &&
                    addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip &&
                    addr.ip != ct->tuplehash[!dir].tuple.src.u3.ip) {
-                       __be32 ip = ct->tuplehash[!dir].tuple.src.u3.ip;
-                       buflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(ip));
+                       buflen = sprintf(buffer, "%pI4",
+                                       &ct->tuplehash[!dir].tuple.src.u3.ip);
                        if (!mangle_packet(skb, dptr, datalen, poff, plen,
                                           buffer, buflen))
                                return NF_DROP;
@@ -279,8 +278,7 @@ static unsigned int ip_nat_sip_expect(struct sk_buff *skb,
 
        if (exp->tuple.dst.u3.ip != exp->saved_ip ||
            exp->tuple.dst.u.udp.port != exp->saved_proto.udp.port) {
-               buflen = sprintf(buffer, "%u.%u.%u.%u:%u",
-                                NIPQUAD(newip), port);
+               buflen = sprintf(buffer, "%pI4:%u", &newip, port);
                if (!mangle_packet(skb, dptr, datalen, matchoff, matchlen,
                                   buffer, buflen))
                        goto err;
@@ -345,7 +343,7 @@ static unsigned int ip_nat_sdp_addr(struct sk_buff *skb, const char **dptr,
        char buffer[sizeof("nnn.nnn.nnn.nnn")];
        unsigned int buflen;
 
-       buflen = sprintf(buffer, NIPQUAD_FMT, NIPQUAD(addr->ip));
+       buflen = sprintf(buffer, "%pI4", &addr->ip);
        if (mangle_sdp_packet(skb, dptr, dataoff, datalen, type, term,
                              buffer, buflen))
                return 0;
@@ -380,7 +378,7 @@ static unsigned int ip_nat_sdp_session(struct sk_buff *skb, const char **dptr,
        unsigned int buflen;
 
        /* Mangle session description owner and contact addresses */
-       buflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(addr->ip));
+       buflen = sprintf(buffer, "%pI4", &addr->ip);
        if (mangle_sdp_packet(skb, dptr, dataoff, datalen,
                               SDP_HDR_OWNER_IP4, SDP_HDR_MEDIA,
                               buffer, buflen))
index 8303e4b406c05b15245d7f89d8e0c2d16f50b992..182f845de92f762e76a5bb5546aa417cf81330bf 100644 (file)
@@ -930,8 +930,8 @@ static inline void mangle_address(unsigned char *begin,
                }
 
                if (debug)
-                       printk(KERN_DEBUG "bsalg: mapped %u.%u.%u.%u to "
-                              "%u.%u.%u.%u\n", NIPQUAD(old), NIPQUAD(*addr));
+                       printk(KERN_DEBUG "bsalg: mapped %pI4 to %pI4\n",
+                              &old, addr);
        }
 }
 
@@ -1267,9 +1267,8 @@ static int help(struct sk_buff *skb, unsigned int protoff,
         */
        if (ntohs(udph->len) != skb->len - (iph->ihl << 2)) {
                 if (net_ratelimit())
-                        printk(KERN_WARNING "SNMP: dropping malformed packet "
-                               "src=%u.%u.%u.%u dst=%u.%u.%u.%u\n",
-                               NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
+                        printk(KERN_WARNING "SNMP: dropping malformed packet src=%pI4 dst=%pI4\n",
+                               &iph->saddr, &iph->daddr);
                 return NF_DROP;
        }
 
index cd975743bcd2f098ab449589b7145c95b7f3bc86..998fcffc9e15eb7de9ac8c1a516b6035853ce6fb 100644 (file)
@@ -247,7 +247,7 @@ static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info)
        }
 
        if (inet->recverr) {
-               struct iphdr *iph = (struct iphdr*)skb->data;
+               struct iphdr *iph = (struct iphdr *)skb->data;
                u8 *payload = skb->data + (iph->ihl << 2);
 
                if (inet->hdrincl)
@@ -465,7 +465,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
         */
 
        if (msg->msg_namelen) {
-               struct sockaddr_in *usin = (struct sockaddr_in*)msg->msg_name;
+               struct sockaddr_in *usin = (struct sockaddr_in *)msg->msg_name;
                err = -EINVAL;
                if (msg->msg_namelen < sizeof(*usin))
                        goto out;
@@ -851,7 +851,7 @@ struct proto raw_prot = {
 static struct sock *raw_get_first(struct seq_file *seq)
 {
        struct sock *sk;
-       struct raw_iter_statestate = raw_seq_private(seq);
+       struct raw_iter_state *state = raw_seq_private(seq);
 
        for (state->bucket = 0; state->bucket < RAW_HTABLE_SIZE;
                        ++state->bucket) {
@@ -868,7 +868,7 @@ found:
 
 static struct sock *raw_get_next(struct seq_file *seq, struct sock *sk)
 {
-       struct raw_iter_statestate = raw_seq_private(seq);
+       struct raw_iter_state *state = raw_seq_private(seq);
 
        do {
                sk = sk_next(sk);
index 2ea6dcc3e2ccd62b6faedb97b31e2206f121764a..4e6959c298194b84e598a3bd6263ba85f32c883e 100644 (file)
@@ -129,6 +129,7 @@ static int ip_rt_mtu_expires __read_mostly  = 10 * 60 * HZ;
 static int ip_rt_min_pmtu __read_mostly                = 512 + 20 + 20;
 static int ip_rt_min_advmss __read_mostly      = 256;
 static int ip_rt_secret_interval __read_mostly = 10 * 60 * HZ;
+static int rt_chain_length_max __read_mostly   = 20;
 
 static void rt_worker_func(struct work_struct *work);
 static DECLARE_DELAYED_WORK(expires_work, rt_worker_func);
@@ -145,6 +146,7 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
 static void             ipv4_link_failure(struct sk_buff *skb);
 static void             ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
 static int rt_garbage_collect(struct dst_ops *ops);
+static void rt_emergency_hash_rebuild(struct net *net);
 
 
 static struct dst_ops ipv4_dst_ops = {
@@ -158,7 +160,6 @@ static struct dst_ops ipv4_dst_ops = {
        .link_failure =         ipv4_link_failure,
        .update_pmtu =          ip_rt_update_pmtu,
        .local_out =            __ip_local_out,
-       .entry_size =           sizeof(struct rtable),
        .entries =              ATOMIC_INIT(0),
 };
 
@@ -201,6 +202,7 @@ const __u8 ip_tos2prio[16] = {
 struct rt_hash_bucket {
        struct rtable   *chain;
 };
+
 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) || \
        defined(CONFIG_PROVE_LOCKING)
 /*
@@ -674,6 +676,20 @@ static inline u32 rt_score(struct rtable *rt)
        return score;
 }
 
+static inline bool rt_caching(const struct net *net)
+{
+       return net->ipv4.current_rt_cache_rebuild_count <=
+               net->ipv4.sysctl_rt_cache_rebuild_count;
+}
+
+static inline bool compare_hash_inputs(const struct flowi *fl1,
+                                       const struct flowi *fl2)
+{
+       return (__force u32)(((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) |
+               (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr) |
+               (fl1->iif ^ fl2->iif)) == 0);
+}
+
 static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
 {
        return ((__force u32)((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) |
@@ -753,11 +769,24 @@ static void rt_do_flush(int process_context)
        }
 }
 
+/*
+ * While freeing expired entries, we compute average chain length
+ * and standard deviation, using fixed-point arithmetic.
+ * This to have an estimation of rt_chain_length_max
+ *  rt_chain_length_max = max(elasticity, AVG + 4*SD)
+ * We use 3 bits for frational part, and 29 (or 61) for magnitude.
+ */
+
+#define FRACT_BITS 3
+#define ONE (1UL << FRACT_BITS)
+
 static void rt_check_expire(void)
 {
        static unsigned int rover;
        unsigned int i = rover, goal;
        struct rtable *rth, **rthp;
+       unsigned long length = 0, samples = 0;
+       unsigned long sum = 0, sum2 = 0;
        u64 mult;
 
        mult = ((u64)ip_rt_gc_interval) << rt_hash_log;
@@ -766,6 +795,7 @@ static void rt_check_expire(void)
        goal = (unsigned int)mult;
        if (goal > rt_hash_mask)
                goal = rt_hash_mask + 1;
+       length = 0;
        for (; goal > 0; goal--) {
                unsigned long tmo = ip_rt_gc_timeout;
 
@@ -775,6 +805,8 @@ static void rt_check_expire(void)
                if (need_resched())
                        cond_resched();
 
+               samples++;
+
                if (*rthp == NULL)
                        continue;
                spin_lock_bh(rt_hash_lock_addr(i));
@@ -789,11 +821,29 @@ static void rt_check_expire(void)
                                if (time_before_eq(jiffies, rth->u.dst.expires)) {
                                        tmo >>= 1;
                                        rthp = &rth->u.dst.rt_next;
+                                       /*
+                                        * Only bump our length if the hash
+                                        * inputs on entries n and n+1 are not
+                                        * the same, we only count entries on
+                                        * a chain with equal hash inputs once
+                                        * so that entries for different QOS
+                                        * levels, and other non-hash input
+                                        * attributes don't unfairly skew
+                                        * the length computation
+                                        */
+                                       if ((*rthp == NULL) ||
+                                           !compare_hash_inputs(&(*rthp)->fl,
+                                                                &rth->fl))
+                                               length += ONE;
                                        continue;
                                }
                        } else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout)) {
                                tmo >>= 1;
                                rthp = &rth->u.dst.rt_next;
+                               if ((*rthp == NULL) ||
+                                   !compare_hash_inputs(&(*rthp)->fl,
+                                                        &rth->fl))
+                                       length += ONE;
                                continue;
                        }
 
@@ -802,6 +852,15 @@ static void rt_check_expire(void)
                        rt_free(rth);
                }
                spin_unlock_bh(rt_hash_lock_addr(i));
+               sum += length;
+               sum2 += length*length;
+       }
+       if (samples) {
+               unsigned long avg = sum / samples;
+               unsigned long sd = int_sqrt(sum2 / samples - avg*avg);
+               rt_chain_length_max = max_t(unsigned long,
+                                       ip_rt_gc_elasticity,
+                                       (avg + 4*sd) >> FRACT_BITS);
        }
        rover = i;
 }
@@ -851,6 +910,26 @@ static void rt_secret_rebuild(unsigned long __net)
        mod_timer(&net->ipv4.rt_secret_timer, jiffies + ip_rt_secret_interval);
 }
 
+static void rt_secret_rebuild_oneshot(struct net *net)
+{
+       del_timer_sync(&net->ipv4.rt_secret_timer);
+       rt_cache_invalidate(net);
+       if (ip_rt_secret_interval) {
+               net->ipv4.rt_secret_timer.expires += ip_rt_secret_interval;
+               add_timer(&net->ipv4.rt_secret_timer);
+       }
+}
+
+static void rt_emergency_hash_rebuild(struct net *net)
+{
+       if (net_ratelimit()) {
+               printk(KERN_WARNING "Route hash chain too long!\n");
+               printk(KERN_WARNING "Adjust your secret_interval!\n");
+       }
+
+       rt_secret_rebuild_oneshot(net);
+}
+
 /*
    Short description of GC goals.
 
@@ -989,6 +1068,7 @@ out:       return 0;
 static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp)
 {
        struct rtable   *rth, **rthp;
+       struct rtable   *rthi;
        unsigned long   now;
        struct rtable *cand, **candp;
        u32             min_score;
@@ -1002,7 +1082,13 @@ restart:
        candp = NULL;
        now = jiffies;
 
+       if (!rt_caching(dev_net(rt->u.dst.dev))) {
+               rt_drop(rt);
+               return 0;
+       }
+
        rthp = &rt_hash_table[hash].chain;
+       rthi = NULL;
 
        spin_lock_bh(rt_hash_lock_addr(hash));
        while ((rth = *rthp) != NULL) {
@@ -1048,6 +1134,17 @@ restart:
                chain_length++;
 
                rthp = &rth->u.dst.rt_next;
+
+               /*
+                * check to see if the next entry in the chain
+                * contains the same hash input values as rt.  If it does
+                * This is where we will insert into the list, instead of
+                * at the head.  This groups entries that differ by aspects not
+                * relvant to the hash function together, which we use to adjust
+                * our chain length
+                */
+               if (*rthp && compare_hash_inputs(&(*rthp)->fl, &rt->fl))
+                       rthi = rth;
        }
 
        if (cand) {
@@ -1061,6 +1158,16 @@ restart:
                        *candp = cand->u.dst.rt_next;
                        rt_free(cand);
                }
+       } else {
+               if (chain_length > rt_chain_length_max) {
+                       struct net *net = dev_net(rt->u.dst.dev);
+                       int num = ++net->ipv4.current_rt_cache_rebuild_count;
+                       if (!rt_caching(dev_net(rt->u.dst.dev))) {
+                               printk(KERN_WARNING "%s: %d rebuilds is over limit, route caching disabled\n",
+                                       rt->u.dst.dev->name, num);
+                       }
+                       rt_emergency_hash_rebuild(dev_net(rt->u.dst.dev));
+               }
        }
 
        /* Try to bind route to arp only if it is output
@@ -1098,14 +1205,17 @@ restart:
                }
        }
 
-       rt->u.dst.rt_next = rt_hash_table[hash].chain;
+       if (rthi)
+               rt->u.dst.rt_next = rthi->u.dst.rt_next;
+       else
+               rt->u.dst.rt_next = rt_hash_table[hash].chain;
+
 #if RT_CACHE_DEBUG >= 2
        if (rt->u.dst.rt_next) {
                struct rtable *trt;
-               printk(KERN_DEBUG "rt_cache @%02x: " NIPQUAD_FMT, hash,
-                      NIPQUAD(rt->rt_dst));
+               printk(KERN_DEBUG "rt_cache @%02x: %pI4", hash, &rt->rt_dst);
                for (trt = rt->u.dst.rt_next; trt; trt = trt->u.dst.rt_next)
-                       printk(" . " NIPQUAD_FMT, NIPQUAD(trt->rt_dst));
+                       printk(" . %pI4", &trt->rt_dst);
                printk("\n");
        }
 #endif
@@ -1114,7 +1224,11 @@ restart:
         * previous writes to rt are comitted to memory
         * before making rt visible to other CPUS.
         */
-       rcu_assign_pointer(rt_hash_table[hash].chain, rt);
+       if (rthi)
+               rcu_assign_pointer(rthi->u.dst.rt_next, rt);
+       else
+               rcu_assign_pointer(rt_hash_table[hash].chain, rt);
+
        spin_unlock_bh(rt_hash_lock_addr(hash));
        *rp = rt;
        return 0;
@@ -1217,6 +1331,9 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
            || ipv4_is_zeronet(new_gw))
                goto reject_redirect;
 
+       if (!rt_caching(net))
+               goto reject_redirect;
+
        if (!IN_DEV_SHARED_MEDIA(in_dev)) {
                if (!inet_addr_onlink(in_dev, new_gw, old_gw))
                        goto reject_redirect;
@@ -1267,7 +1384,6 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
 
                                /* Copy all the information. */
                                *rt = *rth;
-                               INIT_RCU_HEAD(&rt->u.dst.rcu_head);
                                rt->u.dst.__use         = 1;
                                atomic_set(&rt->u.dst.__refcnt, 1);
                                rt->u.dst.child         = NULL;
@@ -1280,7 +1396,9 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
                                rt->u.dst.path          = &rt->u.dst;
                                rt->u.dst.neighbour     = NULL;
                                rt->u.dst.hh            = NULL;
+#ifdef CONFIG_XFRM
                                rt->u.dst.xfrm          = NULL;
+#endif
                                rt->rt_genid            = rt_genid(net);
                                rt->rt_flags            |= RTCF_REDIRECTED;
 
@@ -1324,11 +1442,10 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
 reject_redirect:
 #ifdef CONFIG_IP_ROUTE_VERBOSE
        if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit())
-               printk(KERN_INFO "Redirect from " NIPQUAD_FMT " on %s about "
-                       NIPQUAD_FMT " ignored.\n"
-                       "  Advised path = " NIPQUAD_FMT " -> " NIPQUAD_FMT "\n",
-                      NIPQUAD(old_gw), dev->name, NIPQUAD(new_gw),
-                      NIPQUAD(saddr), NIPQUAD(daddr));
+               printk(KERN_INFO "Redirect from %pI4 on %s about %pI4 ignored.\n"
+                       "  Advised path = %pI4 -> %pI4\n",
+                      &old_gw, dev->name, &new_gw,
+                      &saddr, &daddr);
 #endif
        in_dev_put(in_dev);
 }
@@ -1348,9 +1465,8 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
                                                rt->fl.oif,
                                                rt_genid(dev_net(dst->dev)));
 #if RT_CACHE_DEBUG >= 1
-                       printk(KERN_DEBUG "ipv4_negative_advice: redirect to "
-                                         NIPQUAD_FMT "/%02x dropped\n",
-                               NIPQUAD(rt->rt_dst), rt->fl.fl4_tos);
+                       printk(KERN_DEBUG "ipv4_negative_advice: redirect to %pI4/%02x dropped\n",
+                               &rt->rt_dst, rt->fl.fl4_tos);
 #endif
                        rt_del(hash, rt);
                        ret = NULL;
@@ -1414,10 +1530,9 @@ void ip_rt_send_redirect(struct sk_buff *skb)
                if (IN_DEV_LOG_MARTIANS(in_dev) &&
                    rt->u.dst.rate_tokens == ip_rt_redirect_number &&
                    net_ratelimit())
-                       printk(KERN_WARNING "host " NIPQUAD_FMT "/if%d ignores "
-                               "redirects for " NIPQUAD_FMT " to " NIPQUAD_FMT ".\n",
-                               NIPQUAD(rt->rt_src), rt->rt_iif,
-                               NIPQUAD(rt->rt_dst), NIPQUAD(rt->rt_gateway));
+                       printk(KERN_WARNING "host %pI4/if%d ignores redirects for %pI4 to %pI4.\n",
+                               &rt->rt_src, rt->rt_iif,
+                               &rt->rt_dst, &rt->rt_gateway);
 #endif
        }
 out:
@@ -1610,8 +1725,8 @@ static void ipv4_link_failure(struct sk_buff *skb)
 
 static int ip_rt_bug(struct sk_buff *skb)
 {
-       printk(KERN_DEBUG "ip_rt_bug: " NIPQUAD_FMT " -> " NIPQUAD_FMT ", %s\n",
-               NIPQUAD(ip_hdr(skb)->saddr), NIPQUAD(ip_hdr(skb)->daddr),
+       printk(KERN_DEBUG "ip_rt_bug: %pI4 -> %pI4, %s\n",
+               &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr,
                skb->dev ? skb->dev->name : "?");
        kfree_skb(skb);
        return 0;
@@ -1788,9 +1903,8 @@ static void ip_handle_martian_source(struct net_device *dev,
                 *      RFC1812 recommendation, if source is martian,
                 *      the only hint is MAC header.
                 */
-               printk(KERN_WARNING "martian source " NIPQUAD_FMT " from "
-                       NIPQUAD_FMT", on dev %s\n",
-                       NIPQUAD(daddr), NIPQUAD(saddr), dev->name);
+               printk(KERN_WARNING "martian source %pI4 from %pI4, on dev %s\n",
+                       &daddr, &saddr, dev->name);
                if (dev->hard_header_len && skb_mac_header_was_set(skb)) {
                        int i;
                        const unsigned char *p = skb_mac_header(skb);
@@ -2099,9 +2213,8 @@ martian_destination:
        RT_CACHE_STAT_INC(in_martian_dst);
 #ifdef CONFIG_IP_ROUTE_VERBOSE
        if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit())
-               printk(KERN_WARNING "martian destination " NIPQUAD_FMT " from "
-                       NIPQUAD_FMT ", dev %s\n",
-                       NIPQUAD(daddr), NIPQUAD(saddr), dev->name);
+               printk(KERN_WARNING "martian destination %pI4 from %pI4, dev %s\n",
+                       &daddr, &saddr, dev->name);
 #endif
 
 e_hostunreach:
@@ -2130,6 +2243,10 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        struct net *net;
 
        net = dev_net(dev);
+
+       if (!rt_caching(net))
+               goto skip_cache;
+
        tos &= IPTOS_RT_MASK;
        hash = rt_hash(daddr, saddr, iif, rt_genid(net));
 
@@ -2154,6 +2271,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        }
        rcu_read_unlock();
 
+skip_cache:
        /* Multicast recognition logic is moved from route cache to here.
           The problem was that too many Ethernet cards have broken/missing
           hardware multicast filters :-( As result the host on multicasting
@@ -2539,6 +2657,9 @@ int __ip_route_output_key(struct net *net, struct rtable **rp,
        unsigned hash;
        struct rtable *rth;
 
+       if (!rt_caching(net))
+               goto slow_output;
+
        hash = rt_hash(flp->fl4_dst, flp->fl4_src, flp->oif, rt_genid(net));
 
        rcu_read_lock_bh();
@@ -2563,6 +2684,7 @@ int __ip_route_output_key(struct net *net, struct rtable **rp,
        }
        rcu_read_unlock_bh();
 
+slow_output:
        return ip_route_output_slow(net, rp, flp);
 }
 
@@ -2578,7 +2700,6 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
        .destroy                =       ipv4_dst_destroy,
        .check                  =       ipv4_dst_check,
        .update_pmtu            =       ipv4_rt_blackhole_update_pmtu,
-       .entry_size             =       sizeof(struct rtable),
        .entries                =       ATOMIC_INIT(0),
 };
 
@@ -2995,7 +3116,7 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ipv4_dst_ops.gc_thresh,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_ROUTE_MAX_SIZE,
@@ -3003,7 +3124,7 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_max_size,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                /*  Deprecated. Use gc_min_interval_ms */
@@ -3013,8 +3134,8 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_gc_min_interval,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies,
        },
        {
                .ctl_name       = NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS,
@@ -3022,8 +3143,8 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_gc_min_interval,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_ms_jiffies,
-               .strategy       = &sysctl_ms_jiffies,
+               .proc_handler   = proc_dointvec_ms_jiffies,
+               .strategy       = sysctl_ms_jiffies,
        },
        {
                .ctl_name       = NET_IPV4_ROUTE_GC_TIMEOUT,
@@ -3031,8 +3152,8 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_gc_timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies,
        },
        {
                .ctl_name       = NET_IPV4_ROUTE_GC_INTERVAL,
@@ -3040,8 +3161,8 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_gc_interval,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies,
        },
        {
                .ctl_name       = NET_IPV4_ROUTE_REDIRECT_LOAD,
@@ -3049,7 +3170,7 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_redirect_load,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_ROUTE_REDIRECT_NUMBER,
@@ -3057,7 +3178,7 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_redirect_number,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_ROUTE_REDIRECT_SILENCE,
@@ -3065,7 +3186,7 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_redirect_silence,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_ROUTE_ERROR_COST,
@@ -3073,7 +3194,7 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_error_cost,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_ROUTE_ERROR_BURST,
@@ -3081,7 +3202,7 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_error_burst,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_ROUTE_GC_ELASTICITY,
@@ -3089,7 +3210,7 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_gc_elasticity,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_ROUTE_MTU_EXPIRES,
@@ -3097,8 +3218,8 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_mtu_expires,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies,
        },
        {
                .ctl_name       = NET_IPV4_ROUTE_MIN_PMTU,
@@ -3106,7 +3227,7 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_min_pmtu,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_ROUTE_MIN_ADVMSS,
@@ -3114,7 +3235,7 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_min_advmss,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_ROUTE_SECRET_INTERVAL,
@@ -3122,8 +3243,8 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_secret_interval,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &ipv4_sysctl_rt_secret_interval,
-               .strategy       = &ipv4_sysctl_rt_secret_interval_strategy,
+               .proc_handler   = ipv4_sysctl_rt_secret_interval,
+               .strategy       = ipv4_sysctl_rt_secret_interval_strategy,
        },
        { .ctl_name = 0 }
 };
@@ -3151,8 +3272,8 @@ static struct ctl_table ipv4_route_flush_table[] = {
                .procname       = "flush",
                .maxlen         = sizeof(int),
                .mode           = 0200,
-               .proc_handler   = &ipv4_sysctl_rtcache_flush,
-               .strategy       = &ipv4_sysctl_rtcache_flush_strategy,
+               .proc_handler   = ipv4_sysctl_rtcache_flush,
+               .strategy       = ipv4_sysctl_rtcache_flush_strategy,
        },
        { .ctl_name = 0 },
 };
index 1bb10df8ce7dd94b89a0b43b170307557cf521f0..4710d219f06ae9df6c2754906ca09663ed4da738 100644 (file)
@@ -195,7 +195,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_timestamps,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_TCP_WINDOW_SCALING,
@@ -203,7 +203,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_window_scaling,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_TCP_SACK,
@@ -211,7 +211,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_sack,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_TCP_RETRANS_COLLAPSE,
@@ -219,7 +219,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_retrans_collapse,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_DEFAULT_TTL,
@@ -227,8 +227,8 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_ip_default_ttl,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &ipv4_doint_and_flush,
-               .strategy       = &ipv4_doint_and_flush_strategy,
+               .proc_handler   = ipv4_doint_and_flush,
+               .strategy       = ipv4_doint_and_flush_strategy,
                .extra2         = &init_net,
        },
        {
@@ -237,7 +237,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &ipv4_config.no_pmtu_disc,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_NONLOCAL_BIND,
@@ -245,7 +245,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_ip_nonlocal_bind,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_TCP_SYN_RETRIES,
@@ -253,7 +253,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_syn_retries,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_SYNACK_RETRIES,
@@ -261,7 +261,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_synack_retries,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_MAX_ORPHANS,
@@ -269,7 +269,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_max_orphans,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_MAX_TW_BUCKETS,
@@ -277,7 +277,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &tcp_death_row.sysctl_max_tw_buckets,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_DYNADDR,
@@ -285,7 +285,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_ip_dynaddr,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_TCP_KEEPALIVE_TIME,
@@ -293,8 +293,8 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_keepalive_time,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies
        },
        {
                .ctl_name       = NET_IPV4_TCP_KEEPALIVE_PROBES,
@@ -302,7 +302,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_keepalive_probes,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_TCP_KEEPALIVE_INTVL,
@@ -310,8 +310,8 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_keepalive_intvl,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies
        },
        {
                .ctl_name       = NET_IPV4_TCP_RETRIES1,
@@ -319,8 +319,8 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_retries1,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra2         = &tcp_retr1_max
        },
        {
@@ -329,7 +329,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_retries2,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_TCP_FIN_TIMEOUT,
@@ -337,8 +337,8 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_fin_timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies
        },
 #ifdef CONFIG_SYN_COOKIES
        {
@@ -347,7 +347,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_syncookies,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
 #endif
        {
@@ -356,7 +356,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &tcp_death_row.sysctl_tw_recycle,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_ABORT_ON_OVERFLOW,
@@ -364,7 +364,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_abort_on_overflow,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_STDURG,
@@ -372,7 +372,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_stdurg,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_RFC1337,
@@ -380,7 +380,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_rfc1337,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_MAX_SYN_BACKLOG,
@@ -388,7 +388,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_max_syn_backlog,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_LOCAL_PORT_RANGE,
@@ -396,8 +396,8 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_local_ports.range,
                .maxlen         = sizeof(sysctl_local_ports.range),
                .mode           = 0644,
-               .proc_handler   = &ipv4_local_port_range,
-               .strategy       = &ipv4_sysctl_local_port_range,
+               .proc_handler   = ipv4_local_port_range,
+               .strategy       = ipv4_sysctl_local_port_range,
        },
 #ifdef CONFIG_IP_MULTICAST
        {
@@ -406,7 +406,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_igmp_max_memberships,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
 
 #endif
@@ -416,7 +416,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_igmp_max_msf,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_INET_PEER_THRESHOLD,
@@ -424,7 +424,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &inet_peer_threshold,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_INET_PEER_MINTTL,
@@ -432,8 +432,8 @@ static struct ctl_table ipv4_table[] = {
                .data           = &inet_peer_minttl,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies
        },
        {
                .ctl_name       = NET_IPV4_INET_PEER_MAXTTL,
@@ -441,8 +441,8 @@ static struct ctl_table ipv4_table[] = {
                .data           = &inet_peer_maxttl,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies
        },
        {
                .ctl_name       = NET_IPV4_INET_PEER_GC_MINTIME,
@@ -450,8 +450,8 @@ static struct ctl_table ipv4_table[] = {
                .data           = &inet_peer_gc_mintime,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies
        },
        {
                .ctl_name       = NET_IPV4_INET_PEER_GC_MAXTIME,
@@ -459,8 +459,8 @@ static struct ctl_table ipv4_table[] = {
                .data           = &inet_peer_gc_maxtime,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies
        },
        {
                .ctl_name       = NET_TCP_ORPHAN_RETRIES,
@@ -468,7 +468,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_orphan_retries,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_FACK,
@@ -476,7 +476,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_fack,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_REORDERING,
@@ -484,7 +484,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_reordering,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_ECN,
@@ -492,7 +492,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_ecn,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_DSACK,
@@ -500,7 +500,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_dsack,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_MEM,
@@ -508,7 +508,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_mem,
                .maxlen         = sizeof(sysctl_tcp_mem),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_WMEM,
@@ -516,7 +516,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_wmem,
                .maxlen         = sizeof(sysctl_tcp_wmem),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_RMEM,
@@ -524,7 +524,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_rmem,
                .maxlen         = sizeof(sysctl_tcp_rmem),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_APP_WIN,
@@ -532,7 +532,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_app_win,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_ADV_WIN_SCALE,
@@ -540,7 +540,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_adv_win_scale,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_TW_REUSE,
@@ -548,7 +548,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_tw_reuse,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_FRTO,
@@ -556,7 +556,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_frto,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_FRTO_RESPONSE,
@@ -564,7 +564,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_frto_response,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_LOW_LATENCY,
@@ -572,7 +572,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_low_latency,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_TCP_NO_METRICS_SAVE,
@@ -580,7 +580,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_nometrics_save,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_TCP_MODERATE_RCVBUF,
@@ -588,7 +588,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_moderate_rcvbuf,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_TCP_TSO_WIN_DIVISOR,
@@ -596,15 +596,15 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_tso_win_divisor,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_TCP_CONG_CONTROL,
                .procname       = "tcp_congestion_control",
                .mode           = 0644,
                .maxlen         = TCP_CA_NAME_MAX,
-               .proc_handler   = &proc_tcp_congestion_control,
-               .strategy       = &sysctl_tcp_congestion_control,
+               .proc_handler   = proc_tcp_congestion_control,
+               .strategy       = sysctl_tcp_congestion_control,
        },
        {
                .ctl_name       = NET_TCP_ABC,
@@ -612,7 +612,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_abc,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_TCP_MTU_PROBING,
@@ -620,7 +620,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_mtu_probing,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_TCP_BASE_MSS,
@@ -628,7 +628,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_base_mss,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS,
@@ -636,7 +636,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_workaround_signed_windows,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
 #ifdef CONFIG_NET_DMA
        {
@@ -645,7 +645,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_dma_copybreak,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
 #endif
        {
@@ -654,7 +654,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_slow_start_after_idle,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
 #ifdef CONFIG_NETLABEL
        {
@@ -663,7 +663,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &cipso_v4_cache_enabled,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_CIPSOV4_CACHE_BUCKET_SIZE,
@@ -671,7 +671,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &cipso_v4_cache_bucketsize,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_CIPSOV4_RBM_OPTFMT,
@@ -679,7 +679,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &cipso_v4_rbm_optfmt,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_CIPSOV4_RBM_STRICTVALID,
@@ -687,22 +687,22 @@ static struct ctl_table ipv4_table[] = {
                .data           = &cipso_v4_rbm_strictvalid,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
 #endif /* CONFIG_NETLABEL */
        {
                .procname       = "tcp_available_congestion_control",
                .maxlen         = TCP_CA_BUF_MAX,
                .mode           = 0444,
-               .proc_handler   = &proc_tcp_available_congestion_control,
+               .proc_handler   = proc_tcp_available_congestion_control,
        },
        {
                .ctl_name       = NET_TCP_ALLOWED_CONG_CONTROL,
                .procname       = "tcp_allowed_congestion_control",
                .maxlen         = TCP_CA_BUF_MAX,
                .mode           = 0644,
-               .proc_handler   = &proc_allowed_congestion_control,
-               .strategy       = &strategy_allowed_congestion_control,
+               .proc_handler   = proc_allowed_congestion_control,
+               .strategy       = strategy_allowed_congestion_control,
        },
        {
                .ctl_name       = NET_TCP_MAX_SSTHRESH,
@@ -710,7 +710,7 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_tcp_max_ssthresh,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = CTL_UNNUMBERED,
@@ -718,8 +718,8 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_udp_mem,
                .maxlen         = sizeof(sysctl_udp_mem),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &zero
        },
        {
@@ -728,8 +728,8 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_udp_rmem_min,
                .maxlen         = sizeof(sysctl_udp_rmem_min),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &zero
        },
        {
@@ -738,8 +738,8 @@ static struct ctl_table ipv4_table[] = {
                .data           = &sysctl_udp_wmem_min,
                .maxlen         = sizeof(sysctl_udp_wmem_min),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &zero
        },
        { .ctl_name = 0 }
@@ -752,7 +752,7 @@ static struct ctl_table ipv4_net_table[] = {
                .data           = &init_net.ipv4.sysctl_icmp_echo_ignore_all,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS,
@@ -760,7 +760,7 @@ static struct ctl_table ipv4_net_table[] = {
                .data           = &init_net.ipv4.sysctl_icmp_echo_ignore_broadcasts,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES,
@@ -768,7 +768,7 @@ static struct ctl_table ipv4_net_table[] = {
                .data           = &init_net.ipv4.sysctl_icmp_ignore_bogus_error_responses,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR,
@@ -776,7 +776,7 @@ static struct ctl_table ipv4_net_table[] = {
                .data           = &init_net.ipv4.sysctl_icmp_errors_use_inbound_ifaddr,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV4_ICMP_RATELIMIT,
@@ -784,8 +784,8 @@ static struct ctl_table ipv4_net_table[] = {
                .data           = &init_net.ipv4.sysctl_icmp_ratelimit,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_ms_jiffies,
-               .strategy       = &sysctl_ms_jiffies
+               .proc_handler   = proc_dointvec_ms_jiffies,
+               .strategy       = sysctl_ms_jiffies
        },
        {
                .ctl_name       = NET_IPV4_ICMP_RATEMASK,
@@ -793,7 +793,15 @@ static struct ctl_table ipv4_net_table[] = {
                .data           = &init_net.ipv4.sysctl_icmp_ratemask,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
+       },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "rt_cache_rebuild_count",
+               .data           = &init_net.ipv4.sysctl_rt_cache_rebuild_count,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec
        },
        { }
 };
@@ -827,8 +835,12 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
                        &net->ipv4.sysctl_icmp_ratelimit;
                table[5].data =
                        &net->ipv4.sysctl_icmp_ratemask;
+               table[6].data =
+                       &net->ipv4.sysctl_rt_cache_rebuild_count;
        }
 
+       net->ipv4.sysctl_rt_cache_rebuild_count = 4;
+
        net->ipv4.ipv4_hdr = register_net_sysctl_table(net,
                        net_ipv4_ctl_path, table);
        if (net->ipv4.ipv4_hdr == NULL)
index c5aca0bb116ae36ead0a824236ab4a5df9162d74..044224a341eb10b6cb476c2b0b43d130a4af5916 100644 (file)
@@ -1680,7 +1680,7 @@ void tcp_set_state(struct sock *sk, int state)
                        inet_put_port(sk);
                /* fall through */
        default:
-               if (oldstate==TCP_ESTABLISHED)
+               if (oldstate == TCP_ESTABLISHED)
                        TCP_DEC_STATS(sock_net(sk), TCP_MIB_CURRESTAB);
        }
 
@@ -1690,7 +1690,7 @@ void tcp_set_state(struct sock *sk, int state)
        sk->sk_state = state;
 
 #ifdef STATE_TRACE
-       SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);
+       SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n", sk, statename[oldstate], statename[state]);
 #endif
 }
 EXPORT_SYMBOL_GPL(tcp_set_state);
@@ -2650,7 +2650,7 @@ EXPORT_SYMBOL(tcp_md5_hash_key);
 
 void tcp_done(struct sock *sk)
 {
-       if(sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV)
+       if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV)
                TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_ATTEMPTFAILS);
 
        tcp_set_state(sk, TCP_CLOSE);
@@ -2707,8 +2707,8 @@ void __init tcp_init(void)
                                        thash_entries ? 0 : 512 * 1024);
        tcp_hashinfo.ehash_size = 1 << tcp_hashinfo.ehash_size;
        for (i = 0; i < tcp_hashinfo.ehash_size; i++) {
-               INIT_HLIST_HEAD(&tcp_hashinfo.ehash[i].chain);
-               INIT_HLIST_HEAD(&tcp_hashinfo.ehash[i].twchain);
+               INIT_HLIST_NULLS_HEAD(&tcp_hashinfo.ehash[i].chain, i);
+               INIT_HLIST_NULLS_HEAD(&tcp_hashinfo.ehash[i].twchain, i);
        }
        if (inet_ehash_locks_alloc(&tcp_hashinfo))
                panic("TCP: failed to alloc ehash_locks");
index 4a1221e5e8ee2ec8b7d1a5157aa063f6a3f8011e..ee467ec40c4f3c0b08123d042921c2f87481632f 100644 (file)
@@ -1,13 +1,23 @@
 /*
- * TCP CUBIC: Binary Increase Congestion control for TCP v2.2
+ * TCP CUBIC: Binary Increase Congestion control for TCP v2.3
  * Home page:
  *      http://netsrv.csc.ncsu.edu/twiki/bin/view/Main/BIC
  * This is from the implementation of CUBIC TCP in
- * Injong Rhee, Lisong Xu.
- *  "CUBIC: A New TCP-Friendly High-Speed TCP Variant
- *  in PFLDnet 2005
+ * Sangtae Ha, Injong Rhee and Lisong Xu,
+ *  "CUBIC: A New TCP-Friendly High-Speed TCP Variant"
+ *  in ACM SIGOPS Operating System Review, July 2008.
  * Available from:
- *  http://netsrv.csc.ncsu.edu/export/cubic-paper.pdf
+ *  http://netsrv.csc.ncsu.edu/export/cubic_a_new_tcp_2008.pdf
+ *
+ * CUBIC integrates a new slow start algorithm, called HyStart.
+ * The details of HyStart are presented in
+ *  Sangtae Ha and Injong Rhee,
+ *  "Taming the Elephants: New TCP Slow Start", NCSU TechReport 2008.
+ * Available from:
+ *  http://netsrv.csc.ncsu.edu/export/hystart_techreport_2008.pdf
+ *
+ * All testing results are available from:
+ * http://netsrv.csc.ncsu.edu/wiki/index.php/TCP_Testing
  *
  * Unless CUBIC is enabled and congestion window is large
  * this behaves the same as the original Reno.
                                         */
 #define        BICTCP_HZ               10      /* BIC HZ 2^10 = 1024 */
 
+/* Two methods of hybrid slow start */
+#define HYSTART_ACK_TRAIN      0x1
+#define HYSTART_DELAY          0x2
+
+/* Number of delay samples for detecting the increase of delay */
+#define HYSTART_MIN_SAMPLES    8
+#define HYSTART_DELAY_MIN      (2U<<3)
+#define HYSTART_DELAY_MAX      (16U<<3)
+#define HYSTART_DELAY_THRESH(x)        clamp(x, HYSTART_DELAY_MIN, HYSTART_DELAY_MAX)
+
 static int fast_convergence __read_mostly = 1;
 static int beta __read_mostly = 717;   /* = 717/1024 (BICTCP_BETA_SCALE) */
 static int initial_ssthresh __read_mostly;
 static int bic_scale __read_mostly = 41;
 static int tcp_friendliness __read_mostly = 1;
 
+static int hystart __read_mostly = 1;
+static int hystart_detect __read_mostly = HYSTART_ACK_TRAIN | HYSTART_DELAY;
+static int hystart_low_window __read_mostly = 16;
+
 static u32 cube_rtt_scale __read_mostly;
 static u32 beta_scale __read_mostly;
 static u64 cube_factor __read_mostly;
@@ -44,6 +68,13 @@ module_param(bic_scale, int, 0444);
 MODULE_PARM_DESC(bic_scale, "scale (scaled by 1024) value for bic function (bic_scale/1024)");
 module_param(tcp_friendliness, int, 0644);
 MODULE_PARM_DESC(tcp_friendliness, "turn on/off tcp friendliness");
+module_param(hystart, int, 0644);
+MODULE_PARM_DESC(hystart, "turn on/off hybrid slow start algorithm");
+module_param(hystart_detect, int, 0644);
+MODULE_PARM_DESC(hystart_detect, "hyrbrid slow start detection mechanisms"
+                " 1: packet-train 2: delay 3: both packet-train and delay");
+module_param(hystart_low_window, int, 0644);
+MODULE_PARM_DESC(hystart_low_window, "lower bound cwnd for hybrid slow start");
 
 /* BIC TCP Parameters */
 struct bictcp {
@@ -59,7 +90,13 @@ struct bictcp {
        u32     ack_cnt;        /* number of acks */
        u32     tcp_cwnd;       /* estimated tcp cwnd */
 #define ACK_RATIO_SHIFT        4
-       u32     delayed_ack;    /* estimate the ratio of Packets/ACKs << 4 */
+       u16     delayed_ack;    /* estimate the ratio of Packets/ACKs << 4 */
+       u8      sample_cnt;     /* number of samples to decide curr_rtt */
+       u8      found;          /* the exit point is found? */
+       u32     round_start;    /* beginning of each round */
+       u32     end_seq;        /* end_seq of the round */
+       u32     last_jiffies;   /* last time when the ACK spacing is close */
+       u32     curr_rtt;       /* the minimum rtt of current round */
 };
 
 static inline void bictcp_reset(struct bictcp *ca)
@@ -76,12 +113,28 @@ static inline void bictcp_reset(struct bictcp *ca)
        ca->delayed_ack = 2 << ACK_RATIO_SHIFT;
        ca->ack_cnt = 0;
        ca->tcp_cwnd = 0;
+       ca->found = 0;
+}
+
+static inline void bictcp_hystart_reset(struct sock *sk)
+{
+       struct tcp_sock *tp = tcp_sk(sk);
+       struct bictcp *ca = inet_csk_ca(sk);
+
+       ca->round_start = ca->last_jiffies = jiffies;
+       ca->end_seq = tp->snd_nxt;
+       ca->curr_rtt = 0;
+       ca->sample_cnt = 0;
 }
 
 static void bictcp_init(struct sock *sk)
 {
        bictcp_reset(inet_csk_ca(sk));
-       if (initial_ssthresh)
+
+       if (hystart)
+               bictcp_hystart_reset(sk);
+
+       if (!hystart && initial_ssthresh)
                tcp_sk(sk)->snd_ssthresh = initial_ssthresh;
 }
 
@@ -235,9 +288,11 @@ static void bictcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
        if (!tcp_is_cwnd_limited(sk, in_flight))
                return;
 
-       if (tp->snd_cwnd <= tp->snd_ssthresh)
+       if (tp->snd_cwnd <= tp->snd_ssthresh) {
+               if (hystart && after(ack, ca->end_seq))
+                       bictcp_hystart_reset(sk);
                tcp_slow_start(tp);
-       else {
+       else {
                bictcp_update(ca, tp->snd_cwnd);
 
                /* In dangerous area, increase slowly.
@@ -281,8 +336,45 @@ static u32 bictcp_undo_cwnd(struct sock *sk)
 
 static void bictcp_state(struct sock *sk, u8 new_state)
 {
-       if (new_state == TCP_CA_Loss)
+       if (new_state == TCP_CA_Loss) {
                bictcp_reset(inet_csk_ca(sk));
+               bictcp_hystart_reset(sk);
+       }
+}
+
+static void hystart_update(struct sock *sk, u32 delay)
+{
+       struct tcp_sock *tp = tcp_sk(sk);
+       struct bictcp *ca = inet_csk_ca(sk);
+
+       if (!(ca->found & hystart_detect)) {
+               u32 curr_jiffies = jiffies;
+
+               /* first detection parameter - ack-train detection */
+               if (curr_jiffies - ca->last_jiffies <= msecs_to_jiffies(2)) {
+                       ca->last_jiffies = curr_jiffies;
+                       if (curr_jiffies - ca->round_start >= ca->delay_min>>4)
+                               ca->found |= HYSTART_ACK_TRAIN;
+               }
+
+               /* obtain the minimum delay of more than sampling packets */
+               if (ca->sample_cnt < HYSTART_MIN_SAMPLES) {
+                       if (ca->curr_rtt == 0 || ca->curr_rtt > delay)
+                               ca->curr_rtt = delay;
+
+                       ca->sample_cnt++;
+               } else {
+                       if (ca->curr_rtt > ca->delay_min +
+                           HYSTART_DELAY_THRESH(ca->delay_min>>4))
+                               ca->found |= HYSTART_DELAY;
+               }
+               /*
+                * Either one of two conditions are met,
+                * we exit from slow start immediately.
+                */
+               if (ca->found & hystart_detect)
+                       tp->snd_ssthresh = tp->snd_cwnd;
+       }
 }
 
 /* Track delayed acknowledgment ratio using sliding window
@@ -291,6 +383,7 @@ static void bictcp_state(struct sock *sk, u8 new_state)
 static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us)
 {
        const struct inet_connection_sock *icsk = inet_csk(sk);
+       const struct tcp_sock *tp = tcp_sk(sk);
        struct bictcp *ca = inet_csk_ca(sk);
        u32 delay;
 
@@ -314,6 +407,11 @@ static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us)
        /* first time call or link delay decreases */
        if (ca->delay_min == 0 || ca->delay_min > delay)
                ca->delay_min = delay;
+
+       /* hystart triggers when cwnd is larger than some threshold */
+       if (hystart && tp->snd_cwnd <= tp->snd_ssthresh &&
+           tp->snd_cwnd >= hystart_low_window)
+               hystart_update(sk, delay);
 }
 
 static struct tcp_congestion_ops cubictcp = {
@@ -372,4 +470,4 @@ module_exit(cubictcp_unregister);
 MODULE_AUTHOR("Sangtae Ha, Stephen Hemminger");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("CUBIC TCP");
-MODULE_VERSION("2.2");
+MODULE_VERSION("2.3");
index d77c0d29e2396bb6c2e4ea4cc159019a106be325..097294b7da3e12e9d81d22a0f9840f25e9d40c6e 100644 (file)
@@ -2336,9 +2336,9 @@ static void DBGUNDO(struct sock *sk, const char *msg)
        struct inet_sock *inet = inet_sk(sk);
 
        if (sk->sk_family == AF_INET) {
-               printk(KERN_DEBUG "Undo %s " NIPQUAD_FMT "/%u c%u l%u ss%u/%u p%u\n",
+               printk(KERN_DEBUG "Undo %s %pI4/%u c%u l%u ss%u/%u p%u\n",
                       msg,
-                      NIPQUAD(inet->daddr), ntohs(inet->dport),
+                      &inet->daddr, ntohs(inet->dport),
                       tp->snd_cwnd, tcp_left_out(tp),
                       tp->snd_ssthresh, tp->prior_ssthresh,
                       tp->packets_out);
@@ -2346,9 +2346,9 @@ static void DBGUNDO(struct sock *sk, const char *msg)
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
        else if (sk->sk_family == AF_INET6) {
                struct ipv6_pinfo *np = inet6_sk(sk);
-               printk(KERN_DEBUG "Undo %s " NIP6_FMT "/%u c%u l%u ss%u/%u p%u\n",
+               printk(KERN_DEBUG "Undo %s %pI6/%u c%u l%u ss%u/%u p%u\n",
                       msg,
-                      NIP6(np->daddr), ntohs(inet->dport),
+                      &np->daddr, ntohs(inet->dport),
                       tp->snd_cwnd, tcp_left_out(tp),
                       tp->snd_ssthresh, tp->prior_ssthresh,
                       tp->packets_out);
index 5c8fa7f1e327821dbcb378244e8674183025906c..b2e3ab2287baa57ef883ba572cc76e29bb18f247 100644 (file)
@@ -1139,10 +1139,9 @@ static int tcp_v4_inbound_md5_hash(struct sock *sk, struct sk_buff *skb)
 
        if (genhash || memcmp(hash_location, newhash, 16) != 0) {
                if (net_ratelimit()) {
-                       printk(KERN_INFO "MD5 Hash failed for "
-                              "(" NIPQUAD_FMT ", %d)->(" NIPQUAD_FMT ", %d)%s\n",
-                              NIPQUAD(iph->saddr), ntohs(th->source),
-                              NIPQUAD(iph->daddr), ntohs(th->dest),
+                       printk(KERN_INFO "MD5 Hash failed for (%pI4, %d)->(%pI4, %d)%s\n",
+                              &iph->saddr, ntohs(th->source),
+                              &iph->daddr, ntohs(th->dest),
                               genhash ? " tcp_v4_calc_md5_hash failed" : "");
                }
                return 1;
@@ -1297,10 +1296,8 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
                         * to destinations, already remembered
                         * to the moment of synflood.
                         */
-                       LIMIT_NETDEBUG(KERN_DEBUG "TCP: drop open "
-                                      "request from " NIPQUAD_FMT "/%u\n",
-                                      NIPQUAD(saddr),
-                                      ntohs(tcp_hdr(skb)->source));
+                       LIMIT_NETDEBUG(KERN_DEBUG "TCP: drop open request from %pI4/%u\n",
+                                      &saddr, ntohs(tcp_hdr(skb)->source));
                        goto drop_and_release;
                }
 
@@ -1860,16 +1857,16 @@ EXPORT_SYMBOL(tcp_v4_destroy_sock);
 #ifdef CONFIG_PROC_FS
 /* Proc filesystem TCP sock list dumping. */
 
-static inline struct inet_timewait_sock *tw_head(struct hlist_head *head)
+static inline struct inet_timewait_sock *tw_head(struct hlist_nulls_head *head)
 {
-       return hlist_empty(head) ? NULL :
+       return hlist_nulls_empty(head) ? NULL :
                list_entry(head->first, struct inet_timewait_sock, tw_node);
 }
 
 static inline struct inet_timewait_sock *tw_next(struct inet_timewait_sock *tw)
 {
-       return tw->tw_node.next ?
-               hlist_entry(tw->tw_node.next, typeof(*tw), tw_node) : NULL;
+       return !is_a_nulls(tw->tw_node.next) ?
+               hlist_nulls_entry(tw->tw_node.next, typeof(*tw), tw_node) : NULL;
 }
 
 static void *listening_get_next(struct seq_file *seq, void *cur)
@@ -1877,7 +1874,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur)
        struct inet_connection_sock *icsk;
        struct hlist_node *node;
        struct sock *sk = cur;
-       struct tcp_iter_statest = seq->private;
+       struct tcp_iter_state *st = seq->private;
        struct net *net = seq_file_net(seq);
 
        if (!sk) {
@@ -1957,19 +1954,19 @@ static void *listening_get_idx(struct seq_file *seq, loff_t *pos)
 
 static inline int empty_bucket(struct tcp_iter_state *st)
 {
-       return hlist_empty(&tcp_hashinfo.ehash[st->bucket].chain) &&
-               hlist_empty(&tcp_hashinfo.ehash[st->bucket].twchain);
+       return hlist_nulls_empty(&tcp_hashinfo.ehash[st->bucket].chain) &&
+               hlist_nulls_empty(&tcp_hashinfo.ehash[st->bucket].twchain);
 }
 
 static void *established_get_first(struct seq_file *seq)
 {
-       struct tcp_iter_statest = seq->private;
+       struct tcp_iter_state *st = seq->private;
        struct net *net = seq_file_net(seq);
        void *rc = NULL;
 
        for (st->bucket = 0; st->bucket < tcp_hashinfo.ehash_size; ++st->bucket) {
                struct sock *sk;
-               struct hlist_node *node;
+               struct hlist_nulls_node *node;
                struct inet_timewait_sock *tw;
                rwlock_t *lock = inet_ehash_lockp(&tcp_hashinfo, st->bucket);
 
@@ -1978,7 +1975,7 @@ static void *established_get_first(struct seq_file *seq)
                        continue;
 
                read_lock_bh(lock);
-               sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
+               sk_nulls_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
                        if (sk->sk_family != st->family ||
                            !net_eq(sock_net(sk), net)) {
                                continue;
@@ -2007,8 +2004,8 @@ static void *established_get_next(struct seq_file *seq, void *cur)
 {
        struct sock *sk = cur;
        struct inet_timewait_sock *tw;
-       struct hlist_node *node;
-       struct tcp_iter_statest = seq->private;
+       struct hlist_nulls_node *node;
+       struct tcp_iter_state *st = seq->private;
        struct net *net = seq_file_net(seq);
 
        ++st->num;
@@ -2035,11 +2032,11 @@ get_tw:
                        return NULL;
 
                read_lock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket));
-               sk = sk_head(&tcp_hashinfo.ehash[st->bucket].chain);
+               sk = sk_nulls_head(&tcp_hashinfo.ehash[st->bucket].chain);
        } else
-               sk = sk_next(sk);
+               sk = sk_nulls_next(sk);
 
-       sk_for_each_from(sk, node) {
+       sk_nulls_for_each_from(sk, node) {
                if (sk->sk_family == st->family && net_eq(sock_net(sk), net))
                        goto found;
        }
@@ -2067,7 +2064,7 @@ static void *established_get_idx(struct seq_file *seq, loff_t pos)
 static void *tcp_get_idx(struct seq_file *seq, loff_t pos)
 {
        void *rc;
-       struct tcp_iter_statest = seq->private;
+       struct tcp_iter_state *st = seq->private;
 
        inet_listen_lock(&tcp_hashinfo);
        st->state = TCP_SEQ_STATE_LISTENING;
@@ -2084,7 +2081,7 @@ static void *tcp_get_idx(struct seq_file *seq, loff_t pos)
 
 static void *tcp_seq_start(struct seq_file *seq, loff_t *pos)
 {
-       struct tcp_iter_statest = seq->private;
+       struct tcp_iter_state *st = seq->private;
        st->state = TCP_SEQ_STATE_LISTENING;
        st->num = 0;
        return *pos ? tcp_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
@@ -2093,7 +2090,7 @@ static void *tcp_seq_start(struct seq_file *seq, loff_t *pos)
 static void *tcp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
        void *rc = NULL;
-       struct tcp_iter_statest;
+       struct tcp_iter_state *st;
 
        if (v == SEQ_START_TOKEN) {
                rc = tcp_get_idx(seq, 0);
@@ -2123,7 +2120,7 @@ out:
 
 static void tcp_seq_stop(struct seq_file *seq, void *v)
 {
-       struct tcp_iter_statest = seq->private;
+       struct tcp_iter_state *st = seq->private;
 
        switch (st->state) {
        case TCP_SEQ_STATE_OPENREQ:
@@ -2284,7 +2281,7 @@ static void get_timewait4_sock(struct inet_timewait_sock *tw,
 
 static int tcp4_seq_show(struct seq_file *seq, void *v)
 {
-       struct tcp_iter_statest;
+       struct tcp_iter_state *st;
        int len;
 
        if (v == SEQ_START_TOKEN) {
@@ -2378,6 +2375,7 @@ struct proto tcp_prot = {
        .sysctl_rmem            = sysctl_tcp_rmem,
        .max_header             = MAX_TCP_HEADER,
        .obj_size               = sizeof(struct tcp_sock),
+       .slab_flags             = SLAB_DESTROY_BY_RCU,
        .twsk_prot              = &tcp_timewait_sock_ops,
        .rsk_prot               = &tcp_request_sock_ops,
        .h.hashinfo             = &tcp_hashinfo,
index 779f2e9d0689449bbf94b3e9c061269c05708d7c..f67effbb102be04ae72b759fa24bef202612f296 100644 (file)
@@ -491,7 +491,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
  *     as a request_sock.
  */
 
-struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
+struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
                           struct request_sock *req,
                           struct request_sock **prev)
 {
index ba85d8831893183b6f72053f5b4952a54cdf0ba5..a524627923aef497fb87a274db5c2c37e767dd55 100644 (file)
@@ -42,7 +42,7 @@
 /* People can turn this off for buggy TCP's found in printers etc. */
 int sysctl_tcp_retrans_collapse __read_mostly = 1;
 
-/* People can turn this on to  work with those rare, broken TCPs that
+/* People can turn this on to work with those rare, broken TCPs that
  * interpret the window field as a signed quantity.
  */
 int sysctl_tcp_workaround_signed_windows __read_mostly = 0;
@@ -484,7 +484,7 @@ static unsigned tcp_syn_options(struct sock *sk, struct sk_buff *skb,
        }
        if (likely(sysctl_tcp_window_scaling)) {
                opts->ws = tp->rx_opt.rcv_wscale;
-               if(likely(opts->ws))
+               if (likely(opts->ws))
                        size += TCPOLEN_WSCALE_ALIGNED;
        }
        if (likely(sysctl_tcp_sack)) {
@@ -526,7 +526,7 @@ static unsigned tcp_synack_options(struct sock *sk,
 
        if (likely(ireq->wscale_ok)) {
                opts->ws = ireq->rcv_wscale;
-               if(likely(opts->ws))
+               if (likely(opts->ws))
                        size += TCPOLEN_WSCALE_ALIGNED;
        }
        if (likely(doing_ts)) {
@@ -1172,7 +1172,7 @@ static int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb,
 
 static inline int tcp_minshall_check(const struct tcp_sock *tp)
 {
-       return after(tp->snd_sml,tp->snd_una) &&
+       return after(tp->snd_sml, tp->snd_una) &&
                !after(tp->snd_sml, tp->snd_nxt);
 }
 
index 7ddc30f0744ff13afe250c37f000fe46d144efcc..25524d4e372a387a4897c64281c3bd8eefc70b53 100644 (file)
@@ -153,12 +153,11 @@ static int tcpprobe_sprint(char *tbuf, int n)
                = ktime_to_timespec(ktime_sub(p->tstamp, tcp_probe.start));
 
        return snprintf(tbuf, n,
-                       "%lu.%09lu " NIPQUAD_FMT ":%u " NIPQUAD_FMT ":%u"
-                       " %d %#x %#x %u %u %u %u\n",
+                       "%lu.%09lu %pI4:%u %pI4:%u %d %#x %#x %u %u %u %u\n",
                        (unsigned long) tv.tv_sec,
                        (unsigned long) tv.tv_nsec,
-                       NIPQUAD(p->saddr), ntohs(p->sport),
-                       NIPQUAD(p->daddr), ntohs(p->dport),
+                       &p->saddr, ntohs(p->sport),
+                       &p->daddr, ntohs(p->dport),
                        p->length, p->snd_nxt, p->snd_una,
                        p->snd_cwnd, p->ssthresh, p->snd_wnd, p->srtt);
 }
index 6b6dff1164b93209da97bf673fd76707c216ea1b..3df339e3e363496f32c058cb22ae394be8f4177f 100644 (file)
@@ -171,7 +171,7 @@ static int tcp_write_timeout(struct sock *sk)
 
 static void tcp_delack_timer(unsigned long data)
 {
-       struct sock *sk = (struct sock*)data;
+       struct sock *sk = (struct sock *)data;
        struct tcp_sock *tp = tcp_sk(sk);
        struct inet_connection_sock *icsk = inet_csk(sk);
 
@@ -299,15 +299,15 @@ static void tcp_retransmit_timer(struct sock *sk)
 #ifdef TCP_DEBUG
                struct inet_sock *inet = inet_sk(sk);
                if (sk->sk_family == AF_INET) {
-                       LIMIT_NETDEBUG(KERN_DEBUG "TCP: Treason uncloaked! Peer " NIPQUAD_FMT ":%u/%u shrinks window %u:%u. Repaired.\n",
-                              NIPQUAD(inet->daddr), ntohs(inet->dport),
+                       LIMIT_NETDEBUG(KERN_DEBUG "TCP: Treason uncloaked! Peer %pI4:%u/%u shrinks window %u:%u. Repaired.\n",
+                              &inet->daddr, ntohs(inet->dport),
                               inet->num, tp->snd_una, tp->snd_nxt);
                }
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
                else if (sk->sk_family == AF_INET6) {
                        struct ipv6_pinfo *np = inet6_sk(sk);
-                       LIMIT_NETDEBUG(KERN_DEBUG "TCP: Treason uncloaked! Peer " NIP6_FMT ":%u/%u shrinks window %u:%u. Repaired.\n",
-                              NIP6(np->daddr), ntohs(inet->dport),
+                       LIMIT_NETDEBUG(KERN_DEBUG "TCP: Treason uncloaked! Peer %pI6:%u/%u shrinks window %u:%u. Repaired.\n",
+                              &np->daddr, ntohs(inet->dport),
                               inet->num, tp->snd_una, tp->snd_nxt);
                }
 #endif
@@ -396,7 +396,7 @@ out:;
 
 static void tcp_write_timer(unsigned long data)
 {
-       struct sock *sk = (struct sock*)data;
+       struct sock *sk = (struct sock *)data;
        struct inet_connection_sock *icsk = inet_csk(sk);
        int event;
 
index e03b10183a8b86810cc7f33d4bc69815d3c05f7f..9ec843a9bbb2507a9d96cc088ef6b167747ea603 100644 (file)
@@ -83,7 +83,7 @@ static void tcp_yeah_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
        else if (!yeah->doing_reno_now) {
                /* Scalable */
 
-               tp->snd_cwnd_cnt+=yeah->pkts_acked;
+               tp->snd_cwnd_cnt += yeah->pkts_acked;
                if (tp->snd_cwnd_cnt > min(tp->snd_cwnd, TCP_SCALABLE_AI_CNT)){
                        if (tp->snd_cwnd < tp->snd_cwnd_clamp)
                                tp->snd_cwnd++;
@@ -224,7 +224,7 @@ static u32 tcp_yeah_ssthresh(struct sock *sk) {
 
                reduction = max( reduction, tp->snd_cwnd >> TCP_YEAH_DELTA);
        } else
-               reduction = max(tp->snd_cwnd>>1,2U);
+               reduction = max(tp->snd_cwnd>>1, 2U);
 
        yeah->fast_count = 0;
        yeah->reno_count = max(yeah->reno_count>>1, 2U);
index cf02701ced48091d9eecb6765fe80934a3dc73c8..fea2d873dd419776f352a40de7840625003823c4 100644 (file)
@@ -81,6 +81,8 @@
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
 #include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/swap.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/module.h>
 #include <net/xfrm.h>
 #include "udp_impl.h"
 
-/*
- *     Snmp MIB for the UDP layer
- */
-
-struct hlist_head udp_hash[UDP_HTABLE_SIZE];
-DEFINE_RWLOCK(udp_hash_lock);
+struct udp_table udp_table;
+EXPORT_SYMBOL(udp_table);
 
 int sysctl_udp_mem[3] __read_mostly;
 int sysctl_udp_rmem_min __read_mostly;
@@ -123,15 +121,15 @@ atomic_t udp_memory_allocated;
 EXPORT_SYMBOL(udp_memory_allocated);
 
 static int udp_lib_lport_inuse(struct net *net, __u16 num,
-                              const struct hlist_head udptable[],
+                              const struct udp_hslot *hslot,
                               struct sock *sk,
                               int (*saddr_comp)(const struct sock *sk1,
                                                 const struct sock *sk2))
 {
        struct sock *sk2;
-       struct hlist_node *node;
+       struct hlist_nulls_node *node;
 
-       sk_for_each(sk2, node, &udptable[udp_hashfn(net, num)])
+       sk_nulls_for_each(sk2, node, &hslot->head)
                if (net_eq(sock_net(sk2), net)                  &&
                    sk2 != sk                                   &&
                    sk2->sk_hash == num                         &&
@@ -154,12 +152,11 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
                       int (*saddr_comp)(const struct sock *sk1,
                                         const struct sock *sk2 )    )
 {
-       struct hlist_head *udptable = sk->sk_prot->h.udp_hash;
+       struct udp_hslot *hslot;
+       struct udp_table *udptable = sk->sk_prot->h.udp_table;
        int    error = 1;
        struct net *net = sock_net(sk);
 
-       write_lock_bh(&udp_hash_lock);
-
        if (!snum) {
                int low, high, remaining;
                unsigned rand;
@@ -171,26 +168,34 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
                rand = net_random();
                snum = first = rand % remaining + low;
                rand |= 1;
-               while (udp_lib_lport_inuse(net, snum, udptable, sk,
-                                          saddr_comp)) {
+               for (;;) {
+                       hslot = &udptable->hash[udp_hashfn(net, snum)];
+                       spin_lock_bh(&hslot->lock);
+                       if (!udp_lib_lport_inuse(net, snum, hslot, sk, saddr_comp))
+                               break;
+                       spin_unlock_bh(&hslot->lock);
                        do {
                                snum = snum + rand;
                        } while (snum < low || snum > high);
                        if (snum == first)
                                goto fail;
                }
-       } else if (udp_lib_lport_inuse(net, snum, udptable, sk, saddr_comp))
-               goto fail;
-
+       } else {
+               hslot = &udptable->hash[udp_hashfn(net, snum)];
+               spin_lock_bh(&hslot->lock);
+               if (udp_lib_lport_inuse(net, snum, hslot, sk, saddr_comp))
+                       goto fail_unlock;
+       }
        inet_sk(sk)->num = snum;
        sk->sk_hash = snum;
        if (sk_unhashed(sk)) {
-               sk_add_node(sk, &udptable[udp_hashfn(net, snum)]);
+               sk_nulls_add_node_rcu(sk, &hslot->head);
                sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
        }
        error = 0;
+fail_unlock:
+       spin_unlock_bh(&hslot->lock);
 fail:
-       write_unlock_bh(&udp_hash_lock);
        return error;
 }
 
@@ -208,63 +213,91 @@ int udp_v4_get_port(struct sock *sk, unsigned short snum)
        return udp_lib_get_port(sk, snum, ipv4_rcv_saddr_equal);
 }
 
+static inline int compute_score(struct sock *sk, struct net *net, __be32 saddr,
+                        unsigned short hnum,
+                        __be16 sport, __be32 daddr, __be16 dport, int dif)
+{
+       int score = -1;
+
+       if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum &&
+                       !ipv6_only_sock(sk)) {
+               struct inet_sock *inet = inet_sk(sk);
+
+               score = (sk->sk_family == PF_INET ? 1 : 0);
+               if (inet->rcv_saddr) {
+                       if (inet->rcv_saddr != daddr)
+                               return -1;
+                       score += 2;
+               }
+               if (inet->daddr) {
+                       if (inet->daddr != saddr)
+                               return -1;
+                       score += 2;
+               }
+               if (inet->dport) {
+                       if (inet->dport != sport)
+                               return -1;
+                       score += 2;
+               }
+               if (sk->sk_bound_dev_if) {
+                       if (sk->sk_bound_dev_if != dif)
+                               return -1;
+                       score += 2;
+               }
+       }
+       return score;
+}
+
 /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
  * harder than this. -DaveM
  */
 static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
                __be16 sport, __be32 daddr, __be16 dport,
-               int dif, struct hlist_head udptable[])
+               int dif, struct udp_table *udptable)
 {
-       struct sock *sk, *result = NULL;
-       struct hlist_node *node;
+       struct sock *sk, *result;
+       struct hlist_nulls_node *node;
        unsigned short hnum = ntohs(dport);
-       int badness = -1;
-
-       read_lock(&udp_hash_lock);
-       sk_for_each(sk, node, &udptable[udp_hashfn(net, hnum)]) {
-               struct inet_sock *inet = inet_sk(sk);
-
-               if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum &&
-                               !ipv6_only_sock(sk)) {
-                       int score = (sk->sk_family == PF_INET ? 1 : 0);
-                       if (inet->rcv_saddr) {
-                               if (inet->rcv_saddr != daddr)
-                                       continue;
-                               score+=2;
-                       }
-                       if (inet->daddr) {
-                               if (inet->daddr != saddr)
-                                       continue;
-                               score+=2;
-                       }
-                       if (inet->dport) {
-                               if (inet->dport != sport)
-                                       continue;
-                               score+=2;
-                       }
-                       if (sk->sk_bound_dev_if) {
-                               if (sk->sk_bound_dev_if != dif)
-                                       continue;
-                               score+=2;
-                       }
-                       if (score == 9) {
-                               result = sk;
-                               break;
-                       } else if (score > badness) {
-                               result = sk;
-                               badness = score;
-                       }
+       unsigned int hash = udp_hashfn(net, hnum);
+       struct udp_hslot *hslot = &udptable->hash[hash];
+       int score, badness;
+
+       rcu_read_lock();
+begin:
+       result = NULL;
+       badness = -1;
+       sk_nulls_for_each_rcu(sk, node, &hslot->head) {
+               score = compute_score(sk, net, saddr, hnum, sport,
+                                     daddr, dport, dif);
+               if (score > badness) {
+                       result = sk;
+                       badness = score;
                }
        }
-       if (result)
-               sock_hold(result);
-       read_unlock(&udp_hash_lock);
+       /*
+        * if the nulls value we got at the end of this lookup is
+        * not the expected one, we must restart lookup.
+        * We probably met an item that was moved to another chain.
+        */
+       if (get_nulls_value(node) != hash)
+               goto begin;
+
+       if (result) {
+               if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt)))
+                       result = NULL;
+               else if (unlikely(compute_score(result, net, saddr, hnum, sport,
+                                 daddr, dport, dif) < badness)) {
+                       sock_put(result);
+                       goto begin;
+               }
+       }
+       rcu_read_unlock();
        return result;
 }
 
 static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb,
                                                 __be16 sport, __be16 dport,
-                                                struct hlist_head udptable[])
+                                                struct udp_table *udptable)
 {
        struct sock *sk;
        const struct iphdr *iph = ip_hdr(skb);
@@ -280,7 +313,7 @@ static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb,
 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);
+       return __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, &udp_table);
 }
 EXPORT_SYMBOL_GPL(udp4_lib_lookup);
 
@@ -289,11 +322,11 @@ static inline struct sock *udp_v4_mcast_next(struct net *net, struct sock *sk,
                                             __be16 rmt_port, __be32 rmt_addr,
                                             int dif)
 {
-       struct hlist_node *node;
+       struct hlist_nulls_node *node;
        struct sock *s = sk;
        unsigned short hnum = ntohs(loc_port);
 
-       sk_for_each_from(s, node) {
+       sk_nulls_for_each_from(s, node) {
                struct inet_sock *inet = inet_sk(s);
 
                if (!net_eq(sock_net(s), net)                           ||
@@ -324,7 +357,7 @@ found:
  * to find the appropriate port.
  */
 
-void __udp4_lib_err(struct sk_buff *skb, u32 info, struct hlist_head udptable[])
+void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
 {
        struct inet_sock *inet;
        struct iphdr *iph = (struct iphdr*)skb->data;
@@ -393,7 +426,7 @@ out:
 
 void udp_err(struct sk_buff *skb, u32 info)
 {
-       __udp4_lib_err(skb, info, udp_hash);
+       __udp4_lib_err(skb, info, &udp_table);
 }
 
 /*
@@ -934,6 +967,21 @@ int udp_disconnect(struct sock *sk, int flags)
        return 0;
 }
 
+void udp_lib_unhash(struct sock *sk)
+{
+       struct udp_table *udptable = sk->sk_prot->h.udp_table;
+       unsigned int hash = udp_hashfn(sock_net(sk), sk->sk_hash);
+       struct udp_hslot *hslot = &udptable->hash[hash];
+
+       spin_lock_bh(&hslot->lock);
+       if (sk_nulls_del_node_init_rcu(sk)) {
+               inet_sk(sk)->num = 0;
+               sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
+       }
+       spin_unlock_bh(&hslot->lock);
+}
+EXPORT_SYMBOL(udp_lib_unhash);
+
 static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
        int is_udplite = IS_UDPLITE(sk);
@@ -1072,13 +1120,14 @@ drop:
 static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
                                    struct udphdr  *uh,
                                    __be32 saddr, __be32 daddr,
-                                   struct hlist_head udptable[])
+                                   struct udp_table *udptable)
 {
        struct sock *sk;
+       struct udp_hslot *hslot = &udptable->hash[udp_hashfn(net, ntohs(uh->dest))];
        int dif;
 
-       read_lock(&udp_hash_lock);
-       sk = sk_head(&udptable[udp_hashfn(net, ntohs(uh->dest))]);
+       spin_lock(&hslot->lock);
+       sk = sk_nulls_head(&hslot->head);
        dif = skb->dev->ifindex;
        sk = udp_v4_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif);
        if (sk) {
@@ -1087,7 +1136,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
                do {
                        struct sk_buff *skb1 = skb;
 
-                       sknext = udp_v4_mcast_next(net, sk_next(sk), uh->dest,
+                       sknext = udp_v4_mcast_next(net, sk_nulls_next(sk), uh->dest,
                                                   daddr, uh->source, saddr,
                                                   dif);
                        if (sknext)
@@ -1104,7 +1153,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
                } while (sknext);
        } else
                kfree_skb(skb);
-       read_unlock(&udp_hash_lock);
+       spin_unlock(&hslot->lock);
        return 0;
 }
 
@@ -1150,7 +1199,7 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
  *     All we need to do is get the socket, and then do a checksum.
  */
 
-int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
+int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
                   int proto)
 {
        struct sock *sk;
@@ -1218,13 +1267,13 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
        return 0;
 
 short_packet:
-       LIMIT_NETDEBUG(KERN_DEBUG "UDP%s: short packet: From " NIPQUAD_FMT ":%u %d/%d to " NIPQUAD_FMT ":%u\n",
+       LIMIT_NETDEBUG(KERN_DEBUG "UDP%s: short packet: From %pI4:%u %d/%d to %pI4:%u\n",
                       proto == IPPROTO_UDPLITE ? "-Lite" : "",
-                      NIPQUAD(saddr),
+                      &saddr,
                       ntohs(uh->source),
                       ulen,
                       skb->len,
-                      NIPQUAD(daddr),
+                      &daddr,
                       ntohs(uh->dest));
        goto drop;
 
@@ -1233,11 +1282,11 @@ csum_error:
         * RFC1122: OK.  Discards the bad packet silently (as far as
         * the network is concerned, anyway) as per 4.1.3.4 (MUST).
         */
-       LIMIT_NETDEBUG(KERN_DEBUG "UDP%s: bad checksum. From " NIPQUAD_FMT ":%u to " NIPQUAD_FMT ":%u ulen %d\n",
+       LIMIT_NETDEBUG(KERN_DEBUG "UDP%s: bad checksum. From %pI4:%u to %pI4:%u ulen %d\n",
                       proto == IPPROTO_UDPLITE ? "-Lite" : "",
-                      NIPQUAD(saddr),
+                      &saddr,
                       ntohs(uh->source),
-                      NIPQUAD(daddr),
+                      &daddr,
                       ntohs(uh->dest),
                       ulen);
 drop:
@@ -1248,7 +1297,7 @@ drop:
 
 int udp_rcv(struct sk_buff *skb)
 {
-       return __udp4_lib_rcv(skb, udp_hash, IPPROTO_UDP);
+       return __udp4_lib_rcv(skb, &udp_table, IPPROTO_UDP);
 }
 
 void udp_destroy_sock(struct sock *sk)
@@ -1490,7 +1539,8 @@ struct proto udp_prot = {
        .sysctl_wmem       = &sysctl_udp_wmem_min,
        .sysctl_rmem       = &sysctl_udp_rmem_min,
        .obj_size          = sizeof(struct udp_sock),
-       .h.udp_hash        = udp_hash,
+       .slab_flags        = SLAB_DESTROY_BY_RCU,
+       .h.udp_table       = &udp_table,
 #ifdef CONFIG_COMPAT
        .compat_setsockopt = compat_udp_setsockopt,
        .compat_getsockopt = compat_udp_getsockopt,
@@ -1500,20 +1550,23 @@ struct proto udp_prot = {
 /* ------------------------------------------------------------------------ */
 #ifdef CONFIG_PROC_FS
 
-static struct sock *udp_get_first(struct seq_file *seq)
+static struct sock *udp_get_first(struct seq_file *seq, int start)
 {
        struct sock *sk;
        struct udp_iter_state *state = seq->private;
        struct net *net = seq_file_net(seq);
 
-       for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
-               struct hlist_node *node;
-               sk_for_each(sk, node, state->hashtable + state->bucket) {
+       for (state->bucket = start; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
+               struct hlist_nulls_node *node;
+               struct udp_hslot *hslot = &state->udp_table->hash[state->bucket];
+               spin_lock_bh(&hslot->lock);
+               sk_nulls_for_each(sk, node, &hslot->head) {
                        if (!net_eq(sock_net(sk), net))
                                continue;
                        if (sk->sk_family == state->family)
                                goto found;
                }
+               spin_unlock_bh(&hslot->lock);
        }
        sk = NULL;
 found:
@@ -1526,21 +1579,19 @@ static struct sock *udp_get_next(struct seq_file *seq, struct sock *sk)
        struct net *net = seq_file_net(seq);
 
        do {
-               sk = sk_next(sk);
-try_again:
-               ;
+               sk = sk_nulls_next(sk);
        } while (sk && (!net_eq(sock_net(sk), net) || sk->sk_family != state->family));
 
-       if (!sk && ++state->bucket < UDP_HTABLE_SIZE) {
-               sk = sk_head(state->hashtable + state->bucket);
-               goto try_again;
+       if (!sk) {
+               spin_unlock_bh(&state->udp_table->hash[state->bucket].lock);
+               return udp_get_first(seq, state->bucket + 1);
        }
        return sk;
 }
 
 static struct sock *udp_get_idx(struct seq_file *seq, loff_t pos)
 {
-       struct sock *sk = udp_get_first(seq);
+       struct sock *sk = udp_get_first(seq, 0);
 
        if (sk)
                while (pos && (sk = udp_get_next(seq, sk)) != NULL)
@@ -1549,9 +1600,7 @@ static struct sock *udp_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *udp_seq_start(struct seq_file *seq, loff_t *pos)
-       __acquires(udp_hash_lock)
 {
-       read_lock(&udp_hash_lock);
        return *pos ? udp_get_idx(seq, *pos-1) : SEQ_START_TOKEN;
 }
 
@@ -1569,9 +1618,11 @@ static void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void udp_seq_stop(struct seq_file *seq, void *v)
-       __releases(udp_hash_lock)
 {
-       read_unlock(&udp_hash_lock);
+       struct udp_iter_state *state = seq->private;
+
+       if (state->bucket < UDP_HTABLE_SIZE)
+               spin_unlock_bh(&state->udp_table->hash[state->bucket].lock);
 }
 
 static int udp_seq_open(struct inode *inode, struct file *file)
@@ -1587,7 +1638,7 @@ static int udp_seq_open(struct inode *inode, struct file *file)
 
        s = ((struct seq_file *)file->private_data)->private;
        s->family               = afinfo->family;
-       s->hashtable            = afinfo->hashtable;
+       s->udp_table            = afinfo->udp_table;
        return err;
 }
 
@@ -1659,7 +1710,7 @@ int udp4_seq_show(struct seq_file *seq, void *v)
 static struct udp_seq_afinfo udp4_seq_afinfo = {
        .name           = "udp",
        .family         = AF_INET,
-       .hashtable      = udp_hash,
+       .udp_table      = &udp_table,
        .seq_fops       = {
                .owner  =       THIS_MODULE,
        },
@@ -1694,16 +1745,28 @@ void udp4_proc_exit(void)
 }
 #endif /* CONFIG_PROC_FS */
 
+void __init udp_table_init(struct udp_table *table)
+{
+       int i;
+
+       for (i = 0; i < UDP_HTABLE_SIZE; i++) {
+               INIT_HLIST_NULLS_HEAD(&table->hash[i].head, i);
+               spin_lock_init(&table->hash[i].lock);
+       }
+}
+
 void __init udp_init(void)
 {
-       unsigned long limit;
+       unsigned long nr_pages, limit;
 
+       udp_table_init(&udp_table);
        /* Set the pressure threshold up by the same strategy of TCP. It is a
         * fraction of global memory that is up to 1/2 at 256 MB, decreasing
         * toward zero with the amount of memory, with a floor of 128 pages.
         */
-       limit = min(nr_all_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
-       limit = (limit * (nr_all_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
+       nr_pages = totalram_pages - totalhigh_pages;
+       limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
+       limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
        limit = max(limit, 128UL);
        sysctl_udp_mem[0] = limit / 4 * 3;
        sysctl_udp_mem[1] = limit;
@@ -1714,8 +1777,6 @@ void __init udp_init(void)
 }
 
 EXPORT_SYMBOL(udp_disconnect);
-EXPORT_SYMBOL(udp_hash);
-EXPORT_SYMBOL(udp_hash_lock);
 EXPORT_SYMBOL(udp_ioctl);
 EXPORT_SYMBOL(udp_prot);
 EXPORT_SYMBOL(udp_sendmsg);
index 2e9bad2fa1bcd682049846179e2ee19ecf1bd1b6..9f4a6165f7229ca68deaf98aeadae777a61437a0 100644 (file)
@@ -5,8 +5,8 @@
 #include <net/protocol.h>
 #include <net/inet_common.h>
 
-extern int     __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int );
-extern void    __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []);
+extern int     __udp4_lib_rcv(struct sk_buff *, struct udp_table *, int );
+extern void    __udp4_lib_err(struct sk_buff *, u32, struct udp_table *);
 
 extern int     udp_v4_get_port(struct sock *sk, unsigned short snum);
 
index 3c807964da96a95eb08f738974abda92b0959f87..c784891cb7e57b3f037b26f858c714bfc9614a33 100644 (file)
  */
 #include "udp_impl.h"
 
-struct hlist_head      udplite_hash[UDP_HTABLE_SIZE];
+struct udp_table       udplite_table;
+EXPORT_SYMBOL(udplite_table);
 
 static int udplite_rcv(struct sk_buff *skb)
 {
-       return __udp4_lib_rcv(skb, udplite_hash, IPPROTO_UDPLITE);
+       return __udp4_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE);
 }
 
 static void udplite_err(struct sk_buff *skb, u32 info)
 {
-       __udp4_lib_err(skb, info, udplite_hash);
+       __udp4_lib_err(skb, info, &udplite_table);
 }
 
 static struct net_protocol udplite_protocol = {
@@ -50,7 +51,8 @@ struct proto  udplite_prot = {
        .unhash            = udp_lib_unhash,
        .get_port          = udp_v4_get_port,
        .obj_size          = sizeof(struct udp_sock),
-       .h.udp_hash        = udplite_hash,
+       .slab_flags        = SLAB_DESTROY_BY_RCU,
+       .h.udp_table       = &udplite_table,
 #ifdef CONFIG_COMPAT
        .compat_setsockopt = compat_udp_setsockopt,
        .compat_getsockopt = compat_udp_getsockopt,
@@ -71,7 +73,7 @@ static struct inet_protosw udplite4_protosw = {
 static struct udp_seq_afinfo udplite4_seq_afinfo = {
        .name           = "udplite",
        .family         = AF_INET,
-       .hashtable      = udplite_hash,
+       .udp_table      = &udplite_table,
        .seq_fops       = {
                .owner  =       THIS_MODULE,
        },
@@ -108,6 +110,7 @@ static inline int udplite4_proc_init(void)
 
 void __init udplite4_register(void)
 {
+       udp_table_init(&udplite_table);
        if (proto_register(&udplite_prot, 1))
                goto out_register_err;
 
@@ -126,5 +129,4 @@ out_register_err:
        printk(KERN_CRIT "%s: Cannot add UDP-Lite protocol.\n", __func__);
 }
 
-EXPORT_SYMBOL(udplite_hash);
 EXPORT_SYMBOL(udplite_prot);
index c63de0a72aba746184e1c4e9f97aefe57cdff1a8..84dbb5a03cc21ce864a67d01e677cac2d8c67c0f 100644 (file)
@@ -65,7 +65,7 @@ __xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
 
        read_lock_bh(&policy->lock);
        for (dst = policy->bundles; dst; dst = dst->next) {
-               struct xfrm_dst *xdst = (struct xfrm_dst*)dst;
+               struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
                if (xdst->u.rt.fl.oif == fl->oif &&     /*XXX*/
                    xdst->u.rt.fl.fl4_dst == fl->fl4_dst &&
                    xdst->u.rt.fl.fl4_src == fl->fl4_src &&
@@ -246,7 +246,6 @@ static struct dst_ops xfrm4_dst_ops = {
        .ifdown =               xfrm4_dst_ifdown,
        .local_out =            __ip_local_out,
        .gc_thresh =            1024,
-       .entry_size =           sizeof(struct xfrm_dst),
        .entries =              ATOMIC_INIT(0),
 };
 
index d9da5eb9dcb20c81f9b04619b6b2f9c73c7f0ca7..0e41f1be6dc9ca0694a91f592e65b5bd46be65f2 100644 (file)
@@ -2988,9 +2988,8 @@ static void if6_seq_stop(struct seq_file *seq, void *v)
 static int if6_seq_show(struct seq_file *seq, void *v)
 {
        struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
-       seq_printf(seq,
-                  NIP6_SEQFMT " %02x %02x %02x %02x %8s\n",
-                  NIP6(ifp->addr),
+       seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
+                  &ifp->addr,
                   ifp->idev->dev->ifindex,
                   ifp->prefix_len,
                   ifp->scope,
@@ -4033,8 +4032,8 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.forwarding,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &addrconf_sysctl_forward,
-                       .strategy       =       &addrconf_sysctl_forward_strategy,
+                       .proc_handler   =       addrconf_sysctl_forward,
+                       .strategy       =       addrconf_sysctl_forward_strategy,
                },
                {
                        .ctl_name       =       NET_IPV6_HOP_LIMIT,
@@ -4050,7 +4049,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.mtu6,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       NET_IPV6_ACCEPT_RA,
@@ -4058,7 +4057,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.accept_ra,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       NET_IPV6_ACCEPT_REDIRECTS,
@@ -4066,7 +4065,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.accept_redirects,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       NET_IPV6_AUTOCONF,
@@ -4074,7 +4073,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.autoconf,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       NET_IPV6_DAD_TRANSMITS,
@@ -4082,7 +4081,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.dad_transmits,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       NET_IPV6_RTR_SOLICITS,
@@ -4090,7 +4089,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.rtr_solicits,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       NET_IPV6_RTR_SOLICIT_INTERVAL,
@@ -4098,8 +4097,8 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.rtr_solicit_interval,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec_jiffies,
-                       .strategy       =       &sysctl_jiffies,
+                       .proc_handler   =       proc_dointvec_jiffies,
+                       .strategy       =       sysctl_jiffies,
                },
                {
                        .ctl_name       =       NET_IPV6_RTR_SOLICIT_DELAY,
@@ -4107,8 +4106,8 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.rtr_solicit_delay,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec_jiffies,
-                       .strategy       =       &sysctl_jiffies,
+                       .proc_handler   =       proc_dointvec_jiffies,
+                       .strategy       =       sysctl_jiffies,
                },
                {
                        .ctl_name       =       NET_IPV6_FORCE_MLD_VERSION,
@@ -4116,7 +4115,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.force_mld_version,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
 #ifdef CONFIG_IPV6_PRIVACY
                {
@@ -4125,7 +4124,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.use_tempaddr,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       NET_IPV6_TEMP_VALID_LFT,
@@ -4133,7 +4132,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.temp_valid_lft,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       NET_IPV6_TEMP_PREFERED_LFT,
@@ -4141,7 +4140,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.temp_prefered_lft,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       NET_IPV6_REGEN_MAX_RETRY,
@@ -4149,7 +4148,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.regen_max_retry,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       NET_IPV6_MAX_DESYNC_FACTOR,
@@ -4157,7 +4156,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.max_desync_factor,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
 #endif
                {
@@ -4166,7 +4165,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.max_addresses,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       NET_IPV6_ACCEPT_RA_DEFRTR,
@@ -4174,7 +4173,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.accept_ra_defrtr,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       NET_IPV6_ACCEPT_RA_PINFO,
@@ -4182,7 +4181,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.accept_ra_pinfo,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
 #ifdef CONFIG_IPV6_ROUTER_PREF
                {
@@ -4191,7 +4190,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.accept_ra_rtr_pref,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       NET_IPV6_RTR_PROBE_INTERVAL,
@@ -4199,8 +4198,8 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.rtr_probe_interval,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec_jiffies,
-                       .strategy       =       &sysctl_jiffies,
+                       .proc_handler   =       proc_dointvec_jiffies,
+                       .strategy       =       sysctl_jiffies,
                },
 #ifdef CONFIG_IPV6_ROUTE_INFO
                {
@@ -4209,7 +4208,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.accept_ra_rt_info_max_plen,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
 #endif
 #endif
@@ -4219,7 +4218,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.proxy_ndp,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       NET_IPV6_ACCEPT_SOURCE_ROUTE,
@@ -4227,7 +4226,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.accept_source_route,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
 #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
                {
@@ -4236,7 +4235,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.optimistic_dad,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
 
                },
 #endif
@@ -4247,7 +4246,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.mc_forwarding,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
 #endif
                {
@@ -4256,7 +4255,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.disable_ipv6,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       CTL_UNNUMBERED,
@@ -4264,7 +4263,7 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.accept_dad,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       &proc_dointvec,
+                       .proc_handler   =       proc_dointvec,
                },
                {
                        .ctl_name       =       0,      /* sentinel */
index 08909039d87b570617750c8b9e6a27f973bbbfc4..6ff73c4c126aeabc14e102df05d879f4463825e9 100644 (file)
@@ -186,10 +186,8 @@ u32 ipv6_addr_label(struct net *net,
        label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT;
        rcu_read_unlock();
 
-       ADDRLABEL(KERN_DEBUG "%s(addr=" NIP6_FMT ", type=%d, ifindex=%d) => %08x\n",
-                       __func__,
-                       NIP6(*addr), type, ifindex,
-                       label);
+       ADDRLABEL(KERN_DEBUG "%s(addr=%pI6, type=%d, ifindex=%d) => %08x\n",
+                 __func__, addr, type, ifindex, label);
 
        return label;
 }
@@ -203,11 +201,8 @@ static struct ip6addrlbl_entry *ip6addrlbl_alloc(struct net *net,
        struct ip6addrlbl_entry *newp;
        int addrtype;
 
-       ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d, label=%u)\n",
-                       __func__,
-                       NIP6(*prefix), prefixlen,
-                       ifindex,
-                       (unsigned int)label);
+       ADDRLABEL(KERN_DEBUG "%s(prefix=%pI6, prefixlen=%d, ifindex=%d, label=%u)\n",
+                 __func__, prefix, prefixlen, ifindex, (unsigned int)label);
 
        addrtype = ipv6_addr_type(prefix) & (IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK);
 
@@ -294,12 +289,9 @@ static int ip6addrlbl_add(struct net *net,
        struct ip6addrlbl_entry *newp;
        int ret = 0;
 
-       ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d, label=%u, replace=%d)\n",
-                       __func__,
-                       NIP6(*prefix), prefixlen,
-                       ifindex,
-                       (unsigned int)label,
-                       replace);
+       ADDRLABEL(KERN_DEBUG "%s(prefix=%pI6, prefixlen=%d, ifindex=%d, label=%u, replace=%d)\n",
+                 __func__, prefix, prefixlen, ifindex, (unsigned int)label,
+                 replace);
 
        newp = ip6addrlbl_alloc(net, prefix, prefixlen, ifindex, label);
        if (IS_ERR(newp))
@@ -321,10 +313,8 @@ static int __ip6addrlbl_del(struct net *net,
        struct hlist_node *pos, *n;
        int ret = -ESRCH;
 
-       ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d)\n",
-                       __func__,
-                       NIP6(*prefix), prefixlen,
-                       ifindex);
+       ADDRLABEL(KERN_DEBUG "%s(prefix=%pI6, prefixlen=%d, ifindex=%d)\n",
+                 __func__, prefix, prefixlen, ifindex);
 
        hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) {
                if (p->prefixlen == prefixlen &&
@@ -347,10 +337,8 @@ static int ip6addrlbl_del(struct net *net,
        struct in6_addr prefix_buf;
        int ret;
 
-       ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d)\n",
-                       __func__,
-                       NIP6(*prefix), prefixlen,
-                       ifindex);
+       ADDRLABEL(KERN_DEBUG "%s(prefix=%pI6, prefixlen=%d, ifindex=%d)\n",
+                 __func__, prefix, prefixlen, ifindex);
 
        ipv6_addr_prefix(&prefix_buf, prefix, prefixlen);
        spin_lock(&ip6addrlbl_table.lock);
index 2ff0c8233e47a0096e5670aaa3e41d80d7e3f6a3..7a8a01369e5ca2a7fdd9d01888d7d336d9117a74 100644 (file)
@@ -419,8 +419,8 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        if (!x)
                return;
 
-       NETDEBUG(KERN_DEBUG "pmtu discovery on SA AH/%08x/" NIP6_FMT "\n",
-                ntohl(ah->spi), NIP6(iph->daddr));
+       NETDEBUG(KERN_DEBUG "pmtu discovery on SA AH/%08x/%pI6\n",
+                ntohl(ah->spi), &iph->daddr);
 
        xfrm_state_put(x);
 }
index 8336cd81cb4ffbef03708de15f2faad55a5f936d..1ae58bec1de08bf8cb860bb127a2e947d9b149f7 100644 (file)
@@ -512,11 +512,9 @@ static int ac6_seq_show(struct seq_file *seq, void *v)
        struct ifacaddr6 *im = (struct ifacaddr6 *)v;
        struct ac6_iter_state *state = ac6_seq_private(seq);
 
-       seq_printf(seq,
-                  "%-4d %-15s " NIP6_SEQFMT " %5d\n",
+       seq_printf(seq, "%-4d %-15s %pi6 %5d\n",
                   state->dev->ifindex, state->dev->name,
-                  NIP6(im->aca_addr),
-                  im->aca_users);
+                  &im->aca_addr, im->aca_users);
        return 0;
 }
 
index b181b08fb761c4f9cab3e4f06dfc439734213298..c02a6308defe6c98936fb045626ab61eed93f17a 100644 (file)
@@ -367,8 +367,8 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6);
        if (!x)
                return;
-       printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/" NIP6_FMT "\n",
-                       ntohl(esph->spi), NIP6(iph->daddr));
+       printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/%pI6\n",
+                       ntohl(esph->spi), &iph->daddr);
        xfrm_state_put(x);
 }
 
index 6bfffec2371ccf4cced48a9ffb3cdcb512c9dc00..1c7f400a3cfe5d58e95233de5a785b293d2fbeae 100644 (file)
@@ -219,7 +219,7 @@ static int ipv6_dest_hao(struct sk_buff *skb, int optoff)
 
        if (!(ipv6_addr_type(&hao->addr) & IPV6_ADDR_UNICAST)) {
                LIMIT_NETDEBUG(
-                       KERN_DEBUG "hao is not an unicast addr: " NIP6_FMT "\n", NIP6(hao->addr));
+                       KERN_DEBUG "hao is not an unicast addr: %pI6\n", &hao->addr);
                goto discard;
        }
 
index 9b7d19ae5ced5c7aa50dc5e48b98d7d7007c8770..be351009fd03830042ad6eba11bb1767bfdbcc40 100644 (file)
@@ -646,9 +646,10 @@ static int icmpv6_rcv(struct sk_buff *skb)
        int type;
 
        if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+               struct sec_path *sp = skb_sec_path(skb);
                int nh;
 
-               if (!(skb->sp && skb->sp->xvec[skb->sp->len - 1]->props.flags &
+               if (!(sp && sp->xvec[sp->len - 1]->props.flags &
                                 XFRM_STATE_ICMP))
                        goto drop_no_count;
 
@@ -680,8 +681,8 @@ static int icmpv6_rcv(struct sk_buff *skb)
                skb->csum = ~csum_unfold(csum_ipv6_magic(saddr, daddr, skb->len,
                                             IPPROTO_ICMPV6, 0));
                if (__skb_checksum_complete(skb)) {
-                       LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [" NIP6_FMT " > " NIP6_FMT "]\n",
-                                      NIP6(*saddr), NIP6(*daddr));
+                       LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%pI6 > %pI6]\n",
+                                      saddr, daddr);
                        goto discard_it;
                }
        }
@@ -955,8 +956,8 @@ ctl_table ipv6_icmp_table_template[] = {
                .data           = &init_net.ipv6.sysctl.icmpv6_time,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_ms_jiffies,
-               .strategy       = &sysctl_ms_jiffies
+               .proc_handler   = proc_dointvec_ms_jiffies,
+               .strategy       = sysctl_ms_jiffies
        },
        { .ctl_name = 0 },
 };
index 1646a565825513421332b02411f00aa863f9c261..c1b4d401fd950f18762573f6537d634aa5fd4ced 100644 (file)
 void __inet6_hash(struct sock *sk)
 {
        struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo;
-       struct hlist_head *list;
        rwlock_t *lock;
 
        WARN_ON(!sk_unhashed(sk));
 
        if (sk->sk_state == TCP_LISTEN) {
+               struct hlist_head *list;
+
                list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
                lock = &hashinfo->lhash_lock;
                inet_listen_wlock(hashinfo);
+               __sk_add_node(sk, list);
        } else {
                unsigned int hash;
+               struct hlist_nulls_head *list;
+
                sk->sk_hash = hash = inet6_sk_ehashfn(sk);
                list = &inet_ehash_bucket(hashinfo, hash)->chain;
                lock = inet_ehash_lockp(hashinfo, hash);
                write_lock(lock);
+               __sk_nulls_add_node_rcu(sk, list);
        }
 
-       __sk_add_node(sk, list);
        sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
        write_unlock(lock);
 }
@@ -63,33 +67,53 @@ struct sock *__inet6_lookup_established(struct net *net,
                                           const int dif)
 {
        struct sock *sk;
-       const struct hlist_node *node;
+       const struct hlist_nulls_node *node;
        const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
        /* Optimize here for direct hit, only listening connections can
         * have wildcards anyways.
         */
        unsigned int hash = inet6_ehashfn(net, daddr, hnum, saddr, sport);
-       struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
-       rwlock_t *lock = inet_ehash_lockp(hashinfo, hash);
+       unsigned int slot = hash & (hashinfo->ehash_size - 1);
+       struct inet_ehash_bucket *head = &hashinfo->ehash[slot];
 
-       prefetch(head->chain.first);
-       read_lock(lock);
-       sk_for_each(sk, node, &head->chain) {
+
+       rcu_read_lock();
+begin:
+       sk_nulls_for_each_rcu(sk, node, &head->chain) {
                /* For IPV6 do the cheaper port and family tests first. */
-               if (INET6_MATCH(sk, net, hash, saddr, daddr, ports, dif))
-                       goto hit; /* You sunk my battleship! */
+               if (INET6_MATCH(sk, net, hash, saddr, daddr, ports, dif)) {
+                       if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt)))
+                               goto begintw;
+                       if (!INET6_MATCH(sk, net, hash, saddr, daddr, ports, dif)) {
+                               sock_put(sk);
+                               goto begin;
+                       }
+               goto out;
+               }
        }
+       if (get_nulls_value(node) != slot)
+               goto begin;
+
+begintw:
        /* Must check for a TIME_WAIT'er before going to listener hash. */
-       sk_for_each(sk, node, &head->twchain) {
-               if (INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif))
-                       goto hit;
+       sk_nulls_for_each_rcu(sk, node, &head->twchain) {
+               if (INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif)) {
+                       if (unlikely(!atomic_inc_not_zero(&sk->sk_refcnt))) {
+                               sk = NULL;
+                               goto out;
+                       }
+                       if (!INET6_TW_MATCH(sk, net, hash, saddr, daddr, ports, dif)) {
+                               sock_put(sk);
+                               goto begintw;
+                       }
+                       goto out;
+               }
        }
-       read_unlock(lock);
-       return NULL;
-
-hit:
-       sock_hold(sk);
-       read_unlock(lock);
+       if (get_nulls_value(node) != slot)
+               goto begintw;
+       sk = NULL;
+out:
+       rcu_read_unlock();
        return sk;
 }
 EXPORT_SYMBOL(__inet6_lookup_established);
@@ -172,14 +196,14 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
        struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
        rwlock_t *lock = inet_ehash_lockp(hinfo, hash);
        struct sock *sk2;
-       const struct hlist_node *node;
+       const struct hlist_nulls_node *node;
        struct inet_timewait_sock *tw;
 
        prefetch(head->chain.first);
        write_lock(lock);
 
        /* Check TIME-WAIT sockets first. */
-       sk_for_each(sk2, node, &head->twchain) {
+       sk_nulls_for_each(sk2, node, &head->twchain) {
                tw = inet_twsk(sk2);
 
                if (INET6_TW_MATCH(sk2, net, hash, saddr, daddr, ports, dif)) {
@@ -192,7 +216,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
        tw = NULL;
 
        /* And established part... */
-       sk_for_each(sk2, node, &head->chain) {
+       sk_nulls_for_each(sk2, node, &head->chain) {
                if (INET6_MATCH(sk2, net, hash, saddr, daddr, ports, dif))
                        goto not_unique;
        }
@@ -203,7 +227,7 @@ unique:
        inet->num = lport;
        inet->sport = htons(lport);
        WARN_ON(!sk_unhashed(sk));
-       __sk_add_node(sk, &head->chain);
+       __sk_nulls_add_node_rcu(sk, &head->chain);
        sk->sk_hash = hash;
        sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
        write_unlock(lock);
index 37a4e777e3476e0d59060e2694e374ac7408dcc1..7927a8498d17d3a91ad89e49a78a1bd838a6272c 100644 (file)
@@ -696,14 +696,14 @@ static int ip6fl_seq_show(struct seq_file *seq, void *v)
        else {
                struct ip6_flowlabel *fl = v;
                seq_printf(seq,
-                          "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_SEQFMT " %-4d\n",
+                          "%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n",
                           (unsigned)ntohl(fl->label),
                           fl->share,
                           (unsigned)fl->owner,
                           atomic_read(&fl->users),
                           fl->linger/HZ,
                           (long)(fl->expires - jiffies)/HZ,
-                          NIP6(fl->dst),
+                          &fl->dst,
                           fl->opt ? fl->opt->opt_nflen : 0);
        }
        return 0;
index c77db0b95e263cd24a2571c0f76c69dfcc89a0bd..7d92fd97cfb9ec6d42df8a0c0ad54621013ebd0d 100644 (file)
@@ -490,7 +490,7 @@ int ip6_forward(struct sk_buff *skb)
           We don't send redirects to frames decapsulated from IPsec.
         */
        if (skb->dev == dst->dev && dst->neighbour && opt->srcrt == 0 &&
-           !skb->sp) {
+           !skb_sec_path(skb)) {
                struct in6_addr *target = NULL;
                struct rt6_info *rt;
                struct neighbour *n = dst->neighbour;
index 52a7eb0e2c2c0e8fb65b2136828c0f827da7b360..b17377d6f260dee81c8a2db5102408ffe53af4e1 100644 (file)
@@ -297,9 +297,8 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
                const struct mfc6_cache *mfc = v;
                const struct ipmr_mfc_iter *it = seq->private;
 
-               seq_printf(seq,
-                          NIP6_FMT " " NIP6_FMT " %-3d %8ld %8ld %8ld",
-                          NIP6(mfc->mf6c_mcastgrp), NIP6(mfc->mf6c_origin),
+               seq_printf(seq, "%pI6 %pI6 %-3d %8ld %8ld %8ld",
+                          &mfc->mf6c_mcastgrp, &mfc->mf6c_origin,
                           mfc->mf6c_parent,
                           mfc->mfc_un.res.pkt,
                           mfc->mfc_un.res.bytes,
index 4545e4306862b104217aa5189eac1d4b64c1b43e..d4576a9c154f040334bde597122f9a838f315dd7 100644 (file)
@@ -67,8 +67,8 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        if (!x)
                return;
 
-       printk(KERN_DEBUG "pmtu discovery on SA IPCOMP/%08x/" NIP6_FMT "\n",
-                       spi, NIP6(iph->daddr));
+       printk(KERN_DEBUG "pmtu discovery on SA IPCOMP/%08x/%pI6\n",
+                       spi, &iph->daddr);
        xfrm_state_put(x);
 }
 
index d7b3c6d398ae382e1342dba28b86575c03f9fd6d..a76199ecad23fae2688fca8223eb98633dab6e22 100644 (file)
@@ -2430,9 +2430,9 @@ static int igmp6_mc_seq_show(struct seq_file *seq, void *v)
        struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
 
        seq_printf(seq,
-                  "%-4d %-15s " NIP6_SEQFMT " %5d %08X %ld\n",
+                  "%-4d %-15s %pi6 %5d %08X %ld\n",
                   state->dev->ifindex, state->dev->name,
-                  NIP6(im->mca_addr),
+                  &im->mca_addr,
                   im->mca_users, im->mca_flags,
                   (im->mca_flags&MAF_TIMER_RUNNING) ?
                   jiffies_to_clock_t(im->mca_timer.expires-jiffies) : 0);
@@ -2591,10 +2591,10 @@ static int igmp6_mcf_seq_show(struct seq_file *seq, void *v)
                           "Source Address", "INC", "EXC");
        } else {
                seq_printf(seq,
-                          "%3d %6.6s " NIP6_SEQFMT " " NIP6_SEQFMT " %6lu %6lu\n",
+                          "%3d %6.6s %pi6 %pi6 %6lu %6lu\n",
                           state->dev->ifindex, state->dev->name,
-                          NIP6(state->im->mca_addr),
-                          NIP6(psf->sf_addr),
+                          &state->im->mca_addr,
+                          &psf->sf_addr,
                           psf->sf_count[MCAST_INCLUDE],
                           psf->sf_count[MCAST_EXCLUDE]);
        }
index 172438320eec74287b045cd6b784bb3de0b38b0f..fbf451c0d77ae469bc7ea0bd54a11728d826a468 100644 (file)
@@ -437,38 +437,20 @@ static void pndisc_destructor(struct pneigh_entry *n)
        ipv6_dev_mc_dec(dev, &maddr);
 }
 
-/*
- *     Send a Neighbour Advertisement
- */
-static void __ndisc_send(struct net_device *dev,
-                        struct neighbour *neigh,
-                        const struct in6_addr *daddr,
-                        const struct in6_addr *saddr,
-                        struct icmp6hdr *icmp6h, const struct in6_addr *target,
-                        int llinfo)
+struct sk_buff *ndisc_build_skb(struct net_device *dev,
+                               const struct in6_addr *daddr,
+                               const struct in6_addr *saddr,
+                               struct icmp6hdr *icmp6h,
+                               const struct in6_addr *target,
+                               int llinfo)
 {
-       struct flowi fl;
-       struct dst_entry *dst;
        struct net *net = dev_net(dev);
        struct sock *sk = net->ipv6.ndisc_sk;
        struct sk_buff *skb;
        struct icmp6hdr *hdr;
-       struct inet6_dev *idev;
        int len;
        int err;
-       u8 *opt, type;
-
-       type = icmp6h->icmp6_type;
-
-       icmpv6_flow_init(sk, &fl, type, saddr, daddr, dev->ifindex);
-
-       dst = icmp6_dst_alloc(dev, neigh, daddr);
-       if (!dst)
-               return;
-
-       err = xfrm_lookup(&dst, &fl, NULL, 0);
-       if (err < 0)
-               return;
+       u8 *opt;
 
        if (!dev->addr_len)
                llinfo = 0;
@@ -485,8 +467,7 @@ static void __ndisc_send(struct net_device *dev,
                ND_PRINTK0(KERN_ERR
                           "ICMPv6 ND: %s() failed to allocate an skb.\n",
                           __func__);
-               dst_release(dst);
-               return;
+               return NULL;
        }
 
        skb_reserve(skb, LL_RESERVED_SPACE(dev));
@@ -513,6 +494,42 @@ static void __ndisc_send(struct net_device *dev,
                                           csum_partial((__u8 *) hdr,
                                                        len, 0));
 
+       return skb;
+}
+
+EXPORT_SYMBOL(ndisc_build_skb);
+
+void ndisc_send_skb(struct sk_buff *skb,
+                   struct net_device *dev,
+                   struct neighbour *neigh,
+                   const struct in6_addr *daddr,
+                   const struct in6_addr *saddr,
+                   struct icmp6hdr *icmp6h)
+{
+       struct flowi fl;
+       struct dst_entry *dst;
+       struct net *net = dev_net(dev);
+       struct sock *sk = net->ipv6.ndisc_sk;
+       struct inet6_dev *idev;
+       int err;
+       u8 type;
+
+       type = icmp6h->icmp6_type;
+
+       icmpv6_flow_init(sk, &fl, type, saddr, daddr, dev->ifindex);
+
+       dst = icmp6_dst_alloc(dev, neigh, daddr);
+       if (!dst) {
+               kfree_skb(skb);
+               return;
+       }
+
+       err = xfrm_lookup(&dst, &fl, NULL, 0);
+       if (err < 0) {
+               kfree_skb(skb);
+               return;
+       }
+
        skb->dst = dst;
 
        idev = in6_dev_get(dst->dev);
@@ -529,6 +546,27 @@ static void __ndisc_send(struct net_device *dev,
                in6_dev_put(idev);
 }
 
+EXPORT_SYMBOL(ndisc_send_skb);
+
+/*
+ *     Send a Neighbour Discover packet
+ */
+static void __ndisc_send(struct net_device *dev,
+                        struct neighbour *neigh,
+                        const struct in6_addr *daddr,
+                        const struct in6_addr *saddr,
+                        struct icmp6hdr *icmp6h, const struct in6_addr *target,
+                        int llinfo)
+{
+       struct sk_buff *skb;
+
+       skb = ndisc_build_skb(dev, daddr, saddr, icmp6h, target, llinfo);
+       if (!skb)
+               return;
+
+       ndisc_send_skb(skb, dev, neigh, daddr, saddr, icmp6h);
+}
+
 static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
                          const struct in6_addr *daddr,
                          const struct in6_addr *solicited_addr,
@@ -647,11 +685,8 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
 
        if ((probes -= neigh->parms->ucast_probes) < 0) {
                if (!(neigh->nud_state & NUD_VALID)) {
-                       ND_PRINTK1(KERN_DEBUG
-                                  "%s(): trying to ucast probe in NUD_INVALID: "
-                                  NIP6_FMT "\n",
-                                  __func__,
-                                  NIP6(*target));
+                       ND_PRINTK1(KERN_DEBUG "%s(): trying to ucast probe in NUD_INVALID: %pI6\n",
+                                  __func__, target);
                }
                ndisc_send_ns(dev, neigh, target, target, saddr);
        } else if ((probes -= neigh->parms->app_probes) < 0) {
index caa441d0956755e0e59f8aa62c8572d61b2eb89c..7c668c63f708ec8c06280fcb157d8d0faaa85c9e 100644 (file)
@@ -61,7 +61,7 @@ static void dump_packet(const struct nf_loginfo *info,
        }
 
        /* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */
-       printk("SRC=" NIP6_FMT " DST=" NIP6_FMT " ", NIP6(ih->saddr), NIP6(ih->daddr));
+       printk("SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr);
 
        /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
        printk("LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
@@ -424,9 +424,8 @@ ip6t_log_packet(u_int8_t pf,
                        if (skb->dev->type == ARPHRD_SIT) {
                                const struct iphdr *iph =
                                        (struct iphdr *)skb_mac_header(skb);
-                               printk("TUNNEL=%u.%u.%u.%u->%u.%u.%u.%u ",
-                                      NIPQUAD(iph->saddr),
-                                      NIPQUAD(iph->daddr));
+                               printk("TUNNEL=%pI4->%pI4 ",
+                                      &iph->saddr, &iph->daddr);
                        }
                } else
                        printk(" ");
index e91db16611d902092b956c63031ee1c39a723d66..727b9530448a5fd42562a8163eaadc067da4b5d6 100644 (file)
@@ -56,9 +56,8 @@ static bool ipv6_invert_tuple(struct nf_conntrack_tuple *tuple,
 static int ipv6_print_tuple(struct seq_file *s,
                            const struct nf_conntrack_tuple *tuple)
 {
-       return seq_printf(s, "src=" NIP6_FMT " dst=" NIP6_FMT " ",
-                         NIP6(*((struct in6_addr *)tuple->src.u3.ip6)),
-                         NIP6(*((struct in6_addr *)tuple->dst.u3.ip6)));
+       return seq_printf(s, "src=%pI6 dst=%pI6 ",
+                         tuple->src.u3.ip6, tuple->dst.u3.ip6);
 }
 
 /*
index 05726177903f91a6f460fb41123dbf9f73660305..bd52151d31e92f19146b96dfa324259d46670a0e 100644 (file)
@@ -253,7 +253,7 @@ static struct ctl_table icmpv6_sysctl_table[] = {
                .data           = &nf_ct_icmpv6_timeout,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name       = 0
index 9967ac7a01a87f49323b7e5f0d4ed9ff1ff283b6..ed4d79a9e4a6263225a83f4874692fbca1911754 100644 (file)
@@ -80,7 +80,7 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = {
                .data           = &nf_init_frags.timeout,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name       = NET_NF_CONNTRACK_FRAG6_LOW_THRESH,
@@ -88,7 +88,7 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = {
                .data           = &nf_init_frags.low_thresh,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH,
@@ -96,7 +96,7 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = {
                .data           = &nf_init_frags.high_thresh,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        { .ctl_name = 0 }
 };
index af12de071f4c524c3f6349d982d7fd3dbb97e5a6..3c575118fca51d05d73c35968a0960b1b92a6005 100644 (file)
@@ -642,7 +642,7 @@ static struct ctl_table ip6_frags_ns_ctl_table[] = {
                .data           = &init_net.ipv6.frags.high_thresh,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV6_IP6FRAG_LOW_THRESH,
@@ -650,7 +650,7 @@ static struct ctl_table ip6_frags_ns_ctl_table[] = {
                .data           = &init_net.ipv6.frags.low_thresh,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IPV6_IP6FRAG_TIME,
@@ -658,8 +658,8 @@ static struct ctl_table ip6_frags_ns_ctl_table[] = {
                .data           = &init_net.ipv6.frags.timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies,
        },
        { }
 };
@@ -671,8 +671,8 @@ static struct ctl_table ip6_frags_ctl_table[] = {
                .data           = &ip6_frags.secret_interval,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies
        },
        { }
 };
index 89dc699243404669dc53aba051d2b1c1cb014d92..9da1ece466a2461a1900bca35740c76ea741f745 100644 (file)
@@ -108,7 +108,6 @@ static struct dst_ops ip6_dst_ops_template = {
        .link_failure           =       ip6_link_failure,
        .update_pmtu            =       ip6_rt_update_pmtu,
        .local_out              =       __ip6_local_out,
-       .entry_size             =       sizeof(struct rt6_info),
        .entries                =       ATOMIC_INIT(0),
 };
 
@@ -122,7 +121,6 @@ static struct dst_ops ip6_dst_blackhole_ops = {
        .destroy                =       ip6_dst_destroy,
        .check                  =       ip6_dst_check,
        .update_pmtu            =       ip6_rt_blackhole_update_pmtu,
-       .entry_size             =       sizeof(struct rt6_info),
        .entries                =       ATOMIC_INIT(0),
 };
 
@@ -2408,19 +2406,16 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
 {
        struct seq_file *m = p_arg;
 
-       seq_printf(m, NIP6_SEQFMT " %02x ", NIP6(rt->rt6i_dst.addr),
-                  rt->rt6i_dst.plen);
+       seq_printf(m, "%pi6 %02x ", &rt->rt6i_dst.addr, rt->rt6i_dst.plen);
 
 #ifdef CONFIG_IPV6_SUBTREES
-       seq_printf(m, NIP6_SEQFMT " %02x ", NIP6(rt->rt6i_src.addr),
-                  rt->rt6i_src.plen);
+       seq_printf(m, "%pi6 %02x ", &rt->rt6i_src.addr, rt->rt6i_src.plen);
 #else
        seq_puts(m, "00000000000000000000000000000000 00 ");
 #endif
 
        if (rt->rt6i_nexthop) {
-               seq_printf(m, NIP6_SEQFMT,
-                          NIP6(*((struct in6_addr *)rt->rt6i_nexthop->primary_key)));
+               seq_printf(m, "%pi6", rt->rt6i_nexthop->primary_key);
        } else {
                seq_puts(m, "00000000000000000000000000000000");
        }
@@ -2502,7 +2497,7 @@ ctl_table ipv6_route_table_template[] = {
                .data           =       &init_net.ipv6.sysctl.flush_delay,
                .maxlen         =       sizeof(int),
                .mode           =       0200,
-               .proc_handler   =       &ipv6_sysctl_rtcache_flush
+               .proc_handler   =       ipv6_sysctl_rtcache_flush
        },
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_THRESH,
@@ -2510,7 +2505,7 @@ ctl_table ipv6_route_table_template[] = {
                .data           =       &ip6_dst_ops_template.gc_thresh,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
-               .proc_handler   =       &proc_dointvec,
+               .proc_handler   =       proc_dointvec,
        },
        {
                .ctl_name       =       NET_IPV6_ROUTE_MAX_SIZE,
@@ -2518,7 +2513,7 @@ ctl_table ipv6_route_table_template[] = {
                .data           =       &init_net.ipv6.sysctl.ip6_rt_max_size,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
-               .proc_handler   =       &proc_dointvec,
+               .proc_handler   =       proc_dointvec,
        },
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_MIN_INTERVAL,
@@ -2526,8 +2521,8 @@ ctl_table ipv6_route_table_template[] = {
                .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_min_interval,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
-               .proc_handler   =       &proc_dointvec_jiffies,
-               .strategy       =       &sysctl_jiffies,
+               .proc_handler   =       proc_dointvec_jiffies,
+               .strategy       =       sysctl_jiffies,
        },
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_TIMEOUT,
@@ -2535,8 +2530,8 @@ ctl_table ipv6_route_table_template[] = {
                .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_timeout,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
-               .proc_handler   =       &proc_dointvec_jiffies,
-               .strategy       =       &sysctl_jiffies,
+               .proc_handler   =       proc_dointvec_jiffies,
+               .strategy       =       sysctl_jiffies,
        },
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_INTERVAL,
@@ -2544,8 +2539,8 @@ ctl_table ipv6_route_table_template[] = {
                .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_interval,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
-               .proc_handler   =       &proc_dointvec_jiffies,
-               .strategy       =       &sysctl_jiffies,
+               .proc_handler   =       proc_dointvec_jiffies,
+               .strategy       =       sysctl_jiffies,
        },
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_ELASTICITY,
@@ -2553,8 +2548,8 @@ ctl_table ipv6_route_table_template[] = {
                .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_elasticity,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
-               .proc_handler   =       &proc_dointvec_jiffies,
-               .strategy       =       &sysctl_jiffies,
+               .proc_handler   =       proc_dointvec_jiffies,
+               .strategy       =       sysctl_jiffies,
        },
        {
                .ctl_name       =       NET_IPV6_ROUTE_MTU_EXPIRES,
@@ -2562,8 +2557,8 @@ ctl_table ipv6_route_table_template[] = {
                .data           =       &init_net.ipv6.sysctl.ip6_rt_mtu_expires,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
-               .proc_handler   =       &proc_dointvec_jiffies,
-               .strategy       =       &sysctl_jiffies,
+               .proc_handler   =       proc_dointvec_jiffies,
+               .strategy       =       sysctl_jiffies,
        },
        {
                .ctl_name       =       NET_IPV6_ROUTE_MIN_ADVMSS,
@@ -2571,8 +2566,8 @@ ctl_table ipv6_route_table_template[] = {
                .data           =       &init_net.ipv6.sysctl.ip6_rt_min_advmss,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
-               .proc_handler   =       &proc_dointvec_jiffies,
-               .strategy       =       &sysctl_jiffies,
+               .proc_handler   =       proc_dointvec_jiffies,
+               .strategy       =       sysctl_jiffies,
        },
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS,
@@ -2580,8 +2575,8 @@ ctl_table ipv6_route_table_template[] = {
                .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_min_interval,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
-               .proc_handler   =       &proc_dointvec_ms_jiffies,
-               .strategy       =       &sysctl_ms_jiffies,
+               .proc_handler   =       proc_dointvec_ms_jiffies,
+               .strategy       =       sysctl_ms_jiffies,
        },
        { .ctl_name = 0 }
 };
index 587f8f60c489644d3d6dc5a9748fd85963912ae3..9048fe7e7ea76dd2a62baa8955da06e30577f2e1 100644 (file)
@@ -35,7 +35,7 @@ static ctl_table ipv6_table_template[] = {
                .data           = &init_net.ipv6.sysctl.bindv6only,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        { .ctl_name = 0 }
 };
@@ -47,7 +47,7 @@ static ctl_table ipv6_table[] = {
                .data           = &sysctl_mld_max_msf,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        { .ctl_name = 0 }
 };
index b6b356b7912a57c298a542731c2c9daf24a77bbc..b35787056313ffeb970efc1c1483ac0020b77ffb 100644 (file)
@@ -872,12 +872,10 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
 
        if (genhash || memcmp(hash_location, newhash, 16) != 0) {
                if (net_ratelimit()) {
-                       printk(KERN_INFO "MD5 Hash %s for "
-                              "(" NIP6_FMT ", %u)->"
-                              "(" NIP6_FMT ", %u)\n",
+                       printk(KERN_INFO "MD5 Hash %s for (%pI6, %u)->(%pI6, %u)\n",
                               genhash ? "failed" : "mismatch",
-                              NIP6(ip6h->saddr), ntohs(th->source),
-                              NIP6(ip6h->daddr), ntohs(th->dest));
+                              &ip6h->saddr, ntohs(th->source),
+                              &ip6h->daddr, ntohs(th->dest));
                }
                return 1;
        }
@@ -2045,6 +2043,7 @@ struct proto tcpv6_prot = {
        .sysctl_rmem            = sysctl_tcp_rmem,
        .max_header             = MAX_TCP_HEADER,
        .obj_size               = sizeof(struct tcp6_sock),
+       .slab_flags             = SLAB_DESTROY_BY_RCU,
        .twsk_prot              = &tcp6_timewait_sock_ops,
        .rsk_prot               = &tcp6_request_sock_ops,
        .h.hashinfo             = &tcp_hashinfo,
index 8b48512ebf6ac98ce279a7ca69daa6639970f1e3..fd2d9ad4a8a3589751be7436cbfead1fba208ea3 100644 (file)
@@ -54,62 +54,91 @@ int udp_v6_get_port(struct sock *sk, unsigned short snum)
        return udp_lib_get_port(sk, snum, ipv6_rcv_saddr_equal);
 }
 
+static inline int compute_score(struct sock *sk, struct net *net,
+                               unsigned short hnum,
+                               struct in6_addr *saddr, __be16 sport,
+                               struct in6_addr *daddr, __be16 dport,
+                               int dif)
+{
+       int score = -1;
+
+       if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum &&
+                       sk->sk_family == PF_INET6) {
+               struct ipv6_pinfo *np = inet6_sk(sk);
+               struct inet_sock *inet = inet_sk(sk);
+
+               score = 0;
+               if (inet->dport) {
+                       if (inet->dport != sport)
+                               return -1;
+                       score++;
+               }
+               if (!ipv6_addr_any(&np->rcv_saddr)) {
+                       if (!ipv6_addr_equal(&np->rcv_saddr, daddr))
+                               return -1;
+                       score++;
+               }
+               if (!ipv6_addr_any(&np->daddr)) {
+                       if (!ipv6_addr_equal(&np->daddr, saddr))
+                               return -1;
+                       score++;
+               }
+               if (sk->sk_bound_dev_if) {
+                       if (sk->sk_bound_dev_if != dif)
+                               return -1;
+                       score++;
+               }
+       }
+       return score;
+}
+
 static struct sock *__udp6_lib_lookup(struct net *net,
                                      struct in6_addr *saddr, __be16 sport,
                                      struct in6_addr *daddr, __be16 dport,
-                                     int dif, struct hlist_head udptable[])
+                                     int dif, struct udp_table *udptable)
 {
-       struct sock *sk, *result = NULL;
-       struct hlist_node *node;
+       struct sock *sk, *result;
+       struct hlist_nulls_node *node;
        unsigned short hnum = ntohs(dport);
-       int badness = -1;
-
-       read_lock(&udp_hash_lock);
-       sk_for_each(sk, node, &udptable[udp_hashfn(net, hnum)]) {
-               struct inet_sock *inet = inet_sk(sk);
-
-               if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum &&
-                               sk->sk_family == PF_INET6) {
-                       struct ipv6_pinfo *np = inet6_sk(sk);
-                       int score = 0;
-                       if (inet->dport) {
-                               if (inet->dport != sport)
-                                       continue;
-                               score++;
-                       }
-                       if (!ipv6_addr_any(&np->rcv_saddr)) {
-                               if (!ipv6_addr_equal(&np->rcv_saddr, daddr))
-                                       continue;
-                               score++;
-                       }
-                       if (!ipv6_addr_any(&np->daddr)) {
-                               if (!ipv6_addr_equal(&np->daddr, saddr))
-                                       continue;
-                               score++;
-                       }
-                       if (sk->sk_bound_dev_if) {
-                               if (sk->sk_bound_dev_if != dif)
-                                       continue;
-                               score++;
-                       }
-                       if (score == 4) {
-                               result = sk;
-                               break;
-                       } else if (score > badness) {
-                               result = sk;
-                               badness = score;
-                       }
+       unsigned int hash = udp_hashfn(net, hnum);
+       struct udp_hslot *hslot = &udptable->hash[hash];
+       int score, badness;
+
+       rcu_read_lock();
+begin:
+       result = NULL;
+       badness = -1;
+       sk_nulls_for_each_rcu(sk, node, &hslot->head) {
+               score = compute_score(sk, net, hnum, saddr, sport, daddr, dport, dif);
+               if (score > badness) {
+                       result = sk;
+                       badness = score;
+               }
+       }
+       /*
+        * if the nulls value we got at the end of this lookup is
+        * not the expected one, we must restart lookup.
+        * We probably met an item that was moved to another chain.
+        */
+       if (get_nulls_value(node) != hash)
+               goto begin;
+
+       if (result) {
+               if (unlikely(!atomic_inc_not_zero(&result->sk_refcnt)))
+                       result = NULL;
+               else if (unlikely(compute_score(result, net, hnum, saddr, sport,
+                                       daddr, dport, dif) < badness)) {
+                       sock_put(result);
+                       goto begin;
                }
        }
-       if (result)
-               sock_hold(result);
-       read_unlock(&udp_hash_lock);
+       rcu_read_unlock();
        return result;
 }
 
 static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
                                          __be16 sport, __be16 dport,
-                                         struct hlist_head udptable[])
+                                         struct udp_table *udptable)
 {
        struct sock *sk;
        struct ipv6hdr *iph = ipv6_hdr(skb);
@@ -253,7 +282,7 @@ csum_copy_err:
 
 void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                    int type, int code, int offset, __be32 info,
-                   struct hlist_head udptable[]                    )
+                   struct udp_table *udptable)
 {
        struct ipv6_pinfo *np;
        struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
@@ -289,7 +318,7 @@ static __inline__ void udpv6_err(struct sk_buff *skb,
                                 struct inet6_skb_parm *opt, int type,
                                 int code, int offset, __be32 info     )
 {
-       __udp6_lib_err(skb, opt, type, code, offset, info, udp_hash);
+       __udp6_lib_err(skb, opt, type, code, offset, info, &udp_table);
 }
 
 int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
@@ -347,11 +376,11 @@ static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk,
                                      __be16 rmt_port, struct in6_addr *rmt_addr,
                                      int dif)
 {
-       struct hlist_node *node;
+       struct hlist_nulls_node *node;
        struct sock *s = sk;
        unsigned short num = ntohs(loc_port);
 
-       sk_for_each_from(s, node) {
+       sk_nulls_for_each_from(s, node) {
                struct inet_sock *inet = inet_sk(s);
 
                if (!net_eq(sock_net(s), net))
@@ -388,14 +417,15 @@ static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk,
  */
 static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
                struct in6_addr *saddr, struct in6_addr *daddr,
-               struct hlist_head udptable[])
+               struct udp_table *udptable)
 {
        struct sock *sk, *sk2;
        const struct udphdr *uh = udp_hdr(skb);
+       struct udp_hslot *hslot = &udptable->hash[udp_hashfn(net, ntohs(uh->dest))];
        int dif;
 
-       read_lock(&udp_hash_lock);
-       sk = sk_head(&udptable[udp_hashfn(net, ntohs(uh->dest))]);
+       spin_lock(&hslot->lock);
+       sk = sk_nulls_head(&hslot->head);
        dif = inet6_iif(skb);
        sk = udp_v6_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif);
        if (!sk) {
@@ -404,7 +434,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
        }
 
        sk2 = sk;
-       while ((sk2 = udp_v6_mcast_next(net, sk_next(sk2), uh->dest, daddr,
+       while ((sk2 = udp_v6_mcast_next(net, sk_nulls_next(sk2), uh->dest, daddr,
                                        uh->source, saddr, dif))) {
                struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC);
                if (buff) {
@@ -423,7 +453,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
                sk_add_backlog(sk, skb);
        bh_unlock_sock(sk);
 out:
-       read_unlock(&udp_hash_lock);
+       spin_unlock(&hslot->lock);
        return 0;
 }
 
@@ -461,7 +491,7 @@ static inline int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh,
        return 0;
 }
 
-int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
+int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
                   int proto)
 {
        struct sock *sk;
@@ -558,7 +588,7 @@ discard:
 
 static __inline__ int udpv6_rcv(struct sk_buff *skb)
 {
-       return __udp6_lib_rcv(skb, udp_hash, IPPROTO_UDP);
+       return __udp6_lib_rcv(skb, &udp_table, IPPROTO_UDP);
 }
 
 /*
@@ -1022,7 +1052,7 @@ int udp6_seq_show(struct seq_file *seq, void *v)
 static struct udp_seq_afinfo udp6_seq_afinfo = {
        .name           = "udp6",
        .family         = AF_INET6,
-       .hashtable      = udp_hash,
+       .udp_table      = &udp_table,
        .seq_fops       = {
                .owner  =       THIS_MODULE,
        },
@@ -1064,7 +1094,8 @@ struct proto udpv6_prot = {
        .sysctl_wmem       = &sysctl_udp_wmem_min,
        .sysctl_rmem       = &sysctl_udp_rmem_min,
        .obj_size          = sizeof(struct udp6_sock),
-       .h.udp_hash        = udp_hash,
+       .slab_flags        = SLAB_DESTROY_BY_RCU,
+       .h.udp_table       = &udp_table,
 #ifdef CONFIG_COMPAT
        .compat_setsockopt = compat_udpv6_setsockopt,
        .compat_getsockopt = compat_udpv6_getsockopt,
index 92dd7da766d8c9855a71afd863a39f90418fde46..23779208c334e90aa1bad9100a1d8c84f6b452df 100644 (file)
@@ -7,9 +7,9 @@
 #include <net/inet_common.h>
 #include <net/transp_v6.h>
 
-extern int     __udp6_lib_rcv(struct sk_buff *, struct hlist_head [], int );
+extern int     __udp6_lib_rcv(struct sk_buff *, struct udp_table *, int );
 extern void    __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *,
-                              int , int , int , __be32 , struct hlist_head []);
+                              int , int , int , __be32 , struct udp_table *);
 
 extern int     udp_v6_get_port(struct sock *sk, unsigned short snum);
 
index 3cd1a1ac3d6c7c8dfb686f9b7992a5be9e3095de..ba162a824585b8fcecd2c1022c0c64d09faa68bc 100644 (file)
 
 static int udplitev6_rcv(struct sk_buff *skb)
 {
-       return __udp6_lib_rcv(skb, udplite_hash, IPPROTO_UDPLITE);
+       return __udp6_lib_rcv(skb, &udplite_table, IPPROTO_UDPLITE);
 }
 
 static void udplitev6_err(struct sk_buff *skb,
                          struct inet6_skb_parm *opt,
                          int type, int code, int offset, __be32 info)
 {
-       __udp6_lib_err(skb, opt, type, code, offset, info, udplite_hash);
+       __udp6_lib_err(skb, opt, type, code, offset, info, &udplite_table);
 }
 
 static struct inet6_protocol udplitev6_protocol = {
@@ -49,7 +49,8 @@ struct proto udplitev6_prot = {
        .unhash            = udp_lib_unhash,
        .get_port          = udp_v6_get_port,
        .obj_size          = sizeof(struct udp6_sock),
-       .h.udp_hash        = udplite_hash,
+       .slab_flags        = SLAB_DESTROY_BY_RCU,
+       .h.udp_table       = &udplite_table,
 #ifdef CONFIG_COMPAT
        .compat_setsockopt = compat_udpv6_setsockopt,
        .compat_getsockopt = compat_udpv6_getsockopt,
@@ -95,7 +96,7 @@ void udplitev6_exit(void)
 static struct udp_seq_afinfo udplite6_seq_afinfo = {
        .name           = "udplite6",
        .family         = AF_INET6,
-       .hashtable      = udplite_hash,
+       .udp_table      = &udplite_table,
        .seq_fops       = {
                .owner  =       THIS_MODULE,
        },
index 08e4cbbe3f04e5f64e6d91f8b7864c8108d5e0ef..3b67ce7786ecba68e0c46168aa1510e78abe56ae 100644 (file)
@@ -144,6 +144,7 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
 static inline void
 _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
 {
+       int onlyproto = 0;
        u16 offset = skb_network_header_len(skb);
        struct ipv6hdr *hdr = ipv6_hdr(skb);
        struct ipv6_opt_hdr *exthdr;
@@ -159,6 +160,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
                exthdr = (struct ipv6_opt_hdr *)(nh + offset);
 
                switch (nexthdr) {
+               case NEXTHDR_FRAGMENT:
+                       onlyproto = 1;
                case NEXTHDR_ROUTING:
                case NEXTHDR_HOP:
                case NEXTHDR_DEST:
@@ -172,7 +175,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
                case IPPROTO_TCP:
                case IPPROTO_SCTP:
                case IPPROTO_DCCP:
-                       if (pskb_may_pull(skb, nh + offset + 4 - skb->data)) {
+                       if (!onlyproto && pskb_may_pull(skb, nh + offset + 4 - skb->data)) {
                                __be16 *ports = (__be16 *)exthdr;
 
                                fl->fl_ip_sport = ports[!!reverse];
@@ -182,7 +185,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
                        return;
 
                case IPPROTO_ICMPV6:
-                       if (pskb_may_pull(skb, nh + offset + 2 - skb->data)) {
+                       if (!onlyproto && pskb_may_pull(skb, nh + offset + 2 - skb->data)) {
                                u8 *icmp = (u8 *)exthdr;
 
                                fl->fl_icmp_type = icmp[0];
@@ -193,7 +196,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
 
 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
                case IPPROTO_MH:
-                       if (pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
+                       if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
                                struct ip6_mh *mh;
                                mh = (struct ip6_mh *)exthdr;
 
@@ -274,7 +277,6 @@ static struct dst_ops xfrm6_dst_ops = {
        .ifdown =               xfrm6_dst_ifdown,
        .local_out =            __ip6_local_out,
        .gc_thresh =            1024,
-       .entry_size =           sizeof(struct xfrm_dst),
        .entries =              ATOMIC_INIT(0),
 };
 
index 92fef864e85225a142fc778c8da4afc9e94cb5b9..633fcab355800d782cd6805df9931efbc95bf5c8 100644 (file)
@@ -23,7 +23,7 @@ static struct ctl_table ipx_table[] = {
                .data           = &sysctl_ipx_pprop_broadcasting,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        { 0 },
 };
index 6be1ec26b30cc81cca52309d241dd515105b4cf2..42f7d960d055ca7d8ab0784ddde43ad183943dd2 100644 (file)
@@ -436,7 +436,6 @@ static void irlan_check_response_param(struct irlan_cb *self, char *param,
        __u16 tmp_cpu; /* Temporary value in host order */
        __u8 *bytes;
        int i;
-       DECLARE_MAC_BUF(mac);
 
        IRDA_DEBUG(4, "%s(), parm=%s\n", __func__ , param);
 
@@ -521,8 +520,7 @@ static void irlan_check_response_param(struct irlan_cb *self, char *param,
        /* FILTER_ENTRY, have we got an ethernet address? */
        if (strcmp(param, "FILTER_ENTRY") == 0) {
                bytes = value;
-               IRDA_DEBUG(4, "Ethernet address = %s\n",
-                          print_mac(mac, bytes));
+               IRDA_DEBUG(4, "Ethernet address = %pM\n", bytes);
                for (i = 0; i < 6; i++)
                        self->dev->dev_addr[i] = bytes[i];
        }
index 9a1cd87e71426aaa1c8f4d22318c090a39976683..774d73a76852e1ce63262f8d2a1af343668473d5 100644 (file)
@@ -207,7 +207,7 @@ static struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr)
        if (!dev)
                return NULL;
 
-       self = dev->priv;
+       self = netdev_priv(dev);
        self->dev = dev;
 
        /*
index 9ab3df15425db06014e0a2bb3e337cd687a8e729..57f8817c3979029a38a680d1ea65d948766d2ef9 100644 (file)
@@ -118,8 +118,8 @@ static ctl_table irda_table[] = {
                .data           = &sysctl_discovery,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &do_discovery,
-               .strategy       = &sysctl_intvec
+               .proc_handler   = do_discovery,
+               .strategy       = sysctl_intvec
        },
        {
                .ctl_name       = NET_IRDA_DEVNAME,
@@ -127,8 +127,8 @@ static ctl_table irda_table[] = {
                .data           = sysctl_devname,
                .maxlen         = 65,
                .mode           = 0644,
-               .proc_handler   = &do_devname,
-               .strategy       = &sysctl_string
+               .proc_handler   = do_devname,
+               .strategy       = sysctl_string
        },
 #ifdef CONFIG_IRDA_DEBUG
        {
@@ -137,7 +137,7 @@ static ctl_table irda_table[] = {
                .data           = &irda_debug,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
 #endif
 #ifdef CONFIG_IRDA_FAST_RR
@@ -147,7 +147,7 @@ static ctl_table irda_table[] = {
                .data           = &sysctl_fast_poll_increase,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
 #endif
        {
@@ -156,8 +156,8 @@ static ctl_table irda_table[] = {
                .data           = &sysctl_discovery_slots,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_discovery_slots,
                .extra2         = &max_discovery_slots
        },
@@ -167,7 +167,7 @@ static ctl_table irda_table[] = {
                .data           = &sysctl_discovery_timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        {
                .ctl_name       = NET_IRDA_SLOT_TIMEOUT,
@@ -175,8 +175,8 @@ static ctl_table irda_table[] = {
                .data           = &sysctl_slot_timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_slot_timeout,
                .extra2         = &max_slot_timeout
        },
@@ -186,8 +186,8 @@ static ctl_table irda_table[] = {
                .data           = &sysctl_max_baud_rate,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_max_baud_rate,
                .extra2         = &max_max_baud_rate
        },
@@ -197,8 +197,8 @@ static ctl_table irda_table[] = {
                .data           = &sysctl_min_tx_turn_time,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_min_tx_turn_time,
                .extra2         = &max_min_tx_turn_time
        },
@@ -208,8 +208,8 @@ static ctl_table irda_table[] = {
                .data           = &sysctl_max_tx_data_size,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_max_tx_data_size,
                .extra2         = &max_max_tx_data_size
        },
@@ -219,8 +219,8 @@ static ctl_table irda_table[] = {
                .data           = &sysctl_max_tx_window,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_max_tx_window,
                .extra2         = &max_max_tx_window
        },
@@ -230,8 +230,8 @@ static ctl_table irda_table[] = {
                .data           = &sysctl_max_noreply_time,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_max_noreply_time,
                .extra2         = &max_max_noreply_time
        },
@@ -241,8 +241,8 @@ static ctl_table irda_table[] = {
                .data           = &sysctl_warn_noreply_time,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_warn_noreply_time,
                .extra2         = &max_warn_noreply_time
        },
@@ -252,8 +252,8 @@ static ctl_table irda_table[] = {
                .data           = &sysctl_lap_keepalive_time,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_lap_keepalive_time,
                .extra2         = &max_lap_keepalive_time
        },
index 48212c0a961ca2f5f73d77a239203c4a206562dc..b58bd7c6cdf8b5323df957c1bc113b8970aa9762 100644 (file)
@@ -27,8 +27,7 @@
 
 static void llc_ui_format_mac(struct seq_file *seq, u8 *addr)
 {
-       DECLARE_MAC_BUF(mac);
-       seq_printf(seq, "%s", print_mac(mac, addr));
+       seq_printf(seq, "%pM", addr);
 }
 
 static struct sock *llc_get_sk_idx(loff_t pos)
index 5bef1dcf18e3c1ec060dcdb4f4047376d2a0f417..57b9304d444c115d2e6ef00c17c1f25d41b0f50d 100644 (file)
@@ -20,8 +20,8 @@ static struct ctl_table llc2_timeout_table[] = {
                .data           = &sysctl_llc2_ack_timeout,
                .maxlen         = sizeof(long),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies,
        },
        {
                .ctl_name       = NET_LLC2_BUSY_TIMEOUT,
@@ -29,8 +29,8 @@ static struct ctl_table llc2_timeout_table[] = {
                .data           = &sysctl_llc2_busy_timeout,
                .maxlen         = sizeof(long),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies,
        },
        {
                .ctl_name       = NET_LLC2_P_TIMEOUT,
@@ -38,8 +38,8 @@ static struct ctl_table llc2_timeout_table[] = {
                .data           = &sysctl_llc2_p_timeout,
                .maxlen         = sizeof(long),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies,
        },
        {
                .ctl_name       = NET_LLC2_REJ_TIMEOUT,
@@ -47,8 +47,8 @@ static struct ctl_table llc2_timeout_table[] = {
                .data           = &sysctl_llc2_rej_timeout,
                .maxlen         = sizeof(long),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies,
        },
        { 0 },
 };
@@ -60,8 +60,8 @@ static struct ctl_table llc_station_table[] = {
                .data           = &sysctl_llc_station_ack_timeout,
                .maxlen         = sizeof(long),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
+               .strategy       = sysctl_jiffies,
        },
        { 0 },
 };
index 855126a3039daa16ae64ca60c8087e0439a0d61f..16423f94801bb3a9154e294fa9e95d8602f1806a 100644 (file)
 #include "rate.h"
 #include "mesh.h"
 
-struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy)
-{
-       struct ieee80211_local *local = wiphy_priv(wiphy);
-       return &local->hw;
-}
-EXPORT_SYMBOL(wiphy_to_hw);
-
 static bool nl80211_type_check(enum nl80211_iftype type)
 {
        switch (type) {
@@ -33,6 +26,8 @@ static bool nl80211_type_check(enum nl80211_iftype type)
 #ifdef CONFIG_MAC80211_MESH
        case NL80211_IFTYPE_MESH_POINT:
 #endif
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_AP_VLAN:
        case NL80211_IFTYPE_WDS:
                return true;
        default:
@@ -401,8 +396,8 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
         */
        if (params->interval) {
                sdata->local->hw.conf.beacon_int = params->interval;
-               if (ieee80211_hw_config(sdata->local))
-                       return -EINVAL;
+               ieee80211_hw_config(sdata->local,
+                                   IEEE80211_CONF_CHANGE_BEACON_INTERVAL);
                /*
                 * We updated some parameter so if below bails out
                 * it's not an error.
@@ -589,6 +584,8 @@ static void sta_apply_parameters(struct ieee80211_local *local,
        struct ieee80211_supported_band *sband;
        struct ieee80211_sub_if_data *sdata = sta->sdata;
 
+       sband = local->hw.wiphy->bands[local->oper_channel->band];
+
        /*
         * FIXME: updating the flags is racy when this function is
         *        called from ieee80211_change_station(), this will
@@ -629,7 +626,6 @@ static void sta_apply_parameters(struct ieee80211_local *local,
 
        if (params->supported_rates) {
                rates = 0;
-               sband = local->hw.wiphy->bands[local->oper_channel->band];
 
                for (i = 0; i < params->supported_rates_len; i++) {
                        int rate = (params->supported_rates[i] & 0x7f) * 5;
@@ -641,10 +637,10 @@ static void sta_apply_parameters(struct ieee80211_local *local,
                sta->sta.supp_rates[local->oper_channel->band] = rates;
        }
 
-       if (params->ht_capa) {
-               ieee80211_ht_cap_ie_to_ht_info(params->ht_capa,
-                                              &sta->sta.ht_info);
-       }
+       if (params->ht_capa)
+               ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
+                                                 params->ht_capa,
+                                                 &sta->sta.ht_cap);
 
        if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) {
                switch (params->plink_action) {
@@ -957,6 +953,72 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
        rcu_read_unlock();
        return 0;
 }
+
+static int ieee80211_get_mesh_params(struct wiphy *wiphy,
+                               struct net_device *dev,
+                               struct mesh_config *conf)
+{
+       struct ieee80211_sub_if_data *sdata;
+       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+       if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
+               return -ENOTSUPP;
+       memcpy(conf, &(sdata->u.mesh.mshcfg), sizeof(struct mesh_config));
+       return 0;
+}
+
+static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
+{
+       return (mask >> (parm-1)) & 0x1;
+}
+
+static int ieee80211_set_mesh_params(struct wiphy *wiphy,
+                               struct net_device *dev,
+                               const struct mesh_config *nconf, u32 mask)
+{
+       struct mesh_config *conf;
+       struct ieee80211_sub_if_data *sdata;
+       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+       if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
+               return -ENOTSUPP;
+
+       /* Set the config options which we are interested in setting */
+       conf = &(sdata->u.mesh.mshcfg);
+       if (_chg_mesh_attr(NL80211_MESHCONF_RETRY_TIMEOUT, mask))
+               conf->dot11MeshRetryTimeout = nconf->dot11MeshRetryTimeout;
+       if (_chg_mesh_attr(NL80211_MESHCONF_CONFIRM_TIMEOUT, mask))
+               conf->dot11MeshConfirmTimeout = nconf->dot11MeshConfirmTimeout;
+       if (_chg_mesh_attr(NL80211_MESHCONF_HOLDING_TIMEOUT, mask))
+               conf->dot11MeshHoldingTimeout = nconf->dot11MeshHoldingTimeout;
+       if (_chg_mesh_attr(NL80211_MESHCONF_MAX_PEER_LINKS, mask))
+               conf->dot11MeshMaxPeerLinks = nconf->dot11MeshMaxPeerLinks;
+       if (_chg_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask))
+               conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries;
+       if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask))
+               conf->dot11MeshTTL = nconf->dot11MeshTTL;
+       if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask))
+               conf->auto_open_plinks = nconf->auto_open_plinks;
+       if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask))
+               conf->dot11MeshHWMPmaxPREQretries =
+                       nconf->dot11MeshHWMPmaxPREQretries;
+       if (_chg_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask))
+               conf->path_refresh_time = nconf->path_refresh_time;
+       if (_chg_mesh_attr(NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, mask))
+               conf->min_discovery_timeout = nconf->min_discovery_timeout;
+       if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, mask))
+               conf->dot11MeshHWMPactivePathTimeout =
+                       nconf->dot11MeshHWMPactivePathTimeout;
+       if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask))
+               conf->dot11MeshHWMPpreqMinInterval =
+                       nconf->dot11MeshHWMPpreqMinInterval;
+       if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
+                          mask))
+               conf->dot11MeshHWMPnetDiameterTraversalTime =
+                       nconf->dot11MeshHWMPnetDiameterTraversalTime;
+       return 0;
+}
+
 #endif
 
 static int ieee80211_change_bss(struct wiphy *wiphy,
@@ -972,25 +1034,67 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
                return -EINVAL;
 
        if (params->use_cts_prot >= 0) {
-               sdata->bss_conf.use_cts_prot = params->use_cts_prot;
+               sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot;
                changed |= BSS_CHANGED_ERP_CTS_PROT;
        }
        if (params->use_short_preamble >= 0) {
-               sdata->bss_conf.use_short_preamble =
+               sdata->vif.bss_conf.use_short_preamble =
                        params->use_short_preamble;
                changed |= BSS_CHANGED_ERP_PREAMBLE;
        }
        if (params->use_short_slot_time >= 0) {
-               sdata->bss_conf.use_short_slot =
+               sdata->vif.bss_conf.use_short_slot =
                        params->use_short_slot_time;
                changed |= BSS_CHANGED_ERP_SLOT;
        }
 
+       if (params->basic_rates) {
+               int i, j;
+               u32 rates = 0;
+               struct ieee80211_local *local = wiphy_priv(wiphy);
+               struct ieee80211_supported_band *sband =
+                       wiphy->bands[local->oper_channel->band];
+
+               for (i = 0; i < params->basic_rates_len; i++) {
+                       int rate = (params->basic_rates[i] & 0x7f) * 5;
+                       for (j = 0; j < sband->n_bitrates; j++) {
+                               if (sband->bitrates[j].bitrate == rate)
+                                       rates |= BIT(j);
+                       }
+               }
+               sdata->vif.bss_conf.basic_rates = rates;
+               changed |= BSS_CHANGED_BASIC_RATES;
+       }
+
        ieee80211_bss_info_change_notify(sdata, changed);
 
        return 0;
 }
 
+static int ieee80211_set_txq_params(struct wiphy *wiphy,
+                                   struct ieee80211_txq_params *params)
+{
+       struct ieee80211_local *local = wiphy_priv(wiphy);
+       struct ieee80211_tx_queue_params p;
+
+       if (!local->ops->conf_tx)
+               return -EOPNOTSUPP;
+
+       memset(&p, 0, sizeof(p));
+       p.aifs = params->aifs;
+       p.cw_max = params->cwmax;
+       p.cw_min = params->cwmin;
+       p.txop = params->txop;
+       if (local->ops->conf_tx(local_to_hw(local), params->queue, &p)) {
+               printk(KERN_DEBUG "%s: failed to set TX queue "
+                      "parameters for queue %d\n", local->mdev->name,
+                      params->queue);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 struct cfg80211_ops mac80211_config_ops = {
        .add_virtual_intf = ieee80211_add_iface,
        .del_virtual_intf = ieee80211_del_iface,
@@ -1013,6 +1117,9 @@ struct cfg80211_ops mac80211_config_ops = {
        .change_mpath = ieee80211_change_mpath,
        .get_mpath = ieee80211_get_mpath,
        .dump_mpath = ieee80211_dump_mpath,
+       .set_mesh_params = ieee80211_set_mesh_params,
+       .get_mesh_params = ieee80211_get_mesh_params,
 #endif
        .change_bss = ieee80211_change_bss,
+       .set_txq_params = ieee80211_set_txq_params,
 };
index 24ce544633109c038ee4af718258ddc942311568..2697a2fe608f60978d521acdcb0d90d5ff9ae5b4 100644 (file)
@@ -47,18 +47,14 @@ static const struct file_operations name## _ops = {                 \
 
 DEBUGFS_READONLY_FILE(frequency, 20, "%d",
                      local->hw.conf.channel->center_freq);
-DEBUGFS_READONLY_FILE(antenna_sel_tx, 20, "%d",
-                     local->hw.conf.antenna_sel_tx);
-DEBUGFS_READONLY_FILE(antenna_sel_rx, 20, "%d",
-                     local->hw.conf.antenna_sel_rx);
 DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d",
                      local->rts_threshold);
 DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d",
                      local->fragmentation_threshold);
 DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d",
-                     local->short_retry_limit);
+                     local->hw.conf.short_frame_max_tx_count);
 DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d",
-                     local->long_retry_limit);
+                     local->hw.conf.long_frame_max_tx_count);
 DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d",
                      local->total_ps_buffered);
 DEBUGFS_READONLY_FILE(wep_iv, 20, "%#06x",
@@ -202,8 +198,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
        local->debugfs.keys = debugfs_create_dir("keys", phyd);
 
        DEBUGFS_ADD(frequency);
-       DEBUGFS_ADD(antenna_sel_tx);
-       DEBUGFS_ADD(antenna_sel_rx);
        DEBUGFS_ADD(rts_threshold);
        DEBUGFS_ADD(fragmentation_threshold);
        DEBUGFS_ADD(short_retry_limit);
@@ -258,8 +252,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
 void debugfs_hw_del(struct ieee80211_local *local)
 {
        DEBUGFS_DEL(frequency);
-       DEBUGFS_DEL(antenna_sel_tx);
-       DEBUGFS_DEL(antenna_sel_rx);
        DEBUGFS_DEL(rts_threshold);
        DEBUGFS_DEL(fragmentation_threshold);
        DEBUGFS_DEL(short_retry_limit);
index a3294d109322d61583afe0a967260e2cc1236d62..6424ac565ae0e1760697e626c2a875c295f472a4 100644 (file)
@@ -188,7 +188,6 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key)
   {
        static int keycount;
        char buf[50];
-       DECLARE_MAC_BUF(mac);
        struct sta_info *sta;
 
        if (!key->local->debugfs.keys)
@@ -206,8 +205,7 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key)
        rcu_read_lock();
        sta = rcu_dereference(key->sta);
        if (sta)
-               sprintf(buf, "../../stations/%s",
-                       print_mac(mac, sta->sta.addr));
+               sprintf(buf, "../../stations/%pM", sta->sta.addr);
        rcu_read_unlock();
 
        /* using sta as a boolean is fine outside RCU lock */
index 2ad504fc3414e19eb1b43cef909af2a68214de4b..c54219301724e1198c824294550edf77d7cc6bdb 100644 (file)
@@ -41,29 +41,6 @@ static ssize_t ieee80211_if_read(
        return ret;
 }
 
-#ifdef CONFIG_MAC80211_MESH
-static ssize_t ieee80211_if_write(
-       struct ieee80211_sub_if_data *sdata,
-       char const __user *userbuf,
-       size_t count, loff_t *ppos,
-       int (*format)(struct ieee80211_sub_if_data *, char *))
-{
-       char buf[10];
-       int buf_size;
-
-       memset(buf, 0x00, sizeof(buf));
-       buf_size = min(count, (sizeof(buf)-1));
-       if (copy_from_user(buf, userbuf, buf_size))
-               return count;
-       read_lock(&dev_base_lock);
-       if (sdata->dev->reg_state == NETREG_REGISTERED)
-               (*format)(sdata, buf);
-       read_unlock(&dev_base_lock);
-
-       return count;
-}
-#endif
-
 #define IEEE80211_IF_FMT(name, field, format_string)                   \
 static ssize_t ieee80211_if_fmt_##name(                                        \
        const struct ieee80211_sub_if_data *sdata, char *buf,           \
@@ -71,19 +48,6 @@ static ssize_t ieee80211_if_fmt_##name(                                      \
 {                                                                      \
        return scnprintf(buf, buflen, format_string, sdata->field);     \
 }
-#define IEEE80211_IF_WFMT(name, field, type)                           \
-static int ieee80211_if_wfmt_##name(                                   \
-       struct ieee80211_sub_if_data *sdata, char *buf)                 \
-{                                                                      \
-       unsigned long tmp;                                              \
-       char *endp;                                                     \
-                                                                       \
-       tmp = simple_strtoul(buf, &endp, 0);                            \
-       if ((endp == buf) || ((type)tmp != tmp))                        \
-               return -EINVAL;                                         \
-       sdata->field = tmp;                                             \
-       return 0;                                                       \
-}
 #define IEEE80211_IF_FMT_DEC(name, field)                              \
                IEEE80211_IF_FMT(name, field, "%d\n")
 #define IEEE80211_IF_FMT_HEX(name, field)                              \
@@ -104,8 +68,7 @@ static ssize_t ieee80211_if_fmt_##name(                                      \
        const struct ieee80211_sub_if_data *sdata, char *buf,           \
        int buflen)                                                     \
 {                                                                      \
-       DECLARE_MAC_BUF(mac);                                           \
-       return scnprintf(buf, buflen, "%s\n", print_mac(mac, sdata->field));\
+       return scnprintf(buf, buflen, "%pM\n", sdata->field);           \
 }
 
 #define __IEEE80211_IF_FILE(name)                                      \
@@ -126,34 +89,6 @@ static const struct file_operations name##_ops = {                  \
                IEEE80211_IF_FMT_##format(name, field)                  \
                __IEEE80211_IF_FILE(name)
 
-#define __IEEE80211_IF_WFILE(name)                                     \
-static ssize_t ieee80211_if_read_##name(struct file *file,             \
-                                       char __user *userbuf,           \
-                                       size_t count, loff_t *ppos)     \
-{                                                                      \
-       return ieee80211_if_read(file->private_data,                    \
-                                userbuf, count, ppos,                  \
-                                ieee80211_if_fmt_##name);              \
-}                                                                      \
-static ssize_t ieee80211_if_write_##name(struct file *file,            \
-                                       const char __user *userbuf,     \
-                                       size_t count, loff_t *ppos)     \
-{                                                                      \
-       return ieee80211_if_write(file->private_data,                   \
-                                userbuf, count, ppos,                  \
-                                ieee80211_if_wfmt_##name);             \
-}                                                                      \
-static const struct file_operations name##_ops = {                     \
-       .read = ieee80211_if_read_##name,                               \
-       .write = ieee80211_if_write_##name,                             \
-       .open = mac80211_open_file_generic,                             \
-}
-
-#define IEEE80211_IF_WFILE(name, field, format, type)                  \
-               IEEE80211_IF_FMT_##format(name, field)                  \
-               IEEE80211_IF_WFMT(name, field, type)                    \
-               __IEEE80211_IF_WFILE(name)
-
 /* common attributes */
 IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC);
 IEEE80211_IF_FILE(force_unicast_rateidx, force_unicast_rateidx, DEC);
@@ -184,7 +119,7 @@ static ssize_t ieee80211_if_fmt_flags(
                 sdata->u.sta.flags & IEEE80211_STA_AUTHENTICATED ? "AUTH\n" : "",
                 sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED ? "ASSOC\n" : "",
                 sdata->u.sta.flags & IEEE80211_STA_PROBEREQ_POLL ? "PROBEREQ POLL\n" : "",
-                sdata->bss_conf.use_cts_prot ? "CTS prot\n" : "");
+                sdata->vif.bss_conf.use_cts_prot ? "CTS prot\n" : "");
 }
 __IEEE80211_IF_FILE(flags);
 
@@ -212,30 +147,30 @@ IEEE80211_IF_FILE(dropped_frames_no_route,
 IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC);
 
 /* Mesh parameters */
-IEEE80211_IF_WFILE(dot11MeshMaxRetries,
-               u.mesh.mshcfg.dot11MeshMaxRetries, DEC, u8);
-IEEE80211_IF_WFILE(dot11MeshRetryTimeout,
-               u.mesh.mshcfg.dot11MeshRetryTimeout, DEC, u16);
-IEEE80211_IF_WFILE(dot11MeshConfirmTimeout,
-               u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC, u16);
-IEEE80211_IF_WFILE(dot11MeshHoldingTimeout,
-               u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC, u16);
-IEEE80211_IF_WFILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC, u8);
-IEEE80211_IF_WFILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC, u8);
-IEEE80211_IF_WFILE(dot11MeshMaxPeerLinks,
-               u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC, u16);
-IEEE80211_IF_WFILE(dot11MeshHWMPactivePathTimeout,
-               u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC, u32);
-IEEE80211_IF_WFILE(dot11MeshHWMPpreqMinInterval,
-               u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC, u16);
-IEEE80211_IF_WFILE(dot11MeshHWMPnetDiameterTraversalTime,
-               u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC, u16);
-IEEE80211_IF_WFILE(dot11MeshHWMPmaxPREQretries,
-               u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC, u8);
-IEEE80211_IF_WFILE(path_refresh_time,
-               u.mesh.mshcfg.path_refresh_time, DEC, u32);
-IEEE80211_IF_WFILE(min_discovery_timeout,
-               u.mesh.mshcfg.min_discovery_timeout, DEC, u16);
+IEEE80211_IF_FILE(dot11MeshMaxRetries,
+               u.mesh.mshcfg.dot11MeshMaxRetries, DEC);
+IEEE80211_IF_FILE(dot11MeshRetryTimeout,
+               u.mesh.mshcfg.dot11MeshRetryTimeout, DEC);
+IEEE80211_IF_FILE(dot11MeshConfirmTimeout,
+               u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC);
+IEEE80211_IF_FILE(dot11MeshHoldingTimeout,
+               u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC);
+IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC);
+IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC);
+IEEE80211_IF_FILE(dot11MeshMaxPeerLinks,
+               u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC);
+IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout,
+               u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC);
+IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval,
+               u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC);
+IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime,
+               u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC);
+IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries,
+               u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC);
+IEEE80211_IF_FILE(path_refresh_time,
+               u.mesh.mshcfg.path_refresh_time, DEC);
+IEEE80211_IF_FILE(min_discovery_timeout,
+               u.mesh.mshcfg.min_discovery_timeout, DEC);
 #endif
 
 
index b85c4f27b3618e4f783f47c328b1b0c5f3e43702..a2fbe0131312dcf23dda4b2ce8600af246f462f7 100644 (file)
@@ -39,13 +39,6 @@ static const struct file_operations sta_ ##name## _ops = {           \
        .open = mac80211_open_file_generic,                             \
 }
 
-#define STA_OPS_WR(name)                                               \
-static const struct file_operations sta_ ##name## _ops = {             \
-       .read = sta_##name##_read,                                      \
-       .write = sta_##name##_write,                                    \
-       .open = mac80211_open_file_generic,                             \
-}
-
 #define STA_FILE(name, field, format)                                  \
                STA_READ_##format(name, field)                          \
                STA_OPS(name)
@@ -144,7 +137,7 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
        p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:");
        for (i = 0; i < STA_TID_NUM; i++)
                p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
-                       sta->ampdu_mlme.tid_state_rx[i]?
+                       sta->ampdu_mlme.tid_state_rx[i] ?
                        sta->ampdu_mlme.tid_rx[i]->dialog_token : 0);
 
        p += scnprintf(p, sizeof(buf)+buf-p, "\n TX  :");
@@ -155,84 +148,20 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
        p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:");
        for (i = 0; i < STA_TID_NUM; i++)
                p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
-                       sta->ampdu_mlme.tid_state_tx[i]?
+                       sta->ampdu_mlme.tid_state_tx[i] ?
                        sta->ampdu_mlme.tid_tx[i]->dialog_token : 0);
 
        p += scnprintf(p, sizeof(buf)+buf-p, "\n SSN :");
        for (i = 0; i < STA_TID_NUM; i++)
                p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
-                       sta->ampdu_mlme.tid_state_tx[i]?
+                       sta->ampdu_mlme.tid_state_tx[i] ?
                        sta->ampdu_mlme.tid_tx[i]->ssn : 0);
 
        p += scnprintf(p, sizeof(buf)+buf-p, "\n");
 
        return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
 }
-
-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 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,
-                                       0, 0, 0, 0, 0, 0, 0, 0};
-       static int tid_static_rx[16] = {1, 1, 1, 1, 1, 1, 1, 1,
-                                       1, 1, 1, 1, 1, 1, 1, 1};
-       char *endp;
-       char buf[32];
-       int buf_size, rs;
-       unsigned int tid_num;
-       char state[4];
-
-       memset(buf, 0x00, sizeof(buf));
-       buf_size = min(count, (sizeof(buf)-1));
-       if (copy_from_user(buf, user_buf, buf_size))
-               return -EFAULT;
-
-       tid_num = simple_strtoul(buf, &endp, 0);
-       if (endp == buf)
-               return -EINVAL;
-
-       if ((tid_num >= 100) && (tid_num <= 115)) {
-               /* toggle Rx aggregation command */
-               tid_num = tid_num - 100;
-               if (tid_static_rx[tid_num] == 1) {
-                       strcpy(state, "off");
-                       ieee80211_sta_stop_rx_ba_session(sta->sdata, da, tid_num, 0,
-                                       WLAN_REASON_QSTA_REQUIRE_SETUP);
-                       sta->ampdu_mlme.tid_state_rx[tid_num] |=
-                                       HT_AGG_STATE_DEBUGFS_CTL;
-                       tid_static_rx[tid_num] = 0;
-               } else {
-                       strcpy(state, "on ");
-                       sta->ampdu_mlme.tid_state_rx[tid_num] &=
-                                       ~HT_AGG_STATE_DEBUGFS_CTL;
-                       tid_static_rx[tid_num] = 1;
-               }
-               printk(KERN_DEBUG "debugfs - try switching tid %u %s\n",
-                               tid_num, state);
-       } else if ((tid_num >= 0) && (tid_num <= 15)) {
-               /* toggle Tx aggregation command */
-               if (tid_static_tx[tid_num] == 0) {
-                       strcpy(state, "on ");
-                       rs =  ieee80211_start_tx_ba_session(hw, da, tid_num);
-                       if (rs == 0)
-                               tid_static_tx[tid_num] = 1;
-               } else {
-                       strcpy(state, "off");
-                       rs =  ieee80211_stop_tx_ba_session(hw, da, tid_num, 1);
-                       if (rs == 0)
-                               tid_static_tx[tid_num] = 0;
-               }
-               printk(KERN_DEBUG "debugfs - switching tid %u %s, return=%d\n",
-                               tid_num, state, rs);
-       }
-
-       return count;
-}
-STA_OPS_WR(agg_status);
+STA_OPS(agg_status);
 
 #define DEBUGFS_ADD(name) \
        sta->debugfs.name = debugfs_create_file(#name, 0400, \
@@ -246,15 +175,14 @@ STA_OPS_WR(agg_status);
 void ieee80211_sta_debugfs_add(struct sta_info *sta)
 {
        struct dentry *stations_dir = sta->local->debugfs.stations;
-       DECLARE_MAC_BUF(mbuf);
-       u8 *mac;
+       u8 mac[3*ETH_ALEN];
 
        sta->debugfs.add_has_run = true;
 
        if (!stations_dir)
                return;
 
-       mac = print_mac(mbuf, sta->sta.addr);
+       snprintf(mac, sizeof(mac), "%pM", sta->sta.addr);
 
        /*
         * This might fail due to a race condition:
index 8de60de70bc9bffa32a4fea6dc3b7641f139c563..0d95561c0ee017d72cf3b19986a79fc25ad9a1ae 100644 (file)
@@ -21,14 +21,13 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke
 {
        union iwreq_data wrqu;
        char *buf = kmalloc(128, GFP_ATOMIC);
-       DECLARE_MAC_BUF(mac);
 
        if (buf) {
                /* TODO: needed parameters: count, key type, TSC */
                sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
-                       "keyid=%d %scast addr=%s)",
+                       "keyid=%d %scast addr=%pM)",
                        keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
-                       print_mac(mac, hdr->addr2));
+                       hdr->addr2);
                memset(&wrqu, 0, sizeof(wrqu));
                wrqu.data.length = strlen(buf);
                wireless_send_event(sdata->dev, IWEVCUSTOM, &wrqu, buf);
index dc7d9a3d70d5ccc450faa96a4728a3cee7500cd0..3e231d7567768355f55f89c4cf82e48f1d92bcab 100644 (file)
 #include "sta_info.h"
 #include "wme.h"
 
-int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
-                                  struct ieee80211_ht_info *ht_info)
+void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
+                                      struct ieee80211_ht_cap *ht_cap_ie,
+                                      struct ieee80211_sta_ht_cap *ht_cap)
 {
+       u8 ampdu_info, tx_mcs_set_cap;
+       int i, max_tx_streams;
 
-       if (ht_info == NULL)
-               return -EINVAL;
+       BUG_ON(!ht_cap);
+
+       memset(ht_cap, 0, sizeof(*ht_cap));
+
+       if (!ht_cap_ie)
+               return;
 
-       memset(ht_info, 0, sizeof(*ht_info));
+       ht_cap->ht_supported = true;
 
-       if (ht_cap_ie) {
-               u8 ampdu_info = ht_cap_ie->ampdu_params_info;
+       ht_cap->cap = ht_cap->cap & sband->ht_cap.cap;
+       ht_cap->cap &= ~IEEE80211_HT_CAP_SM_PS;
+       ht_cap->cap |= sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS;
 
-               ht_info->ht_supported = 1;
-               ht_info->cap = le16_to_cpu(ht_cap_ie->cap_info);
-               ht_info->ampdu_factor =
-                       ampdu_info & IEEE80211_HT_CAP_AMPDU_FACTOR;
-               ht_info->ampdu_density =
-                       (ampdu_info & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2;
-               memcpy(ht_info->supp_mcs_set, ht_cap_ie->supp_mcs_set, 16);
-       } else
-               ht_info->ht_supported = 0;
+       ampdu_info = ht_cap_ie->ampdu_params_info;
+       ht_cap->ampdu_factor =
+               ampdu_info & IEEE80211_HT_AMPDU_PARM_FACTOR;
+       ht_cap->ampdu_density =
+               (ampdu_info & IEEE80211_HT_AMPDU_PARM_DENSITY) >> 2;
 
-       return 0;
+       /* own MCS TX capabilities */
+       tx_mcs_set_cap = sband->ht_cap.mcs.tx_params;
+
+       /* can we TX with MCS rates? */
+       if (!(tx_mcs_set_cap & IEEE80211_HT_MCS_TX_DEFINED))
+               return;
+
+       /* Counting from 0, therefore +1 */
+       if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_RX_DIFF)
+               max_tx_streams =
+                       ((tx_mcs_set_cap & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
+                               >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1;
+       else
+               max_tx_streams = IEEE80211_HT_MCS_TX_MAX_STREAMS;
+
+       /*
+        * 802.11n D5.0 20.3.5 / 20.6 says:
+        * - indices 0 to 7 and 32 are single spatial stream
+        * - 8 to 31 are multiple spatial streams using equal modulation
+        *   [8..15 for two streams, 16..23 for three and 24..31 for four]
+        * - remainder are multiple spatial streams using unequal modulation
+        */
+       for (i = 0; i < max_tx_streams; i++)
+               ht_cap->mcs.rx_mask[i] =
+                       sband->ht_cap.mcs.rx_mask[i] & ht_cap_ie->mcs.rx_mask[i];
+
+       if (tx_mcs_set_cap & IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION)
+               for (i = IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE;
+                    i < IEEE80211_HT_MCS_MASK_LEN; i++)
+                       ht_cap->mcs.rx_mask[i] =
+                               sband->ht_cap.mcs.rx_mask[i] &
+                                       ht_cap_ie->mcs.rx_mask[i];
+
+       /* handle MCS rate 32 too */
+       if (sband->ht_cap.mcs.rx_mask[32/8] & ht_cap_ie->mcs.rx_mask[32/8] & 1)
+               ht_cap->mcs.rx_mask[32/8] |= 1;
 }
 
-int ieee80211_ht_addt_info_ie_to_ht_bss_info(
-                       struct ieee80211_ht_addt_info *ht_add_info_ie,
-                       struct ieee80211_ht_bss_info *bss_info)
+/*
+ * ieee80211_enable_ht should be called only after the operating band
+ * has been determined as ht configuration depends on the hw's
+ * HT abilities for a specific band.
+ */
+u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
+                       struct ieee80211_ht_info *hti,
+                       u16 ap_ht_cap_flags)
 {
-       if (bss_info == NULL)
-               return -EINVAL;
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_bss_ht_conf ht;
+       u32 changed = 0;
+       bool enable_ht = true, ht_changed;
+
+       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
 
-       memset(bss_info, 0, sizeof(*bss_info));
+       memset(&ht, 0, sizeof(ht));
 
-       if (ht_add_info_ie) {
-               u16 op_mode;
-               op_mode = le16_to_cpu(ht_add_info_ie->operation_mode);
+       /* HT is not supported */
+       if (!sband->ht_cap.ht_supported)
+               enable_ht = false;
 
-               bss_info->primary_channel = ht_add_info_ie->control_chan;
-               bss_info->bss_cap = ht_add_info_ie->ht_param;
-               bss_info->bss_op_mode = (u8)(op_mode & 0xff);
+       /* check that channel matches the right operating channel */
+       if (local->hw.conf.channel->center_freq !=
+           ieee80211_channel_to_frequency(hti->control_chan))
+               enable_ht = false;
+
+       /*
+        * XXX: This is totally incorrect when there are multiple virtual
+        *      interfaces, needs to be fixed later.
+        */
+       ht_changed = local->hw.conf.ht.enabled != enable_ht;
+       local->hw.conf.ht.enabled = enable_ht;
+       if (ht_changed)
+               ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT);
+
+       /* disable HT */
+       if (!enable_ht)
+               return 0;
+       ht.secondary_channel_offset =
+               hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
+       ht.width_40_ok =
+               !(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
+               (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
+               (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY);
+       ht.operation_mode = le16_to_cpu(hti->operation_mode);
+
+       /* if bss configuration changed store the new one */
+       if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) {
+               changed |= BSS_CHANGED_HT;
+               sdata->vif.bss_conf.ht = ht;
        }
 
-       return 0;
+       return changed;
 }
 
 static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
@@ -241,7 +316,6 @@ void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *r
        struct ieee80211_hw *hw = &local->hw;
        struct sta_info *sta;
        int ret, i;
-       DECLARE_MAC_BUF(mac);
 
        rcu_read_lock();
 
@@ -269,8 +343,8 @@ void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *r
        BUG_ON(!local->ops->ampdu_action);
 
 #ifdef CONFIG_MAC80211_HT_DEBUG
-       printk(KERN_DEBUG "Rx BA session stop requested for %s tid %u\n",
-                               print_mac(mac, ra), tid);
+       printk(KERN_DEBUG "Rx BA session stop requested for %pM tid %u\n",
+              ra, tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
 
        ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
@@ -383,14 +457,13 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
        u16 start_seq_num;
        u8 *state;
        int ret;
-       DECLARE_MAC_BUF(mac);
 
-       if (tid >= STA_TID_NUM)
+       if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
                return -EINVAL;
 
 #ifdef CONFIG_MAC80211_HT_DEBUG
-       printk(KERN_DEBUG "Open BA session requested for %s tid %u\n",
-                               print_mac(mac, ra), tid);
+       printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n",
+              ra, tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
 
        rcu_read_lock();
@@ -442,17 +515,19 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
                        (unsigned long)&sta->timer_to_tid[tid];
        init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
 
-       /* create a new queue for this aggregation */
-       ret = ieee80211_ht_agg_queue_add(local, sta, tid);
+       if (hw->ampdu_queues) {
+               /* create a new queue for this aggregation */
+               ret = ieee80211_ht_agg_queue_add(local, sta, tid);
 
-       /* case no queue is available to aggregation
-        * don't switch to aggregation */
-       if (ret) {
+               /* case no queue is available to aggregation
+                * don't switch to aggregation */
+               if (ret) {
 #ifdef CONFIG_MAC80211_HT_DEBUG
-               printk(KERN_DEBUG "BA request denied - queue unavailable for"
-                                       " tid %d\n", tid);
+                       printk(KERN_DEBUG "BA request denied - "
+                              "queue unavailable for tid %d\n", tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
-               goto err_unlock_queue;
+                       goto err_unlock_queue;
+               }
        }
        sdata = sta->sdata;
 
@@ -471,7 +546,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
                /* No need to requeue the packets in the agg queue, since we
                 * held the tx lock: no packet could be enqueued to the newly
                 * allocated queue */
-               ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
+               if (hw->ampdu_queues)
+                       ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
 #ifdef CONFIG_MAC80211_HT_DEBUG
                printk(KERN_DEBUG "BA request denied - HW unavailable for"
                                        " tid %d\n", tid);
@@ -481,7 +557,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
        }
 
        /* Will put all the packets in the new SW queue */
-       ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
+       if (hw->ampdu_queues)
+               ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
        spin_unlock_bh(&sta->lock);
 
        /* send an addBA request */
@@ -524,7 +601,6 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
        struct sta_info *sta;
        u8 *state;
        int ret = 0;
-       DECLARE_MAC_BUF(mac);
 
        if (tid >= STA_TID_NUM)
                return -EINVAL;
@@ -546,11 +622,12 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
        }
 
 #ifdef CONFIG_MAC80211_HT_DEBUG
-       printk(KERN_DEBUG "Tx BA session stop requested for %s tid %u\n",
-                               print_mac(mac, ra), tid);
+       printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
+              ra, tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
 
-       ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]);
+       if (hw->ampdu_queues)
+               ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]);
 
        *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
                (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
@@ -563,7 +640,8 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
        if (ret) {
                WARN_ON(ret != -EBUSY);
                *state = HT_AGG_STATE_OPERATIONAL;
-               ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
+               if (hw->ampdu_queues)
+                       ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
                goto stop_BA_exit;
        }
 
@@ -579,7 +657,6 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
        struct ieee80211_local *local = hw_to_local(hw);
        struct sta_info *sta;
        u8 *state;
-       DECLARE_MAC_BUF(mac);
 
        if (tid >= STA_TID_NUM) {
 #ifdef CONFIG_MAC80211_HT_DEBUG
@@ -594,8 +671,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
        if (!sta) {
                rcu_read_unlock();
 #ifdef CONFIG_MAC80211_HT_DEBUG
-               printk(KERN_DEBUG "Could not find station: %s\n",
-                               print_mac(mac, ra));
+               printk(KERN_DEBUG "Could not find station: %pM\n", ra);
 #endif
                return;
        }
@@ -621,7 +697,8 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
 #ifdef CONFIG_MAC80211_HT_DEBUG
                printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
 #endif
-               ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
+               if (hw->ampdu_queues)
+                       ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
        }
        spin_unlock_bh(&sta->lock);
        rcu_read_unlock();
@@ -634,7 +711,6 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
        struct sta_info *sta;
        u8 *state;
        int agg_queue;
-       DECLARE_MAC_BUF(mac);
 
        if (tid >= STA_TID_NUM) {
 #ifdef CONFIG_MAC80211_HT_DEBUG
@@ -645,16 +721,15 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
        }
 
 #ifdef CONFIG_MAC80211_HT_DEBUG
-       printk(KERN_DEBUG "Stopping Tx BA session for %s tid %d\n",
-                               print_mac(mac, ra), tid);
+       printk(KERN_DEBUG "Stopping Tx BA session for %pM tid %d\n",
+              ra, tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
 
        rcu_read_lock();
        sta = sta_info_get(local, ra);
        if (!sta) {
 #ifdef CONFIG_MAC80211_HT_DEBUG
-               printk(KERN_DEBUG "Could not find station: %s\n",
-                               print_mac(mac, ra));
+               printk(KERN_DEBUG "Could not find station: %pM\n", ra);
 #endif
                rcu_read_unlock();
                return;
@@ -677,16 +752,18 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
                ieee80211_send_delba(sta->sdata, ra, tid,
                        WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
 
-       agg_queue = sta->tid_to_tx_q[tid];
-
-       ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
-
-       /* We just requeued the all the frames that were in the
-        * removed queue, and since we might miss a softirq we do
-        * netif_schedule_queue.  ieee80211_wake_queue is not used
-        * here as this queue is not necessarily stopped
-        */
-       netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue));
+       if (hw->ampdu_queues) {
+               agg_queue = sta->tid_to_tx_q[tid];
+               ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
+
+               /* We just requeued the all the frames that were in the
+                * removed queue, and since we might miss a softirq we do
+                * netif_schedule_queue.  ieee80211_wake_queue is not used
+                * here as this queue is not necessarily stopped
+                */
+               netif_schedule_queue(netdev_get_tx_queue(local->mdev,
+                                                        agg_queue));
+       }
        spin_lock_bh(&sta->lock);
        *state = HT_AGG_STATE_IDLE;
        sta->ampdu_mlme.addba_req_num[tid] = 0;
@@ -783,7 +860,6 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
        u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
        u8 dialog_token;
        int ret = -EOPNOTSUPP;
-       DECLARE_MAC_BUF(mac);
 
        /* extract session parameters from addba request frame */
        dialog_token = mgmt->u.action.u.addba_req.dialog_token;
@@ -801,15 +877,16 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
        /* sanity check for incoming parameters:
         * check if configuration can support the BA policy
         * and if buffer size does not exceeds max value */
+       /* XXX: check own ht delayed BA capability?? */
        if (((ba_policy != 1)
-               && (!(conf->ht_conf.cap & IEEE80211_HT_CAP_DELAY_BA)))
+               && (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA)))
                || (buf_size > IEEE80211_MAX_AMPDU_BUF)) {
                status = WLAN_STATUS_INVALID_QOS_PARAM;
 #ifdef CONFIG_MAC80211_HT_DEBUG
                if (net_ratelimit())
                        printk(KERN_DEBUG "AddBA Req with bad params from "
-                               "%s on tid %u. policy %d, buffer size %d\n",
-                               print_mac(mac, mgmt->sa), tid, ba_policy,
+                               "%pM on tid %u. policy %d, buffer size %d\n",
+                               mgmt->sa, tid, ba_policy,
                                buf_size);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
                goto end_no_lock;
@@ -820,7 +897,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
 
                sband = local->hw.wiphy->bands[conf->channel->band];
                buf_size = IEEE80211_MIN_AMPDU_BUF;
-               buf_size = buf_size << sband->ht_info.ampdu_factor;
+               buf_size = buf_size << sband->ht_cap.ampdu_factor;
        }
 
 
@@ -831,8 +908,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
 #ifdef CONFIG_MAC80211_HT_DEBUG
                if (net_ratelimit())
                        printk(KERN_DEBUG "unexpected AddBA Req from "
-                               "%s on tid %u\n",
-                               print_mac(mac, mgmt->sa), tid);
+                               "%pM on tid %u\n",
+                               mgmt->sa, tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
                goto end;
        }
@@ -910,7 +987,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
 {
        struct ieee80211_hw *hw = &local->hw;
        u16 capab;
-       u16 tid;
+       u16 tid, start_seq_num;
        u8 *state;
 
        capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
@@ -943,9 +1020,18 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
                *state |= HT_ADDBA_RECEIVED_MSK;
                sta->ampdu_mlme.addba_req_num[tid] = 0;
 
-               if (*state == HT_AGG_STATE_OPERATIONAL)
+               if (*state == HT_AGG_STATE_OPERATIONAL &&
+                   local->hw.ampdu_queues)
                        ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
 
+               if (local->ops->ampdu_action) {
+                       (void)local->ops->ampdu_action(hw,
+                                              IEEE80211_AMPDU_TX_RESUME,
+                                              &sta->sta, tid, &start_seq_num);
+               }
+#ifdef CONFIG_MAC80211_HT_DEBUG
+               printk(KERN_DEBUG "Resuming TX aggregation for tid %d\n", tid);
+#endif /* CONFIG_MAC80211_HT_DEBUG */
                spin_unlock_bh(&sta->lock);
        } else {
                sta->ampdu_mlme.addba_req_num[tid]++;
@@ -964,7 +1050,6 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        u16 tid, params;
        u16 initiator;
-       DECLARE_MAC_BUF(mac);
 
        params = le16_to_cpu(mgmt->u.action.u.delba.params);
        tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
@@ -972,9 +1057,8 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
 
 #ifdef CONFIG_MAC80211_HT_DEBUG
        if (net_ratelimit())
-               printk(KERN_DEBUG "delba from %s (%s) tid %d reason code %d\n",
-                       print_mac(mac, mgmt->sa),
-                       initiator ? "initiator" : "recipient", tid,
+               printk(KERN_DEBUG "delba from %pM (%s) tid %d reason code %d\n",
+                       mgmt->sa, initiator ? "initiator" : "recipient", tid,
                        mgmt->u.action.u.delba.reason_code);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
 
index 156e42a003ae77ac38e77aa1e047d58575e87eec..155a20410017661e60436712019f0b114a5abf83 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/etherdevice.h>
+#include <net/cfg80211.h>
 #include <net/wireless.h>
 #include <net/iw_handler.h>
 #include <net/mac80211.h>
@@ -142,7 +143,6 @@ typedef unsigned __bitwise__ ieee80211_tx_result;
 #define IEEE80211_TX_FRAGMENTED                BIT(0)
 #define IEEE80211_TX_UNICAST           BIT(1)
 #define IEEE80211_TX_PS_BUFFERED       BIT(2)
-#define IEEE80211_TX_PROBE_LAST_FRAG   BIT(3)
 
 struct ieee80211_tx_data {
        struct sk_buff *skb;
@@ -153,11 +153,6 @@ struct ieee80211_tx_data {
        struct ieee80211_key *key;
 
        struct ieee80211_channel *channel;
-       s8 rate_idx;
-       /* use this rate (if set) for last fragment; rate can
-        * be set to lower rate for the first fragments, e.g.,
-        * when using CTS protection with IEEE 802.11g. */
-       s8 last_frag_rate_idx;
 
        /* Extra fragments (in addition to the first fragment
         * in skb) */
@@ -203,9 +198,7 @@ struct ieee80211_rx_data {
 struct ieee80211_tx_stored_packet {
        struct sk_buff *skb;
        struct sk_buff **extra_frag;
-       s8 last_frag_rate_idx;
        int num_extra_frag;
-       bool last_frag_rate_ctrl_probe;
 };
 
 struct beacon_data {
@@ -219,9 +212,6 @@ struct ieee80211_if_ap {
 
        struct list_head vlans;
 
-       u8 ssid[IEEE80211_MAX_SSID_LEN];
-       size_t ssid_len;
-
        /* yes, this looks ugly, but guarantees that we can later use
         * bitmap_empty :)
         * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */
@@ -255,26 +245,6 @@ struct mesh_preq_queue {
        u8 flags;
 };
 
-struct mesh_config {
-       /* Timeouts in ms */
-       /* Mesh plink management parameters */
-       u16 dot11MeshRetryTimeout;
-       u16 dot11MeshConfirmTimeout;
-       u16 dot11MeshHoldingTimeout;
-       u16 dot11MeshMaxPeerLinks;
-       u8  dot11MeshMaxRetries;
-       u8  dot11MeshTTL;
-       bool auto_open_plinks;
-       /* HWMP parameters */
-       u8  dot11MeshHWMPmaxPREQretries;
-       u32 path_refresh_time;
-       u16 min_discovery_timeout;
-       u32 dot11MeshHWMPactivePathTimeout;
-       u16 dot11MeshHWMPpreqMinInterval;
-       u16 dot11MeshHWMPnetDiameterTraversalTime;
-};
-
-
 /* flags used in struct ieee80211_if_sta.flags */
 #define IEEE80211_STA_SSID_SET         BIT(0)
 #define IEEE80211_STA_BSSID_SET                BIT(1)
@@ -438,8 +408,7 @@ struct ieee80211_sub_if_data {
        struct ieee80211_key *keys[NUM_DEFAULT_KEYS];
        struct ieee80211_key *default_key;
 
-       /* BSS configuration for this interface. */
-       struct ieee80211_bss_conf bss_conf;
+       u16 sequence_number;
 
        /*
         * AP this belongs to: self in AP mode and
@@ -633,8 +602,6 @@ struct ieee80211_local {
 
        int rts_threshold;
        int fragmentation_threshold;
-       int short_retry_limit; /* dot11ShortRetryLimit */
-       int long_retry_limit; /* dot11LongRetryLimit */
 
        struct crypto_blkcipher *wep_tx_tfm;
        struct crypto_blkcipher *wep_rx_tfm;
@@ -727,8 +694,6 @@ struct ieee80211_local {
                struct dentry *rcdir;
                struct dentry *rcname;
                struct dentry *frequency;
-               struct dentry *antenna_sel_tx;
-               struct dentry *antenna_sel_rx;
                struct dentry *rts_threshold;
                struct dentry *fragmentation_threshold;
                struct dentry *short_retry_limit;
@@ -817,7 +782,7 @@ struct ieee802_11_elems {
        u8 *wmm_info;
        u8 *wmm_param;
        struct ieee80211_ht_cap *ht_cap_elem;
-       struct ieee80211_ht_addt_info *ht_info_elem;
+       struct ieee80211_ht_info *ht_info_elem;
        u8 *mesh_config;
        u8 *mesh_id;
        u8 *peer_link;
@@ -869,11 +834,6 @@ static inline struct ieee80211_hw *local_to_hw(
        return &local->hw;
 }
 
-struct sta_attribute {
-       struct attribute attr;
-       ssize_t (*show)(const struct sta_info *, char *buf);
-       ssize_t (*store)(struct sta_info *, const char *buf, size_t count);
-};
 
 static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
 {
@@ -882,12 +842,9 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
 }
 
 
-int ieee80211_hw_config(struct ieee80211_local *local);
+int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
 int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed);
 void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
-u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht,
-                       struct ieee80211_ht_info *req_ht_cap,
-                       struct ieee80211_ht_bss_info *req_bss_cap);
 void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
                                      u32 changed);
 void ieee80211_configure_filter(struct ieee80211_local *local);
@@ -968,11 +925,12 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
 int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
 
 /* HT */
-int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
-                                  struct ieee80211_ht_info *ht_info);
-int ieee80211_ht_addt_info_ie_to_ht_bss_info(
-                       struct ieee80211_ht_addt_info *ht_add_info_ie,
-                       struct ieee80211_ht_bss_info *bss_info);
+void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
+                                      struct ieee80211_ht_cap *ht_cap_ie,
+                                      struct ieee80211_sta_ht_cap *ht_cap);
+u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
+                       struct ieee80211_ht_info *hti,
+                       u16 ap_ht_cap_flags);
 void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn);
 
 void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da,
index 8336fee68d3e05b717047e4d8a1ac5f3623542a8..cde145221b61ba1900d6acd7697660504bd376ab 100644 (file)
@@ -65,7 +65,7 @@ static int ieee80211_open(struct net_device *dev)
        struct ieee80211_if_init_conf conf;
        u32 changed = 0;
        int res;
-       bool need_hw_reconfig = 0;
+       u32 hw_reconf_flags = 0;
        u8 null_addr[ETH_ALEN] = {0};
 
        /* fail early if user set an invalid address */
@@ -152,7 +152,8 @@ static int ieee80211_open(struct net_device *dev)
                        res = local->ops->start(local_to_hw(local));
                if (res)
                        goto err_del_bss;
-               need_hw_reconfig = 1;
+               /* we're brought up, everything changes */
+               hw_reconf_flags = ~0;
                ieee80211_led_radio(local, local->hw.conf.radio_enabled);
        }
 
@@ -198,8 +199,10 @@ static int ieee80211_open(struct net_device *dev)
 
                /* must be before the call to ieee80211_configure_filter */
                local->monitors++;
-               if (local->monitors == 1)
+               if (local->monitors == 1) {
                        local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
+                       hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP;
+               }
 
                if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
                        local->fif_fcsfail++;
@@ -279,8 +282,8 @@ static int ieee80211_open(struct net_device *dev)
                atomic_inc(&local->iff_promiscs);
 
        local->open_count++;
-       if (need_hw_reconfig) {
-               ieee80211_hw_config(local);
+       if (hw_reconf_flags) {
+               ieee80211_hw_config(local, hw_reconf_flags);
                /*
                 * set default queue parameters so drivers don't
                 * need to initialise the hardware if the hardware
@@ -322,6 +325,7 @@ static int ieee80211_stop(struct net_device *dev)
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_if_init_conf conf;
        struct sta_info *sta;
+       u32 hw_reconf_flags = 0;
 
        /*
         * Stop TX on this interface first.
@@ -405,8 +409,10 @@ static int ieee80211_stop(struct net_device *dev)
                }
 
                local->monitors--;
-               if (local->monitors == 0)
+               if (local->monitors == 0) {
                        local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
+                       hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP;
+               }
 
                if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
                        local->fif_fcsfail--;
@@ -504,8 +510,15 @@ static int ieee80211_stop(struct net_device *dev)
 
                tasklet_disable(&local->tx_pending_tasklet);
                tasklet_disable(&local->tasklet);
+
+               /* no reconfiguring after stop! */
+               hw_reconf_flags = 0;
        }
 
+       /* do after stop to avoid reconfiguring when we stop anyway */
+       if (hw_reconf_flags)
+               ieee80211_hw_config(local, hw_reconf_flags);
+
        return 0;
 }
 
@@ -682,7 +695,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
        ieee80211_setup_sdata(sdata, type);
 
        /* reset some values that shouldn't be kept across type changes */
-       sdata->bss_conf.basic_rates =
+       sdata->vif.bss_conf.basic_rates =
                ieee80211_mandatory_rates(sdata->local,
                        sdata->local->hw.conf.channel->band);
        sdata->drop_unencrypted = 0;
index a5b06fe7198019c5a178f0ac21118e222bcb04d7..999f7aa423267a33c525ee5693244f0c67070a30 100644 (file)
@@ -132,7 +132,6 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 {
        const u8 *addr;
        int ret;
-       DECLARE_MAC_BUF(mac);
 
        assert_key_lock();
        might_sleep();
@@ -154,16 +153,15 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 
        if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP)
                printk(KERN_ERR "mac80211-%s: failed to set key "
-                      "(%d, %s) to hardware (%d)\n",
+                      "(%d, %pM) to hardware (%d)\n",
                       wiphy_name(key->local->hw.wiphy),
-                      key->conf.keyidx, print_mac(mac, addr), ret);
+                      key->conf.keyidx, addr, ret);
 }
 
 static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
 {
        const u8 *addr;
        int ret;
-       DECLARE_MAC_BUF(mac);
 
        assert_key_lock();
        might_sleep();
@@ -186,9 +184,9 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
 
        if (ret)
                printk(KERN_ERR "mac80211-%s: failed to remove key "
-                      "(%d, %s) from hardware (%d)\n",
+                      "(%d, %pM) from hardware (%d)\n",
                       wiphy_name(key->local->hw.wiphy),
-                      key->conf.keyidx, print_mac(mac, addr), ret);
+                      key->conf.keyidx, addr, ret);
 
        spin_lock(&todo_lock);
        key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
index ae62ad40ad63715bed2372be5344ce3c4e4889bc..d631dc96c3231a0de2f9ed9ad36329edc330e687 100644 (file)
@@ -41,6 +41,8 @@
  */
 struct ieee80211_tx_status_rtap_hdr {
        struct ieee80211_radiotap_header hdr;
+       u8 rate;
+       u8 padding_for_rate;
        __le16 tx_flags;
        u8 data_retries;
 } __attribute__ ((packed));
@@ -169,19 +171,13 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
        conf.changed = changed;
 
        if (sdata->vif.type == NL80211_IFTYPE_STATION ||
-           sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+           sdata->vif.type == NL80211_IFTYPE_ADHOC)
                conf.bssid = sdata->u.sta.bssid;
-               conf.ssid = sdata->u.sta.ssid;
-               conf.ssid_len = sdata->u.sta.ssid_len;
-       } else if (sdata->vif.type == NL80211_IFTYPE_AP) {
+       else if (sdata->vif.type == NL80211_IFTYPE_AP)
                conf.bssid = sdata->dev->dev_addr;
-               conf.ssid = sdata->u.ap.ssid;
-               conf.ssid_len = sdata->u.ap.ssid_len;
-       } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
+       else if (ieee80211_vif_is_mesh(&sdata->vif)) {
                u8 zero[ETH_ALEN] = { 0 };
                conf.bssid = zero;
-               conf.ssid = zero;
-               conf.ssid_len = 0;
        } else {
                WARN_ON(1);
                return -EINVAL;
@@ -190,136 +186,48 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
        if (WARN_ON(!conf.bssid && (changed & IEEE80211_IFCC_BSSID)))
                return -EINVAL;
 
-       if (WARN_ON(!conf.ssid && (changed & IEEE80211_IFCC_SSID)))
-               return -EINVAL;
-
        return local->ops->config_interface(local_to_hw(local),
                                            &sdata->vif, &conf);
 }
 
-int ieee80211_hw_config(struct ieee80211_local *local)
+int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
 {
        struct ieee80211_channel *chan;
        int ret = 0;
+       int power;
+
+       might_sleep();
 
        if (local->sw_scanning)
                chan = local->scan_channel;
        else
                chan = local->oper_channel;
 
-       local->hw.conf.channel = chan;
+       if (chan != local->hw.conf.channel) {
+               local->hw.conf.channel = chan;
+               changed |= IEEE80211_CONF_CHANGE_CHANNEL;
+       }
+
 
        if (!local->hw.conf.power_level)
-               local->hw.conf.power_level = chan->max_power;
+               power = chan->max_power;
        else
-               local->hw.conf.power_level = min(chan->max_power,
-                                              local->hw.conf.power_level);
-
-       local->hw.conf.max_antenna_gain = chan->max_antenna_gain;
-
-#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-       printk(KERN_DEBUG "%s: HW CONFIG: freq=%d\n",
-              wiphy_name(local->hw.wiphy), chan->center_freq);
-#endif
-
-       if (local->open_count)
-               ret = local->ops->config(local_to_hw(local), &local->hw.conf);
-
-       return ret;
-}
-
-/**
- * ieee80211_handle_ht should be used only after legacy configuration
- * has been determined namely band, as ht configuration depends upon
- * the hardware's HT abilities for a _specific_ band.
- */
-u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht,
-                          struct ieee80211_ht_info *req_ht_cap,
-                          struct ieee80211_ht_bss_info *req_bss_cap)
-{
-       struct ieee80211_conf *conf = &local->hw.conf;
-       struct ieee80211_supported_band *sband;
-       struct ieee80211_ht_info ht_conf;
-       struct ieee80211_ht_bss_info ht_bss_conf;
-       u32 changed = 0;
-       int i;
-       u8 max_tx_streams = IEEE80211_HT_CAP_MAX_STREAMS;
-       u8 tx_mcs_set_cap;
-
-       sband = local->hw.wiphy->bands[conf->channel->band];
-
-       memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info));
-       memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info));
-
-       /* HT is not supported */
-       if (!sband->ht_info.ht_supported) {
-               conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE;
-               goto out;
+               power = min(chan->max_power, local->hw.conf.power_level);
+       if (local->hw.conf.power_level != power) {
+               changed |= IEEE80211_CONF_CHANGE_POWER;
+               local->hw.conf.power_level = power;
        }
 
-       /* disable HT */
-       if (!enable_ht) {
-               if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)
-                       changed |= BSS_CHANGED_HT;
-               conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE;
-               conf->ht_conf.ht_supported = 0;
-               goto out;
+       if (changed && local->open_count) {
+               ret = local->ops->config(local_to_hw(local), changed);
+               /*
+                * HW reconfiguration should never fail, the driver has told
+                * us what it can support so it should live up to that promise.
+                */
+               WARN_ON(ret);
        }
 
-
-       if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE))
-               changed |= BSS_CHANGED_HT;
-
-       conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE;
-       ht_conf.ht_supported = 1;
-
-       ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap;
-       ht_conf.cap &= ~(IEEE80211_HT_CAP_SM_PS);
-       ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_SM_PS;
-       ht_bss_conf.primary_channel = req_bss_cap->primary_channel;
-       ht_bss_conf.bss_cap = req_bss_cap->bss_cap;
-       ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode;
-
-       ht_conf.ampdu_factor = req_ht_cap->ampdu_factor;
-       ht_conf.ampdu_density = req_ht_cap->ampdu_density;
-
-       /* Bits 96-100 */
-       tx_mcs_set_cap = sband->ht_info.supp_mcs_set[12];
-
-       /* configure suppoerted Tx MCS according to requested MCS
-        * (based in most cases on Rx capabilities of peer) and self
-        * Tx MCS capabilities (as defined by low level driver HW
-        * Tx capabilities) */
-       if (!(tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_DEFINED))
-               goto check_changed;
-
-       /* Counting from 0 therfore + 1 */
-       if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_RX_DIFF)
-               max_tx_streams = ((tx_mcs_set_cap &
-                               IEEE80211_HT_CAP_MCS_TX_STREAMS) >> 2) + 1;
-
-       for (i = 0; i < max_tx_streams; i++)
-               ht_conf.supp_mcs_set[i] =
-                       sband->ht_info.supp_mcs_set[i] &
-                                       req_ht_cap->supp_mcs_set[i];
-
-       if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_UEQM)
-               for (i = IEEE80211_SUPP_MCS_SET_UEQM;
-                    i < IEEE80211_SUPP_MCS_SET_LEN; i++)
-                       ht_conf.supp_mcs_set[i] =
-                               sband->ht_info.supp_mcs_set[i] &
-                                       req_ht_cap->supp_mcs_set[i];
-
-check_changed:
-       /* if bss configuration changed store the new one */
-       if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) ||
-           memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) {
-               changed |= BSS_CHANGED_HT;
-               memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf));
-               memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf));
-       }
-out:
-       return changed;
+       return ret;
 }
 
 void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
@@ -336,15 +244,18 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
        if (local->ops->bss_info_changed)
                local->ops->bss_info_changed(local_to_hw(local),
                                             &sdata->vif,
-                                            &sdata->bss_conf,
+                                            &sdata->vif.bss_conf,
                                             changed);
 }
 
 u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
 {
-       sdata->bss_conf.use_cts_prot = 0;
-       sdata->bss_conf.use_short_preamble = 0;
-       return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE;
+       sdata->vif.bss_conf.use_cts_prot = false;
+       sdata->vif.bss_conf.use_short_preamble = false;
+       sdata->vif.bss_conf.use_short_slot = false;
+       return BSS_CHANGED_ERP_CTS_PROT |
+              BSS_CHANGED_ERP_PREAMBLE |
+              BSS_CHANGED_ERP_SLOT;
 }
 
 void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
@@ -466,8 +377,6 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
                                            struct sta_info *sta,
                                            struct sk_buff *skb)
 {
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-
        sta->tx_filtered_count++;
 
        /*
@@ -514,10 +423,9 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
                return;
        }
 
-       if (!test_sta_flags(sta, WLAN_STA_PS) &&
-           !(info->flags & IEEE80211_TX_CTL_REQUEUE)) {
+       if (!test_sta_flags(sta, WLAN_STA_PS) && !skb->requeue) {
                /* Software retry the packet once */
-               info->flags |= IEEE80211_TX_CTL_REQUEUE;
+               skb->requeue = 1;
                ieee80211_remove_tx_extra(local, sta->key, skb);
                dev_queue_xmit(skb);
                return;
@@ -547,13 +455,28 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
        struct ieee80211_sub_if_data *sdata;
        struct net_device *prev_dev = NULL;
        struct sta_info *sta;
+       int retry_count = -1, i;
+
+       for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
+               /* the HW cannot have attempted that rate */
+               if (i >= hw->max_rates) {
+                       info->status.rates[i].idx = -1;
+                       info->status.rates[i].count = 0;
+               }
+
+               retry_count += info->status.rates[i].count;
+       }
+       if (retry_count < 0)
+               retry_count = 0;
 
        rcu_read_lock();
 
+       sband = local->hw.wiphy->bands[info->band];
+
        sta = sta_info_get(local, hdr->addr1);
 
        if (sta) {
-               if (info->status.excessive_retries &&
+               if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
                    test_sta_flags(sta, WLAN_STA_PS)) {
                        /*
                         * The STA is in power save mode, so assume
@@ -584,12 +507,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
                        rcu_read_unlock();
                        return;
                } else {
-                       if (info->status.excessive_retries)
+                       if (!(info->flags & IEEE80211_TX_STAT_ACK))
                                sta->tx_retry_failed++;
-                       sta->tx_retry_count += info->status.retry_count;
+                       sta->tx_retry_count += retry_count;
                }
 
-               sband = local->hw.wiphy->bands[info->band];
                rate_control_tx_status(local, sband, sta, skb);
        }
 
@@ -610,9 +532,9 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
                        local->dot11TransmittedFrameCount++;
                        if (is_multicast_ether_addr(hdr->addr1))
                                local->dot11MulticastTransmittedFrameCount++;
-                       if (info->status.retry_count > 0)
+                       if (retry_count > 0)
                                local->dot11RetryCount++;
-                       if (info->status.retry_count > 1)
+                       if (retry_count > 1)
                                local->dot11MultipleRetryCount++;
                }
 
@@ -656,19 +578,30 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
        rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));
        rthdr->hdr.it_present =
                cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |
-                           (1 << IEEE80211_RADIOTAP_DATA_RETRIES));
+                           (1 << IEEE80211_RADIOTAP_DATA_RETRIES) |
+                           (1 << IEEE80211_RADIOTAP_RATE));
 
        if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
            !is_multicast_ether_addr(hdr->addr1))
                rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL);
 
-       if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) &&
-           (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT))
+       /*
+        * XXX: Once radiotap gets the bitmap reset thing the vendor
+        *      extensions proposal contains, we can actually report
+        *      the whole set of tries we did.
+        */
+       if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
+           (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
                rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS);
-       else if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
+       else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
                rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS);
+       if (info->status.rates[0].idx >= 0 &&
+           !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS))
+               rthdr->rate = sband->bitrates[
+                               info->status.rates[0].idx].bitrate / 5;
 
-       rthdr->data_retries = info->status.retry_count;
+       /* for now report the total retry_count */
+       rthdr->data_retries = retry_count;
 
        /* XXX: is this sufficient for BPF? */
        skb_set_mac_header(skb, 0);
@@ -753,13 +686,14 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
        BUG_ON(!ops->configure_filter);
        local->ops = ops;
 
-       local->hw.queues = 1; /* default */
-
+       /* set up some defaults */
+       local->hw.queues = 1;
+       local->hw.max_rates = 1;
        local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
        local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
-       local->short_retry_limit = 7;
-       local->long_retry_limit = 4;
-       local->hw.conf.radio_enabled = 1;
+       local->hw.conf.long_frame_max_tx_count = 4;
+       local->hw.conf.short_frame_max_tx_count = 7;
+       local->hw.conf.radio_enabled = true;
 
        INIT_LIST_HEAD(&local->interfaces);
 
@@ -1013,7 +947,7 @@ static int __init ieee80211_init(void)
 
        BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb));
        BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) +
-                    IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb));
+                    IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb));
 
        ret = rc80211_minstrel_init();
        if (ret)
index 8013277924f2d75fca8acca678cbebb079c0f8a4..82f568e943657c2c5114ef111f57e53292011edc 100644 (file)
@@ -238,7 +238,7 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
 
        pos = skb_put(skb, 21);
        *pos++ = WLAN_EID_MESH_CONFIG;
-       *pos++ = MESH_CFG_LEN;
+       *pos++ = IEEE80211_MESH_CONFIG_LEN;
        /* Version */
        *pos++ = 1;
 
@@ -473,7 +473,7 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
                                        size_t len,
                                        struct ieee80211_rx_status *rx_status)
 {
-       struct ieee80211_local *local= sdata->local;
+       struct ieee80211_local *local = sdata->local;
        struct ieee802_11_elems elems;
        struct ieee80211_channel *channel;
        u64 supp_rates = 0;
index e10471c6ba42457894ebca93db6a7f8c9376323f..c197ab545e54a05e56b46f946d1d2bb8e3f5e5e9 100644 (file)
@@ -145,9 +145,6 @@ struct mesh_rmc {
 };
 
 
-/* Mesh IEs constants */
-#define MESH_CFG_LEN           19
-
 /*
  * MESH_CFG_COMP_LEN Includes:
  *     - Active path selection protocol ID.
@@ -157,7 +154,7 @@ struct mesh_rmc {
  * Does not include mesh capabilities, which may vary across nodes in the same
  * mesh
  */
-#define MESH_CFG_CMP_LEN       17
+#define MESH_CFG_CMP_LEN       (IEEE80211_MESH_CONFIG_LEN - 2)
 
 /* Default values, timeouts in ms */
 #define MESH_TTL               5
index 501c7831adb4469627c8b7cd0a8c3b067478ff3b..e8d573d592e709c87d0eddfed9e2f2c53774d4e3 100644 (file)
@@ -218,12 +218,16 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
 
        if (sta->fail_avg >= 100)
                return MAX_METRIC;
+
+       if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
+               return MAX_METRIC;
+
        err = (sta->fail_avg << ARITH_SHIFT) / 100;
 
        /* bitrate is in units of 100 Kbps, while we need rate in units of
         * 1Mbps. This will be corrected on tx_time computation.
         */
-       rate = sband->bitrates[sta->last_txrate_idx].bitrate;
+       rate = sband->bitrates[sta->last_tx_rate.idx].bitrate;
        tx_time = (device_constant + 10 * test_frame_len / rate);
        estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err));
        result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ;
index faac101c0f85a2b7001dfc42c068d5e6140557c3..929ba542fd7294fb812983384552cb2fbb869076 100644 (file)
@@ -257,9 +257,6 @@ static void mesh_plink_timer(unsigned long data)
        struct sta_info *sta;
        __le16 llid, plid, reason;
        struct ieee80211_sub_if_data *sdata;
-#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
-       DECLARE_MAC_BUF(mac);
-#endif
 
        /*
         * This STA is valid because sta_info_destroy() will
@@ -274,8 +271,8 @@ static void mesh_plink_timer(unsigned long data)
                spin_unlock_bh(&sta->lock);
                return;
        }
-       mpl_dbg("Mesh plink timer for %s fired on state %d\n",
-                       print_mac(mac, sta->sta.addr), sta->plink_state);
+       mpl_dbg("Mesh plink timer for %pM fired on state %d\n",
+               sta->sta.addr, sta->plink_state);
        reason = 0;
        llid = sta->llid;
        plid = sta->plid;
@@ -287,9 +284,9 @@ static void mesh_plink_timer(unsigned long data)
                /* retry timer */
                if (sta->plink_retries < dot11MeshMaxRetries(sdata)) {
                        u32 rand;
-                       mpl_dbg("Mesh plink for %s (retry, timeout): %d %d\n",
-                                       print_mac(mac, sta->sta.addr),
-                                       sta->plink_retries, sta->plink_timeout);
+                       mpl_dbg("Mesh plink for %pM (retry, timeout): %d %d\n",
+                               sta->sta.addr, sta->plink_retries,
+                               sta->plink_timeout);
                        get_random_bytes(&rand, sizeof(u32));
                        sta->plink_timeout = sta->plink_timeout +
                                             rand % sta->plink_timeout;
@@ -337,9 +334,6 @@ int mesh_plink_open(struct sta_info *sta)
 {
        __le16 llid;
        struct ieee80211_sub_if_data *sdata = sta->sdata;
-#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
-       DECLARE_MAC_BUF(mac);
-#endif
 
        spin_lock_bh(&sta->lock);
        get_random_bytes(&llid, 2);
@@ -351,8 +345,8 @@ int mesh_plink_open(struct sta_info *sta)
        sta->plink_state = PLINK_OPN_SNT;
        mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
        spin_unlock_bh(&sta->lock);
-       mpl_dbg("Mesh plink: starting establishment with %s\n",
-               print_mac(mac, sta->sta.addr));
+       mpl_dbg("Mesh plink: starting establishment with %pM\n",
+               sta->sta.addr);
 
        return mesh_plink_frame_tx(sdata, PLINK_OPEN,
                                   sta->sta.addr, llid, 0, 0);
@@ -360,10 +354,6 @@ int mesh_plink_open(struct sta_info *sta)
 
 void mesh_plink_block(struct sta_info *sta)
 {
-#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
-       DECLARE_MAC_BUF(mac);
-#endif
-
        spin_lock_bh(&sta->lock);
        __mesh_plink_deactivate(sta);
        sta->plink_state = PLINK_BLOCKED;
@@ -374,12 +364,8 @@ int mesh_plink_close(struct sta_info *sta)
 {
        struct ieee80211_sub_if_data *sdata = sta->sdata;
        __le16 llid, plid, reason;
-#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
-       DECLARE_MAC_BUF(mac);
-#endif
 
-       mpl_dbg("Mesh plink: closing link with %s\n",
-                       print_mac(mac, sta->sta.addr));
+       mpl_dbg("Mesh plink: closing link with %pM\n", sta->sta.addr);
        spin_lock_bh(&sta->lock);
        sta->reason = cpu_to_le16(MESH_LINK_CANCELLED);
        reason = sta->reason;
@@ -417,9 +403,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
        u8 ie_len;
        u8 *baseaddr;
        __le16 plid, llid, reason;
-#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
-       DECLARE_MAC_BUF(mac);
-#endif
 
        /* need action_code, aux */
        if (len < IEEE80211_MIN_ACTION_SIZE + 3)
@@ -557,10 +540,10 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                }
        }
 
-       mpl_dbg("Mesh plink (peer, state, llid, plid, event): %s %d %d %d %d\n",
-                       print_mac(mac, mgmt->sa), sta->plink_state,
-                       le16_to_cpu(sta->llid), le16_to_cpu(sta->plid),
-                       event);
+       mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %d %d %d %d\n",
+               mgmt->sa, sta->plink_state,
+               le16_to_cpu(sta->llid), le16_to_cpu(sta->plid),
+               event);
        reason = 0;
        switch (sta->plink_state) {
                /* spin_unlock as soon as state is updated at each case */
@@ -660,8 +643,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                        sta->plink_state = PLINK_ESTAB;
                        mesh_plink_inc_estab_count(sdata);
                        spin_unlock_bh(&sta->lock);
-                       mpl_dbg("Mesh plink with %s ESTABLISHED\n",
-                                       print_mac(mac, sta->sta.addr));
+                       mpl_dbg("Mesh plink with %pM ESTABLISHED\n",
+                               sta->sta.addr);
                        break;
                default:
                        spin_unlock_bh(&sta->lock);
@@ -693,8 +676,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
                        sta->plink_state = PLINK_ESTAB;
                        mesh_plink_inc_estab_count(sdata);
                        spin_unlock_bh(&sta->lock);
-                       mpl_dbg("Mesh plink with %s ESTABLISHED\n",
-                                       print_mac(mac, sta->sta.addr));
+                       mpl_dbg("Mesh plink with %pM ESTABLISHED\n",
+                               sta->sta.addr);
                        mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid,
                                            plid, 0);
                        break;
index 14d165f0df75ff90e1ec9648b4454245cdbcd153..b2099306def733be1910f3b2510e8a12273e78c1 100644 (file)
@@ -236,7 +236,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        struct sk_buff *skb;
        struct ieee80211_mgmt *mgmt;
-       u8 *pos, *ies, *ht_add_ie;
+       u8 *pos, *ies, *ht_ie;
        int i, len, count, rates_len, supp_rates_len;
        u16 capab;
        struct ieee80211_bss *bss;
@@ -393,24 +393,25 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
 
        /* wmm support is a must to HT */
        if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) &&
-           sband->ht_info.ht_supported &&
-           (ht_add_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_EXTRA_INFO))) {
-               struct ieee80211_ht_addt_info *ht_add_info =
-                       (struct ieee80211_ht_addt_info *)ht_add_ie;
-               u16 cap = sband->ht_info.cap;
+           sband->ht_cap.ht_supported &&
+           (ht_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_INFORMATION)) &&
+           ht_ie[1] >= sizeof(struct ieee80211_ht_info)) {
+               struct ieee80211_ht_info *ht_info =
+                       (struct ieee80211_ht_info *)(ht_ie + 2);
+               u16 cap = sband->ht_cap.cap;
                __le16 tmp;
                u32 flags = local->hw.conf.channel->flags;
 
-               switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) {
-               case IEEE80211_HT_IE_CHA_SEC_ABOVE:
+               switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
+               case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
                        if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) {
-                               cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
+                               cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
                                cap &= ~IEEE80211_HT_CAP_SGI_40;
                        }
                        break;
-               case IEEE80211_HT_IE_CHA_SEC_BELOW:
+               case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
                        if (flags & IEEE80211_CHAN_NO_FAT_BELOW) {
-                               cap &= ~IEEE80211_HT_CAP_SUP_WIDTH;
+                               cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
                                cap &= ~IEEE80211_HT_CAP_SGI_40;
                        }
                        break;
@@ -424,9 +425,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
                memcpy(pos, &tmp, sizeof(u16));
                pos += sizeof(u16);
                /* TODO: needs a define here for << 2 */
-               *pos++ = sband->ht_info.ampdu_factor |
-                        (sband->ht_info.ampdu_density << 2);
-               memcpy(pos, sband->ht_info.supp_mcs_set, 16);
+               *pos++ = sband->ht_cap.ampdu_factor |
+                        (sband->ht_cap.ampdu_density << 2);
+               memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
        }
 
        kfree(ifsta->assocreq_ies);
@@ -568,25 +569,35 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
        }
 }
 
-static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata,
-                                          bool use_protection,
-                                          bool use_short_preamble)
+static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
+                                          u16 capab, bool erp_valid, u8 erp)
 {
-       struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
+       struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
        struct ieee80211_if_sta *ifsta = &sdata->u.sta;
-       DECLARE_MAC_BUF(mac);
 #endif
        u32 changed = 0;
+       bool use_protection;
+       bool use_short_preamble;
+       bool use_short_slot;
+
+       if (erp_valid) {
+               use_protection = (erp & WLAN_ERP_USE_PROTECTION) != 0;
+               use_short_preamble = (erp & WLAN_ERP_BARKER_PREAMBLE) == 0;
+       } else {
+               use_protection = false;
+               use_short_preamble = !!(capab & WLAN_CAPABILITY_SHORT_PREAMBLE);
+       }
+
+       use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
 
        if (use_protection != bss_conf->use_cts_prot) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
                if (net_ratelimit()) {
-                       printk(KERN_DEBUG "%s: CTS protection %s (BSSID="
-                              "%s)\n",
+                       printk(KERN_DEBUG "%s: CTS protection %s (BSSID=%pM)\n",
                               sdata->dev->name,
                               use_protection ? "enabled" : "disabled",
-                              print_mac(mac, ifsta->bssid));
+                              ifsta->bssid);
                }
 #endif
                bss_conf->use_cts_prot = use_protection;
@@ -597,40 +608,28 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata,
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "%s: switched to %s barker preamble"
-                              " (BSSID=%s)\n",
+                              " (BSSID=%pM)\n",
                               sdata->dev->name,
                               use_short_preamble ? "short" : "long",
-                              print_mac(mac, ifsta->bssid));
+                              ifsta->bssid);
                }
 #endif
                bss_conf->use_short_preamble = use_short_preamble;
                changed |= BSS_CHANGED_ERP_PREAMBLE;
        }
 
-       return changed;
-}
-
-static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata,
-                                  u8 erp_value)
-{
-       bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
-       bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0;
-
-       return ieee80211_handle_protect_preamb(sdata,
-                       use_protection, use_short_preamble);
-}
-
-static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
-                                          struct ieee80211_bss *bss)
-{
-       u32 changed = 0;
-
-       if (bss->has_erp_value)
-               changed |= ieee80211_handle_erp_ie(sdata, bss->erp_value);
-       else {
-               u16 capab = bss->capability;
-               changed |= ieee80211_handle_protect_preamb(sdata, false,
-                               (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);
+       if (use_short_slot != bss_conf->use_short_slot) {
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+               if (net_ratelimit()) {
+                       printk(KERN_DEBUG "%s: switched to %s slot"
+                              " (BSSID=%s)\n",
+                              sdata->dev->name,
+                              use_short_slot ? "short" : "long",
+                              ifsta->bssid);
+               }
+#endif
+               bss_conf->use_short_slot = use_short_slot;
+               changed |= BSS_CHANGED_ERP_SLOT;
        }
 
        return changed;
@@ -701,14 +700,15 @@ static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata,
 
 
 static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
-                                    struct ieee80211_if_sta *ifsta)
+                                    struct ieee80211_if_sta *ifsta,
+                                    u32 bss_info_changed)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_conf *conf = &local_to_hw(local)->conf;
-       u32 changed = BSS_CHANGED_ASSOC;
 
        struct ieee80211_bss *bss;
 
+       bss_info_changed |= BSS_CHANGED_ASSOC;
        ifsta->flags |= IEEE80211_STA_ASSOCIATED;
 
        if (sdata->vif.type != NL80211_IFTYPE_STATION)
@@ -719,22 +719,16 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
                                   ifsta->ssid, ifsta->ssid_len);
        if (bss) {
                /* set timing information */
-               sdata->bss_conf.beacon_int = bss->beacon_int;
-               sdata->bss_conf.timestamp = bss->timestamp;
-               sdata->bss_conf.dtim_period = bss->dtim_period;
+               sdata->vif.bss_conf.beacon_int = bss->beacon_int;
+               sdata->vif.bss_conf.timestamp = bss->timestamp;
+               sdata->vif.bss_conf.dtim_period = bss->dtim_period;
 
-               changed |= ieee80211_handle_bss_capability(sdata, bss);
+               bss_info_changed |= ieee80211_handle_bss_capability(sdata,
+                       bss->capability, bss->has_erp_value, bss->erp_value);
 
                ieee80211_rx_bss_put(local, bss);
        }
 
-       if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
-               changed |= BSS_CHANGED_HT;
-               sdata->bss_conf.assoc_ht = 1;
-               sdata->bss_conf.ht_conf = &conf->ht_conf;
-               sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf;
-       }
-
        ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET;
        memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN);
        ieee80211_sta_send_associnfo(sdata, ifsta);
@@ -742,14 +736,14 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
        ifsta->last_probe = jiffies;
        ieee80211_led_assoc(local, 1);
 
-       sdata->bss_conf.assoc = 1;
+       sdata->vif.bss_conf.assoc = 1;
        /*
         * For now just always ask the driver to update the basic rateset
         * when we have associated, we aren't checking whether it actually
         * changed or not.
         */
-       changed |= BSS_CHANGED_BASIC_RATES;
-       ieee80211_bss_info_change_notify(sdata, changed);
+       bss_info_changed |= BSS_CHANGED_BASIC_RATES;
+       ieee80211_bss_info_change_notify(sdata, bss_info_changed);
 
        netif_tx_start_all_queues(sdata->dev);
        netif_carrier_on(sdata->dev);
@@ -760,18 +754,17 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
 static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
                                   struct ieee80211_if_sta *ifsta)
 {
-       DECLARE_MAC_BUF(mac);
-
        ifsta->direct_probe_tries++;
        if (ifsta->direct_probe_tries > IEEE80211_AUTH_MAX_TRIES) {
-               printk(KERN_DEBUG "%s: direct probe to AP %s timed out\n",
-                      sdata->dev->name, print_mac(mac, ifsta->bssid));
+               printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n",
+                      sdata->dev->name, ifsta->bssid);
                ifsta->state = IEEE80211_STA_MLME_DISABLED;
+               ieee80211_sta_send_apinfo(sdata, ifsta);
                return;
        }
 
-       printk(KERN_DEBUG "%s: direct probe to AP %s try %d\n",
-                       sdata->dev->name, print_mac(mac, ifsta->bssid),
+       printk(KERN_DEBUG "%s: direct probe to AP %pM try %d\n",
+                       sdata->dev->name, ifsta->bssid,
                        ifsta->direct_probe_tries);
 
        ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
@@ -791,20 +784,19 @@ static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
 static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
                                   struct ieee80211_if_sta *ifsta)
 {
-       DECLARE_MAC_BUF(mac);
-
        ifsta->auth_tries++;
        if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) {
-               printk(KERN_DEBUG "%s: authentication with AP %s"
+               printk(KERN_DEBUG "%s: authentication with AP %pM"
                       " timed out\n",
-                      sdata->dev->name, print_mac(mac, ifsta->bssid));
+                      sdata->dev->name, ifsta->bssid);
                ifsta->state = IEEE80211_STA_MLME_DISABLED;
+               ieee80211_sta_send_apinfo(sdata, ifsta);
                return;
        }
 
        ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
-       printk(KERN_DEBUG "%s: authenticate with AP %s\n",
-              sdata->dev->name, print_mac(mac, ifsta->bssid));
+       printk(KERN_DEBUG "%s: authenticate with AP %pM\n",
+              sdata->dev->name, ifsta->bssid);
 
        ieee80211_send_auth(sdata, ifsta, 1, NULL, 0, 0);
 
@@ -817,7 +809,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
 {
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
-       u32 changed = BSS_CHANGED_ASSOC;
+       u32 changed = 0;
 
        rcu_read_lock();
 
@@ -851,15 +843,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
        ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
        changed |= ieee80211_reset_erp_info(sdata);
 
-       if (sdata->bss_conf.assoc_ht)
-               changed |= BSS_CHANGED_HT;
-
-       sdata->bss_conf.assoc_ht = 0;
-       sdata->bss_conf.ht_conf = NULL;
-       sdata->bss_conf.ht_bss_conf = NULL;
-
        ieee80211_led_assoc(local, 0);
-       sdata->bss_conf.assoc = 0;
+       changed |= BSS_CHANGED_ASSOC;
+       sdata->vif.bss_conf.assoc = false;
 
        ieee80211_sta_send_apinfo(sdata, ifsta);
 
@@ -871,6 +857,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
        rcu_read_unlock();
 
        sta_info_destroy(sta);
+
+       local->hw.conf.ht.enabled = false;
+       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT);
+
+       ieee80211_bss_info_change_notify(sdata, changed);
 }
 
 static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata)
@@ -914,20 +905,19 @@ static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata,
 static void ieee80211_associate(struct ieee80211_sub_if_data *sdata,
                                struct ieee80211_if_sta *ifsta)
 {
-       DECLARE_MAC_BUF(mac);
-
        ifsta->assoc_tries++;
        if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) {
-               printk(KERN_DEBUG "%s: association with AP %s"
+               printk(KERN_DEBUG "%s: association with AP %pM"
                       " timed out\n",
-                      sdata->dev->name, print_mac(mac, ifsta->bssid));
+                      sdata->dev->name, ifsta->bssid);
                ifsta->state = IEEE80211_STA_MLME_DISABLED;
+               ieee80211_sta_send_apinfo(sdata, ifsta);
                return;
        }
 
        ifsta->state = IEEE80211_STA_MLME_ASSOCIATE;
-       printk(KERN_DEBUG "%s: associate with AP %s\n",
-              sdata->dev->name, print_mac(mac, ifsta->bssid));
+       printk(KERN_DEBUG "%s: associate with AP %pM\n",
+              sdata->dev->name, ifsta->bssid);
        if (ieee80211_privacy_mismatch(sdata, ifsta)) {
                printk(KERN_DEBUG "%s: mismatch in privacy configuration and "
                       "mixed-cell disabled - abort association\n", sdata->dev->name);
@@ -947,7 +937,6 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
        int disassoc;
-       DECLARE_MAC_BUF(mac);
 
        /* TODO: start monitoring current AP signal quality and number of
         * missed beacons. Scan other channels every now and then and search
@@ -960,8 +949,8 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
 
        sta = sta_info_get(local, ifsta->bssid);
        if (!sta) {
-               printk(KERN_DEBUG "%s: No STA entry for own AP %s\n",
-                      sdata->dev->name, print_mac(mac, ifsta->bssid));
+               printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n",
+                      sdata->dev->name, ifsta->bssid);
                disassoc = 1;
        } else {
                disassoc = 0;
@@ -969,9 +958,9 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
                               sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
                        if (ifsta->flags & IEEE80211_STA_PROBEREQ_POLL) {
                                printk(KERN_DEBUG "%s: No ProbeResp from "
-                                      "current AP %s - assume out of "
+                                      "current AP %pM - assume out of "
                                       "range\n",
-                                      sdata->dev->name, print_mac(mac, ifsta->bssid));
+                                      sdata->dev->name, ifsta->bssid);
                                disassoc = 1;
                        } else
                                ieee80211_send_probe_req(sdata, ifsta->bssid,
@@ -1032,7 +1021,6 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
                                   size_t len)
 {
        u16 auth_alg, auth_transaction, status_code;
-       DECLARE_MAC_BUF(mac);
 
        if (ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE &&
            sdata->vif.type != NL80211_IFTYPE_ADHOC)
@@ -1125,7 +1113,6 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
                                     size_t len)
 {
        u16 reason_code;
-       DECLARE_MAC_BUF(mac);
 
        if (len < 24 + 2)
                return;
@@ -1136,7 +1123,8 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
        reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
 
        if (ifsta->flags & IEEE80211_STA_AUTHENTICATED)
-               printk(KERN_DEBUG "%s: deauthenticated\n", sdata->dev->name);
+               printk(KERN_DEBUG "%s: deauthenticated (Reason: %u)\n",
+                               sdata->dev->name, reason_code);
 
        if (ifsta->state == IEEE80211_STA_MLME_AUTHENTICATE ||
            ifsta->state == IEEE80211_STA_MLME_ASSOCIATE ||
@@ -1157,7 +1145,6 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
                                       size_t len)
 {
        u16 reason_code;
-       DECLARE_MAC_BUF(mac);
 
        if (len < 24 + 2)
                return;
@@ -1168,7 +1155,8 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
        reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
 
        if (ifsta->flags & IEEE80211_STA_ASSOCIATED)
-               printk(KERN_DEBUG "%s: disassociated\n", sdata->dev->name);
+               printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n",
+                               sdata->dev->name, reason_code);
 
        if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) {
                ifsta->state = IEEE80211_STA_MLME_ASSOCIATE;
@@ -1192,11 +1180,12 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
        u64 rates, basic_rates;
        u16 capab_info, status_code, aid;
        struct ieee802_11_elems elems;
-       struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
+       struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
        u8 *pos;
+       u32 changed = 0;
        int i, j;
-       DECLARE_MAC_BUF(mac);
-       bool have_higher_than_11mbit = false;
+       bool have_higher_than_11mbit = false, newsta = false;
+       u16 ap_ht_cap_flags;
 
        /* AssocResp and ReassocResp have identical structure, so process both
         * of them in this function. */
@@ -1214,9 +1203,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
        status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
        aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
 
-       printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x "
+       printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x "
               "status=%d aid=%d)\n",
-              sdata->dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa),
+              sdata->dev->name, reassoc ? "Rea" : "A", mgmt->sa,
               capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
 
        if (status_code != WLAN_STATUS_SUCCESS) {
@@ -1259,7 +1248,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
        sta = sta_info_get(local, ifsta->bssid);
        if (!sta) {
                struct ieee80211_bss *bss;
-               int err;
+
+               newsta = true;
 
                sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC);
                if (!sta) {
@@ -1278,13 +1268,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
                        ieee80211_rx_bss_put(local, bss);
                }
 
-               err = sta_info_insert(sta);
-               if (err) {
-                       printk(KERN_DEBUG "%s: failed to insert STA entry for"
-                              " the AP (error %d)\n", sdata->dev->name, err);
-                       rcu_read_unlock();
-                       return;
-               }
                /* update new sta with its last rx activity */
                sta->last_rx = jiffies;
        }
@@ -1308,34 +1291,40 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
 
        for (i = 0; i < elems.supp_rates_len; i++) {
                int rate = (elems.supp_rates[i] & 0x7f) * 5;
+               bool is_basic = !!(elems.supp_rates[i] & 0x80);
 
                if (rate > 110)
                        have_higher_than_11mbit = true;
 
                for (j = 0; j < sband->n_bitrates; j++) {
-                       if (sband->bitrates[j].bitrate == rate)
+                       if (sband->bitrates[j].bitrate == rate) {
                                rates |= BIT(j);
-                       if (elems.supp_rates[i] & 0x80)
-                               basic_rates |= BIT(j);
+                               if (is_basic)
+                                       basic_rates |= BIT(j);
+                               break;
+                       }
                }
        }
 
        for (i = 0; i < elems.ext_supp_rates_len; i++) {
                int rate = (elems.ext_supp_rates[i] & 0x7f) * 5;
+               bool is_basic = !!(elems.supp_rates[i] & 0x80);
 
                if (rate > 110)
                        have_higher_than_11mbit = true;
 
                for (j = 0; j < sband->n_bitrates; j++) {
-                       if (sband->bitrates[j].bitrate == rate)
+                       if (sband->bitrates[j].bitrate == rate) {
                                rates |= BIT(j);
-                       if (elems.ext_supp_rates[i] & 0x80)
-                               basic_rates |= BIT(j);
+                               if (is_basic)
+                                       basic_rates |= BIT(j);
+                               break;
+                       }
                }
        }
 
        sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
-       sdata->bss_conf.basic_rates = basic_rates;
+       sdata->vif.bss_conf.basic_rates = basic_rates;
 
        /* cf. IEEE 802.11 9.2.12 */
        if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
@@ -1344,31 +1333,43 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
        else
                sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
 
-       if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param &&
-           (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
-               struct ieee80211_ht_bss_info bss_info;
-               ieee80211_ht_cap_ie_to_ht_info(
-                               elems.ht_cap_elem, &sta->sta.ht_info);
-               ieee80211_ht_addt_info_ie_to_ht_bss_info(
-                               elems.ht_info_elem, &bss_info);
-               ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info);
-       }
+       if (elems.ht_cap_elem)
+               ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
+                               elems.ht_cap_elem, &sta->sta.ht_cap);
+
+       ap_ht_cap_flags = sta->sta.ht_cap.cap;
 
        rate_control_rate_init(sta);
 
-       if (elems.wmm_param) {
+       if (elems.wmm_param)
                set_sta_flags(sta, WLAN_STA_WME);
-               rcu_read_unlock();
+
+       if (newsta) {
+               int err = sta_info_insert(sta);
+               if (err) {
+                       printk(KERN_DEBUG "%s: failed to insert STA entry for"
+                              " the AP (error %d)\n", sdata->dev->name, err);
+                       rcu_read_unlock();
+                       return;
+               }
+       }
+
+       rcu_read_unlock();
+
+       if (elems.wmm_param)
                ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
                                         elems.wmm_param_len);
-       } else
-               rcu_read_unlock();
+
+       if (elems.ht_info_elem && elems.wmm_param &&
+           (ifsta->flags & IEEE80211_STA_WMM_ENABLED))
+               changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
+                                              ap_ht_cap_flags);
 
        /* set AID and assoc capability,
         * ieee80211_set_associated() will tell the driver */
        bss_conf->aid = aid;
        bss_conf->assoc_capability = capab_info;
-       ieee80211_set_associated(sdata, ifsta);
+       ieee80211_set_associated(sdata, ifsta, changed);
 
        ieee80211_associated(sdata, ifsta);
 }
@@ -1386,6 +1387,13 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_supported_band *sband;
        union iwreq_data wrqu;
 
+       skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
+       if (!skb) {
+               printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
+                      "response\n", sdata->dev->name);
+               return -ENOMEM;
+       }
+
        sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
 
        /* Remove possible STA entries from other IBSS networks. */
@@ -1411,63 +1419,62 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
                return res;
 
        /* Build IBSS probe response */
-       skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
-       if (skb) {
-               skb_reserve(skb, local->hw.extra_tx_headroom);
 
-               mgmt = (struct ieee80211_mgmt *)
-                       skb_put(skb, 24 + sizeof(mgmt->u.beacon));
-               memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
-               mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
-                                                 IEEE80211_STYPE_PROBE_RESP);
-               memset(mgmt->da, 0xff, ETH_ALEN);
-               memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
-               memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
-               mgmt->u.beacon.beacon_int =
-                       cpu_to_le16(local->hw.conf.beacon_int);
-               mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp);
-               mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability);
-
-               pos = skb_put(skb, 2 + ifsta->ssid_len);
-               *pos++ = WLAN_EID_SSID;
-               *pos++ = ifsta->ssid_len;
-               memcpy(pos, ifsta->ssid, ifsta->ssid_len);
-
-               rates = bss->supp_rates_len;
-               if (rates > 8)
-                       rates = 8;
-               pos = skb_put(skb, 2 + rates);
-               *pos++ = WLAN_EID_SUPP_RATES;
-               *pos++ = rates;
-               memcpy(pos, bss->supp_rates, rates);
+       skb_reserve(skb, local->hw.extra_tx_headroom);
 
-               if (bss->band == IEEE80211_BAND_2GHZ) {
-                       pos = skb_put(skb, 2 + 1);
-                       *pos++ = WLAN_EID_DS_PARAMS;
-                       *pos++ = 1;
-                       *pos++ = ieee80211_frequency_to_channel(bss->freq);
-               }
+       mgmt = (struct ieee80211_mgmt *)
+               skb_put(skb, 24 + sizeof(mgmt->u.beacon));
+       memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
+       mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+                                               IEEE80211_STYPE_PROBE_RESP);
+       memset(mgmt->da, 0xff, ETH_ALEN);
+       memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
+       memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
+       mgmt->u.beacon.beacon_int =
+               cpu_to_le16(local->hw.conf.beacon_int);
+       mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp);
+       mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability);
 
-               pos = skb_put(skb, 2 + 2);
-               *pos++ = WLAN_EID_IBSS_PARAMS;
-               *pos++ = 2;
-               /* FIX: set ATIM window based on scan results */
-               *pos++ = 0;
-               *pos++ = 0;
+       pos = skb_put(skb, 2 + ifsta->ssid_len);
+       *pos++ = WLAN_EID_SSID;
+       *pos++ = ifsta->ssid_len;
+       memcpy(pos, ifsta->ssid, ifsta->ssid_len);
 
-               if (bss->supp_rates_len > 8) {
-                       rates = bss->supp_rates_len - 8;
-                       pos = skb_put(skb, 2 + rates);
-                       *pos++ = WLAN_EID_EXT_SUPP_RATES;
-                       *pos++ = rates;
-                       memcpy(pos, &bss->supp_rates[8], rates);
-               }
+       rates = bss->supp_rates_len;
+       if (rates > 8)
+               rates = 8;
+       pos = skb_put(skb, 2 + rates);
+       *pos++ = WLAN_EID_SUPP_RATES;
+       *pos++ = rates;
+       memcpy(pos, bss->supp_rates, rates);
+
+       if (bss->band == IEEE80211_BAND_2GHZ) {
+               pos = skb_put(skb, 2 + 1);
+               *pos++ = WLAN_EID_DS_PARAMS;
+               *pos++ = 1;
+               *pos++ = ieee80211_frequency_to_channel(bss->freq);
+       }
 
-               ifsta->probe_resp = skb;
+       pos = skb_put(skb, 2 + 2);
+       *pos++ = WLAN_EID_IBSS_PARAMS;
+       *pos++ = 2;
+       /* FIX: set ATIM window based on scan results */
+       *pos++ = 0;
+       *pos++ = 0;
 
-               ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
+       if (bss->supp_rates_len > 8) {
+               rates = bss->supp_rates_len - 8;
+               pos = skb_put(skb, 2 + rates);
+               *pos++ = WLAN_EID_EXT_SUPP_RATES;
+               *pos++ = rates;
+               memcpy(pos, &bss->supp_rates[8], rates);
        }
 
+       ifsta->probe_resp = skb;
+
+       ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
+
+
        rates = 0;
        sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
        for (i = 0; i < bss->supp_rates_len; i++) {
@@ -1507,8 +1514,6 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
        u64 beacon_timestamp, rx_timestamp;
        u64 supp_rates = 0;
        enum ieee80211_band band = rx_status->band;
-       DECLARE_MAC_BUF(mac);
-       DECLARE_MAC_BUF(mac2);
 
        if (elems->ds_params && elems->ds_params_len == 1)
                freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
@@ -1538,10 +1543,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
                        if (sta->sta.supp_rates[band] != prev_rates)
                                printk(KERN_DEBUG "%s: updated supp_rates set "
-                                   "for %s based on beacon info (0x%llx | "
+                                   "for %pM based on beacon info (0x%llx | "
                                    "0x%llx -> 0x%llx)\n",
                                    sdata->dev->name,
-                                   print_mac(mac, sta->sta.addr),
+                                   sta->sta.addr,
                                    (unsigned long long) prev_rates,
                                    (unsigned long long) supp_rates,
                                    (unsigned long long) sta->sta.supp_rates[band]);
@@ -1605,10 +1610,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                        /* can't merge without knowing the TSF */
                        rx_timestamp = -1LLU;
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
-               printk(KERN_DEBUG "RX beacon SA=%s BSSID="
-                      "%s TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n",
-                      print_mac(mac, mgmt->sa),
-                      print_mac(mac2, mgmt->bssid),
+               printk(KERN_DEBUG "RX beacon SA=%pM BSSID="
+                      "%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n",
+                      mgmt->sa, mgmt->bssid,
                       (unsigned long long)rx_timestamp,
                       (unsigned long long)beacon_timestamp,
                       (unsigned long long)(rx_timestamp - beacon_timestamp),
@@ -1617,8 +1621,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                if (beacon_timestamp > rx_timestamp) {
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
                        printk(KERN_DEBUG "%s: beacon TSF higher than "
-                              "local TSF - IBSS merge with BSSID %s\n",
-                              sdata->dev->name, print_mac(mac, mgmt->bssid));
+                              "local TSF - IBSS merge with BSSID %pM\n",
+                              sdata->dev->name, mgmt->bssid);
 #endif
                        ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss);
                        ieee80211_ibss_add_sta(sdata, NULL,
@@ -1671,8 +1675,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
        size_t baselen;
        struct ieee802_11_elems elems;
        struct ieee80211_local *local = sdata->local;
-       struct ieee80211_conf *conf = &local->hw.conf;
        u32 changed = 0;
+       bool erp_valid;
+       u8 erp_value = 0;
 
        /* Process beacon from the current BSS */
        baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
@@ -1694,22 +1699,42 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
        ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
                                 elems.wmm_param_len);
 
-       if (elems.erp_info && elems.erp_info_len >= 1)
-               changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]);
-       else {
-               u16 capab = le16_to_cpu(mgmt->u.beacon.capab_info);
-               changed |= ieee80211_handle_protect_preamb(sdata, false,
-                               (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);
+
+       if (elems.erp_info && elems.erp_info_len >= 1) {
+               erp_valid = true;
+               erp_value = elems.erp_info[0];
+       } else {
+               erp_valid = false;
        }
+       changed |= ieee80211_handle_bss_capability(sdata,
+                       le16_to_cpu(mgmt->u.beacon.capab_info),
+                       erp_valid, erp_value);
+
+
+       if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param) {
+               struct sta_info *sta;
+               struct ieee80211_supported_band *sband;
+               u16 ap_ht_cap_flags;
+
+               rcu_read_lock();
+
+               sta = sta_info_get(local, ifsta->bssid);
+               if (!sta) {
+                       rcu_read_unlock();
+                       return;
+               }
+
+               sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
 
-       if (elems.ht_cap_elem && elems.ht_info_elem &&
-           elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
-               struct ieee80211_ht_bss_info bss_info;
+               ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
+                               elems.ht_cap_elem, &sta->sta.ht_cap);
 
-               ieee80211_ht_addt_info_ie_to_ht_bss_info(
-                               elems.ht_info_elem, &bss_info);
-               changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf,
-                                              &bss_info);
+               ap_ht_cap_flags = sta->sta.ht_cap.cap;
+
+               rcu_read_unlock();
+
+               changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
+                                              ap_ht_cap_flags);
        }
 
        ieee80211_bss_info_change_notify(sdata, changed);
@@ -1727,11 +1752,6 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
        struct sk_buff *skb;
        struct ieee80211_mgmt *resp;
        u8 *pos, *end;
-       DECLARE_MAC_BUF(mac);
-#ifdef CONFIG_MAC80211_IBSS_DEBUG
-       DECLARE_MAC_BUF(mac2);
-       DECLARE_MAC_BUF(mac3);
-#endif
 
        if (sdata->vif.type != NL80211_IFTYPE_ADHOC ||
            ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED ||
@@ -1744,10 +1764,10 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
                tx_last_beacon = 1;
 
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
-       printk(KERN_DEBUG "%s: RX ProbeReq SA=%s DA=%s BSSID="
-              "%s (tx_last_beacon=%d)\n",
-              sdata->dev->name, print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da),
-              print_mac(mac3, mgmt->bssid), tx_last_beacon);
+       printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM"
+              " (tx_last_beacon=%d)\n",
+              sdata->dev->name, mgmt->sa, mgmt->da,
+              mgmt->bssid, tx_last_beacon);
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
 
        if (!tx_last_beacon)
@@ -1763,8 +1783,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
            pos + 2 + pos[1] > end) {
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
                printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq "
-                      "from %s\n",
-                      sdata->dev->name, print_mac(mac, mgmt->sa));
+                      "from %pM\n",
+                      sdata->dev->name, mgmt->sa);
 #endif
                return;
        }
@@ -1783,8 +1803,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
        resp = (struct ieee80211_mgmt *) skb->data;
        memcpy(resp->da, mgmt->sa, ETH_ALEN);
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
-       printk(KERN_DEBUG "%s: Sending ProbeResp to %s\n",
-              sdata->dev->name, print_mac(mac, resp->da));
+       printk(KERN_DEBUG "%s: Sending ProbeResp to %pM\n",
+              sdata->dev->name, resp->da);
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
        ieee80211_tx_skb(sdata, skb, 0);
 }
@@ -1990,7 +2010,6 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
        u8 bssid[ETH_ALEN], *pos;
        int i;
        int ret;
-       DECLARE_MAC_BUF(mac);
 
 #if 0
        /* Easier testing, use fixed BSSID. */
@@ -2006,8 +2025,8 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
        bssid[0] |= 0x02;
 #endif
 
-       printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n",
-              sdata->dev->name, print_mac(mac, bssid));
+       printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
+              sdata->dev->name, bssid);
 
        bss = ieee80211_rx_bss_add(local, bssid,
                                   local->hw.conf.channel->center_freq,
@@ -2050,8 +2069,6 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
        int found = 0;
        u8 bssid[ETH_ALEN];
        int active_ibss;
-       DECLARE_MAC_BUF(mac);
-       DECLARE_MAC_BUF(mac2);
 
        if (ifsta->ssid_len == 0)
                return -EINVAL;
@@ -2068,8 +2085,7 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
                    || !(bss->capability & WLAN_CAPABILITY_IBSS))
                        continue;
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
-               printk(KERN_DEBUG "   bssid=%s found\n",
-                      print_mac(mac, bss->bssid));
+               printk(KERN_DEBUG "   bssid=%pM found\n", bss->bssid);
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
                memcpy(bssid, bss->bssid, ETH_ALEN);
                found = 1;
@@ -2080,9 +2096,8 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
 
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
        if (found)
-               printk(KERN_DEBUG "   sta_find_ibss: selected %s current "
-                      "%s\n", print_mac(mac, bssid),
-                      print_mac(mac2, ifsta->bssid));
+               printk(KERN_DEBUG "   sta_find_ibss: selected %pM current "
+                      "%pM\n", bssid, ifsta->bssid);
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
 
        if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) {
@@ -2099,9 +2114,9 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
                if (!bss)
                        goto dont_join;
 
-               printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
+               printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
                       " based on configured SSID\n",
-                      sdata->dev->name, print_mac(mac, bssid));
+                      sdata->dev->name, bssid);
                ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
                ieee80211_rx_bss_put(local, bss);
                return ret;
@@ -2343,7 +2358,6 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
 {
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
-       DECLARE_MAC_BUF(mac);
        int band = local->hw.conf.channel->band;
 
        /* TODO: Could consider removing the least recently used entry and
@@ -2351,7 +2365,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
        if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "%s: No room for a new IBSS STA "
-                              "entry %s\n", sdata->dev->name, print_mac(mac, addr));
+                              "entry %pM\n", sdata->dev->name, addr);
                }
                return NULL;
        }
@@ -2360,8 +2374,8 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
                return NULL;
 
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-       printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n",
-              wiphy_name(local->hw.wiphy), print_mac(mac, addr), sdata->dev->name);
+       printk(KERN_DEBUG "%s: Adding new IBSS station %pM (dev=%s)\n",
+              wiphy_name(local->hw.wiphy), addr, sdata->dev->name);
 #endif
 
        sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
@@ -2408,7 +2422,6 @@ void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata,
 int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
 {
        struct ieee80211_if_sta *ifsta;
-       int res;
 
        if (len > IEEE80211_MAX_SSID_LEN)
                return -EINVAL;
@@ -2420,19 +2433,6 @@ int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size
                memcpy(ifsta->ssid, ssid, len);
                ifsta->ssid_len = len;
                ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
-
-               res = 0;
-               /*
-                * Hack! MLME code needs to be cleaned up to have different
-                * entry points for configuration and internal selection change
-                */
-               if (netif_running(sdata->dev))
-                       res = ieee80211_if_config(sdata, IEEE80211_IFCC_SSID);
-               if (res) {
-                       printk(KERN_DEBUG "%s: Failed to config new SSID to "
-                              "the low-level driver\n", sdata->dev->name);
-                       return res;
-               }
        }
 
        if (len)
index 5d786720d9357c8ecd96a027074489d338a30951..3fa7ab285066a46c5200d49c4ca06e4c56ff5456 100644 (file)
@@ -199,48 +199,44 @@ static void rate_control_release(struct kref *kref)
 }
 
 void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
-                          struct ieee80211_supported_band *sband,
-                          struct sta_info *sta, struct sk_buff *skb,
-                          struct rate_selection *sel)
+                          struct sta_info *sta,
+                          struct ieee80211_tx_rate_control *txrc)
 {
        struct rate_control_ref *ref = sdata->local->rate_ctrl;
        void *priv_sta = NULL;
        struct ieee80211_sta *ista = NULL;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
        int i;
 
-       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;
        }
 
+       for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
+               info->control.rates[i].idx = -1;
+               info->control.rates[i].flags = 0;
+               info->control.rates[i].count = 1;
+       }
+
        if (sta && sdata->force_unicast_rateidx > -1)
-               sel->rate_idx = sdata->force_unicast_rateidx;
+               info->control.rates[0].idx = sdata->force_unicast_rateidx;
        else
-               ref->ops->get_rate(ref->priv, sband, ista, priv_sta, 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);
-
-       /* Select a non-ERP backup rate. */
-       if (sel->nonerp_idx < 0) {
-               for (i = 0; i < sband->n_bitrates; i++) {
-                       struct ieee80211_rate *rate = &sband->bitrates[i];
-                       if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate)
-                               break;
-
-                       if (rate_supported(ista, sband->band, i) &&
-                           !(rate->flags & IEEE80211_RATE_ERP_G))
-                               sel->nonerp_idx = i;
-               }
+               ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
+
+       /*
+        * try to enforce the maximum rate the user wanted
+        */
+       if (sdata->max_ratectrl_rateidx > -1)
+               for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
+                       if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS)
+                               continue;
+                       info->control.rates[i].idx =
+                               min_t(s8, info->control.rates[i].idx,
+                                     sdata->max_ratectrl_rateidx);
        }
+
+       BUG_ON(info->control.rates[0].idx < 0);
 }
 
 struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)
index d0092f847f82775eb19c457874dfc911a12d4795..928da625e281557ccecc0f1923def7b9bfa72415 100644 (file)
@@ -31,9 +31,8 @@ struct rate_control_ref {
 struct rate_control_ref *rate_control_alloc(const char *name,
                                            struct ieee80211_local *local);
 void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
-                          struct ieee80211_supported_band *sband,
-                          struct sta_info *sta, struct sk_buff *skb,
-                          struct rate_selection *sel);
+                          struct sta_info *sta,
+                          struct ieee80211_tx_rate_control *txrc);
 struct rate_control_ref *rate_control_get(struct rate_control_ref *ref);
 void rate_control_put(struct rate_control_ref *ref);
 
@@ -64,12 +63,6 @@ static inline void rate_control_rate_init(struct sta_info *sta)
 }
 
 
-static inline void rate_control_clear(struct ieee80211_local *local)
-{
-       struct rate_control_ref *ref = local->rate_ctrl;
-       ref->ops->clear(ref->priv);
-}
-
 static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
                                           struct ieee80211_sta *sta,
                                           gfp_t gfp)
index f6d69dab07a3eba384bfa91baed0e9b4f3a5f287..2b3b490a6073467755e3b83998d1480398864148 100644 (file)
@@ -126,7 +126,9 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
                        mr->adjusted_retry_count = mr->retry_count >> 1;
                        if (mr->adjusted_retry_count > 2)
                                mr->adjusted_retry_count = 2;
+                       mr->sample_limit = 4;
                } else {
+                       mr->sample_limit = -1;
                        mr->adjusted_retry_count = mr->retry_count;
                }
                if (!mr->adjusted_retry_count)
@@ -169,30 +171,20 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
 {
        struct minstrel_sta_info *mi = priv_sta;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_tx_altrate *ar = info->status.retries;
-       struct minstrel_priv *mp = priv;
-       int i, ndx, tries;
-       int success = 0;
-
-       if (!info->status.excessive_retries)
-               success = 1;
+       struct ieee80211_tx_rate *ar = info->status.rates;
+       int i, ndx;
+       int success;
 
-       if (!mp->has_mrr || (ar[0].rate_idx < 0)) {
-               ndx = rix_to_ndx(mi, info->tx_rate_idx);
-               tries = info->status.retry_count + 1;
-               mi->r[ndx].success += success;
-               mi->r[ndx].attempts += tries;
-               return;
-       }
+       success = !!(info->flags & IEEE80211_TX_STAT_ACK);
 
-       for (i = 0; i < 4; i++) {
-               if (ar[i].rate_idx < 0)
+       for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
+               if (ar[i].idx < 0)
                        break;
 
-               ndx = rix_to_ndx(mi, ar[i].rate_idx);
-               mi->r[ndx].attempts += ar[i].limit + 1;
+               ndx = rix_to_ndx(mi, ar[i].idx);
+               mi->r[ndx].attempts += ar[i].count;
 
-               if ((i != 3) && (ar[i + 1].rate_idx < 0))
+               if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0))
                        mi->r[ndx].success += success;
        }
 
@@ -210,9 +202,9 @@ minstrel_get_retry_count(struct minstrel_rate *mr,
 {
        unsigned int retry = mr->adjusted_retry_count;
 
-       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
+       if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
                retry = max(2U, min(mr->retry_count_rtscts, retry));
-       else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
+       else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
                retry = max(2U, min(mr->retry_count_cts, retry));
        return retry;
 }
@@ -233,15 +225,16 @@ minstrel_get_next_sample(struct minstrel_sta_info *mi)
        return sample_ndx;
 }
 
-void
-minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband,
-                  struct ieee80211_sta *sta, void *priv_sta,
-                  struct sk_buff *skb, struct rate_selection *sel)
+static void
+minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
+                 void *priv_sta, struct ieee80211_tx_rate_control *txrc)
 {
+       struct sk_buff *skb = txrc->skb;
+       struct ieee80211_supported_band *sband = txrc->sband;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct minstrel_sta_info *mi = priv_sta;
        struct minstrel_priv *mp = priv;
-       struct ieee80211_tx_altrate *ar = info->control.retries;
+       struct ieee80211_tx_rate *ar = info->control.rates;
        unsigned int ndx, sample_ndx = 0;
        bool mrr;
        bool sample_slower = false;
@@ -251,16 +244,12 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband,
        int sample_rate;
 
        if (!sta || !mi || use_low_rate(skb)) {
-               sel->rate_idx = rate_lowest_index(sband, sta);
+               ar[0].idx = rate_lowest_index(sband, sta);
+               ar[0].count = mp->max_retry;
                return;
        }
 
-       mrr = mp->has_mrr;
-
-       /* mac80211 does not allow mrr for RTS/CTS */
-       if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
-           (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT))
-               mrr = false;
+       mrr = mp->has_mrr && !txrc->rts && !txrc->bss_conf->use_cts_prot;
 
        if (time_after(jiffies, mi->stats_update + (mp->update_interval *
                        HZ) / 1000))
@@ -278,7 +267,8 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband,
                        (mi->sample_count + mi->sample_deferred / 2);
 
        /* delta > 0: sampling required */
-       if (delta > 0) {
+       if ((delta > 0) && (mrr || !mi->prev_sample)) {
+               struct minstrel_rate *msr;
                if (mi->packet_count >= 10000) {
                        mi->sample_deferred = 0;
                        mi->sample_count = 0;
@@ -297,13 +287,20 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband,
                }
 
                sample_ndx = minstrel_get_next_sample(mi);
+               msr = &mi->r[sample_ndx];
                sample = true;
-               sample_slower = mrr && (mi->r[sample_ndx].perfect_tx_time >
+               sample_slower = mrr && (msr->perfect_tx_time >
                        mi->r[ndx].perfect_tx_time);
 
                if (!sample_slower) {
-                       ndx = sample_ndx;
-                       mi->sample_count++;
+                       if (msr->sample_limit != 0) {
+                               ndx = sample_ndx;
+                               mi->sample_count++;
+                               if (msr->sample_limit > 0)
+                                       msr->sample_limit--;
+                       } else {
+                               sample = false;
+                       }
                } else {
                        /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark
                         * packets that have the sampling rate deferred to the
@@ -315,13 +312,22 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband,
                        mi->sample_deferred++;
                }
        }
-       sel->rate_idx = mi->r[ndx].rix;
-       info->control.retry_limit = minstrel_get_retry_count(&mi->r[ndx], info);
+       mi->prev_sample = sample;
+
+       /* If we're not using MRR and the sampling rate already
+        * has a probability of >95%, we shouldn't be attempting
+        * to use it, as this only wastes precious airtime */
+       if (!mrr && sample && (mi->r[ndx].probability > 17100))
+               ndx = mi->max_tp_rate;
+
+       ar[0].idx = mi->r[ndx].rix;
+       ar[0].count = minstrel_get_retry_count(&mi->r[ndx], info);
 
        if (!mrr) {
-               ar[0].rate_idx = mi->lowest_rix;
-               ar[0].limit = mp->max_retry;
-               ar[1].rate_idx = -1;
+               if (!sample)
+                       ar[0].count = mp->max_retry;
+               ar[1].idx = mi->lowest_rix;
+               ar[1].count = mp->max_retry;
                return;
        }
 
@@ -336,9 +342,9 @@ minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband,
        }
        mrr_ndx[1] = mi->max_prob_rate;
        mrr_ndx[2] = 0;
-       for (i = 0; i < 3; i++) {
-               ar[i].rate_idx = mi->r[mrr_ndx[i]].rix;
-               ar[i].limit = mi->r[mrr_ndx[i]].adjusted_retry_count;
+       for (i = 1; i < 4; i++) {
+               ar[i].idx = mi->r[mrr_ndx[i - 1]].rix;
+               ar[i].count = mi->r[mrr_ndx[i - 1]].adjusted_retry_count;
        }
 }
 
@@ -415,6 +421,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
 
                /* calculate maximum number of retransmissions before
                 * fallback (based on maximum segment size) */
+               mr->sample_limit = -1;
                mr->retry_count = 1;
                mr->retry_count_cts = 1;
                mr->retry_count_rtscts = 1;
@@ -500,11 +507,6 @@ minstrel_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta)
        kfree(mi);
 }
 
-static void
-minstrel_clear(void *priv)
-{
-}
-
 static void *
 minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
 {
@@ -532,13 +534,13 @@ minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
        /* maximum time that the hw is allowed to stay in one MRR segment */
        mp->segment_size = 6000;
 
-       if (hw->max_altrate_tries > 0)
-               mp->max_retry = hw->max_altrate_tries;
+       if (hw->max_rate_tries > 0)
+               mp->max_retry = hw->max_rate_tries;
        else
                /* safe default, does not necessarily have to match hw properties */
                mp->max_retry = 7;
 
-       if (hw->max_altrates >= 3)
+       if (hw->max_rates >= 4)
                mp->has_mrr = true;
 
        mp->hw = hw;
@@ -558,7 +560,6 @@ static struct rate_control_ops mac80211_minstrel = {
        .tx_status = minstrel_tx_status,
        .get_rate = minstrel_get_rate,
        .rate_init = minstrel_rate_init,
-       .clear = minstrel_clear,
        .alloc = minstrel_alloc,
        .free = minstrel_free,
        .alloc_sta = minstrel_alloc_sta,
index 9a90a6aee043fbd0aac5469a89a9981c91d4ab0b..869fe0ef951d176a6bf3b5592a3d6e9191a9e8b8 100644 (file)
@@ -16,6 +16,7 @@ struct minstrel_rate {
        unsigned int perfect_tx_time;
        unsigned int ack_time;
 
+       int sample_limit;
        unsigned int retry_count;
        unsigned int retry_count_cts;
        unsigned int retry_count_rtscts;
@@ -57,6 +58,7 @@ struct minstrel_sta_info {
 
        int n_rates;
        struct minstrel_rate *r;
+       bool prev_sample;
 
        /* sampling table */
        u8 *sample_table;
index 01d64d53f3b9351ead2458fcebf2b1b5301a1f4b..1a873f00691acca56edd1b7c954b9e2f4cde0eb9 100644 (file)
@@ -49,7 +49,7 @@
 
 /* Arithmetic right shift for positive and negative values for ISO C. */
 #define RC_PID_DO_ARITH_RIGHT_SHIFT(x, y) \
-       (x) < 0 ? -((-(x)) >> (y)) : (x) >> (y)
+       ((x) < 0 ? -((-(x)) >> (y)) : (x) >> (y))
 
 enum rc_pid_event_type {
        RC_PID_EVENT_TYPE_TX_STATUS,
@@ -61,6 +61,7 @@ enum rc_pid_event_type {
 union rc_pid_event_data {
        /* RC_PID_EVENT_TX_STATUS */
        struct {
+               u32 flags;
                struct ieee80211_tx_info tx_status;
        };
        /* RC_PID_EVENT_TYPE_RATE_CHANGE */
index 86eb374e3b87f22338b4697552e0283f897db8aa..2328ba56803915ad12e9364bb6d1b93a53d6907b 100644 (file)
@@ -241,7 +241,7 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba
 
        /* 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)
+       if (info->status.rates[0].idx != spinfo->txrate_idx)
                return;
 
        spinfo->tx_num_xmit++;
@@ -253,10 +253,10 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba
        /* We count frames that totally failed to be transmitted as two bad
         * frames, those that made it out but had some retries as one good and
         * one bad frame. */
-       if (info->status.excessive_retries) {
+       if (!(info->flags & IEEE80211_TX_STAT_ACK)) {
                spinfo->tx_num_failed += 2;
                spinfo->tx_num_xmit++;
-       } else if (info->status.retry_count) {
+       } else if (info->status.rates[0].count) {
                spinfo->tx_num_failed++;
                spinfo->tx_num_xmit++;
        }
@@ -270,23 +270,32 @@ static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_ba
 }
 
 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)
+rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
+                         void *priv_sta,
+                         struct ieee80211_tx_rate_control *txrc)
 {
+       struct sk_buff *skb = txrc->skb;
+       struct ieee80211_supported_band *sband = txrc->sband;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct rc_pid_sta_info *spinfo = priv_sta;
        int rateidx;
        u16 fc;
 
+       if (txrc->rts)
+               info->control.rates[0].count =
+                       txrc->hw->conf.long_frame_max_tx_count;
+       else
+               info->control.rates[0].count =
+                       txrc->hw->conf.short_frame_max_tx_count;
+
        /* Send management frames and broadcast/multicast data using lowest
         * rate. */
        fc = le16_to_cpu(hdr->frame_control);
        if (!sta || !spinfo ||
            (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
            is_multicast_ether_addr(hdr->addr1)) {
-               sel->rate_idx = rate_lowest_index(sband, sta);
+               info->control.rates[0].idx = rate_lowest_index(sband, sta);
                return;
        }
 
@@ -295,7 +304,7 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_supported_band *sband,
        if (rateidx >= sband->n_bitrates)
                rateidx = sband->n_bitrates - 1;
 
-       sel->rate_idx = rateidx;
+       info->control.rates[0].idx = rateidx;
 
 #ifdef CONFIG_MAC80211_DEBUGFS
        rate_control_pid_event_tx_rate(&spinfo->events,
@@ -437,10 +446,6 @@ static void rate_control_pid_free(void *priv)
        kfree(pinfo);
 }
 
-static void rate_control_pid_clear(void *priv)
-{
-}
-
 static void *rate_control_pid_alloc_sta(void *priv, struct ieee80211_sta *sta,
                                        gfp_t gfp)
 {
@@ -471,7 +476,6 @@ static struct rate_control_ops mac80211_rcpid = {
        .tx_status = rate_control_pid_tx_status,
        .get_rate = rate_control_pid_get_rate,
        .rate_init = rate_control_pid_rate_init,
-       .clear = rate_control_pid_clear,
        .alloc = rate_control_pid_alloc,
        .free = rate_control_pid_free,
        .alloc_sta = rate_control_pid_alloc_sta,
index 8121d3bc683585e22443f7621a90697d73edddbe..a08a9b5303474bc304b9f119b31cc4938dfa9acb 100644 (file)
@@ -43,6 +43,7 @@ void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
 {
        union rc_pid_event_data evd;
 
+       evd.flags = stat->flags;
        memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_info));
        rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd);
 }
@@ -167,8 +168,8 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf,
        switch (ev->type) {
        case RC_PID_EVENT_TYPE_TX_STATUS:
                p += snprintf(pb + p, length - p, "tx_status %u %u",
-                             ev->data.tx_status.status.excessive_retries,
-                             ev->data.tx_status.status.retry_count);
+                             !(ev->data.flags & IEEE80211_TX_STAT_ACK),
+                             ev->data.tx_status.status.rates[0].idx);
                break;
        case RC_PID_EVENT_TYPE_RATE_CHANGE:
                p += snprintf(pb + p, length - p, "rate_change %d %d",
index cf6b121e1bbf58407608132c24b613c2cbd34129..648a1d0e6c82ab9dbbddc6d23d9125a6daf634c6 100644 (file)
 #include "tkip.h"
 #include "wme.h"
 
-u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
-                               struct tid_ampdu_rx *tid_agg_rx,
-                               struct sk_buff *skb, u16 mpdu_seq_num,
-                               int bar_req);
+static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
+                                          struct tid_ampdu_rx *tid_agg_rx,
+                                          struct sk_buff *skb,
+                                          u16 mpdu_seq_num,
+                                          int bar_req);
 /*
  * monitor mode reception
  *
@@ -653,13 +654,12 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
 static void ap_sta_ps_start(struct sta_info *sta)
 {
        struct ieee80211_sub_if_data *sdata = sta->sdata;
-       DECLARE_MAC_BUF(mac);
 
        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",
-              sdata->dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid);
+       printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n",
+              sdata->dev->name, sta->sta.addr, sta->sta.aid);
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
 }
 
@@ -669,8 +669,6 @@ static int ap_sta_ps_end(struct sta_info *sta)
        struct ieee80211_local *local = sdata->local;
        struct sk_buff *skb;
        int sent = 0;
-       struct ieee80211_tx_info *info;
-       DECLARE_MAC_BUF(mac);
 
        atomic_dec(&sdata->bss->num_sta_ps);
 
@@ -680,27 +678,25 @@ static int ap_sta_ps_end(struct sta_info *sta)
                sta_info_clear_tim_bit(sta);
 
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
-       printk(KERN_DEBUG "%s: STA %s aid %d exits power save mode\n",
-              sdata->dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid);
+       printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n",
+              sdata->dev->name, sta->sta.addr, sta->sta.aid);
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
 
        /* Send all buffered frames to the station */
        while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) {
-               info = IEEE80211_SKB_CB(skb);
                sent++;
-               info->flags |= IEEE80211_TX_CTL_REQUEUE;
+               skb->requeue = 1;
                dev_queue_xmit(skb);
        }
        while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) {
-               info = IEEE80211_SKB_CB(skb);
                local->total_ps_buffered--;
                sent++;
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
-               printk(KERN_DEBUG "%s: STA %s aid %d send PS frame "
+               printk(KERN_DEBUG "%s: STA %pM aid %d send PS frame "
                       "since STA not sleeping anymore\n", sdata->dev->name,
-                      print_mac(mac, sta->sta.addr), sta->sta.aid);
+                      sta->sta.addr, sta->sta.aid);
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
-               info->flags |= IEEE80211_TX_CTL_REQUEUE;
+               skb->requeue = 1;
                dev_queue_xmit(skb);
        }
 
@@ -789,15 +785,12 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata,
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
                struct ieee80211_hdr *hdr =
                        (struct ieee80211_hdr *) entry->skb_list.next->data;
-               DECLARE_MAC_BUF(mac);
-               DECLARE_MAC_BUF(mac2);
                printk(KERN_DEBUG "%s: RX reassembly removed oldest "
                       "fragment entry (idx=%d age=%lu seq=%d last_frag=%d "
-                      "addr1=%s addr2=%s\n",
+                      "addr1=%pM addr2=%pM\n",
                       sdata->dev->name, idx,
                       jiffies - entry->first_frag_time, entry->seq,
-                      entry->last_frag, print_mac(mac, hdr->addr1),
-                      print_mac(mac2, hdr->addr2));
+                      entry->last_frag, hdr->addr1, hdr->addr2);
 #endif
                __skb_queue_purge(&entry->skb_list);
        }
@@ -866,7 +859,6 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
        unsigned int frag, seq;
        struct ieee80211_fragment_entry *entry;
        struct sk_buff *skb;
-       DECLARE_MAC_BUF(mac);
 
        hdr = (struct ieee80211_hdr *)rx->skb->data;
        fc = hdr->frame_control;
@@ -970,7 +962,6 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
        struct sk_buff *skb;
        int no_pending_pkts;
-       DECLARE_MAC_BUF(mac);
        __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control;
 
        if (likely(!rx->sta || !ieee80211_is_pspoll(fc) ||
@@ -1001,8 +992,8 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
                set_sta_flags(rx->sta, WLAN_STA_PSPOLL);
 
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
-               printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n",
-                      print_mac(mac, rx->sta->sta.addr), rx->sta->sta.aid,
+               printk(KERN_DEBUG "STA %pM aid %d: PS Poll (entries after %d)\n",
+                      rx->sta->sta.addr, rx->sta->sta.aid,
                       skb_queue_len(&rx->sta->ps_tx_buf));
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
 
@@ -1025,9 +1016,9 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
                 *        Should we send it a null-func frame indicating we
                 *        have nothing buffered for it?
                 */
-               printk(KERN_DEBUG "%s: STA %s sent PS Poll even "
+               printk(KERN_DEBUG "%s: STA %pM sent PS Poll even "
                       "though there are no buffered frames for it\n",
-                      rx->dev->name, print_mac(mac, rx->sta->sta.addr));
+                      rx->dev->name, rx->sta->sta.addr);
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
        }
 
@@ -1097,10 +1088,6 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
        u8 src[ETH_ALEN] __aligned(2);
        struct sk_buff *skb = rx->skb;
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       DECLARE_MAC_BUF(mac);
-       DECLARE_MAC_BUF(mac2);
-       DECLARE_MAC_BUF(mac3);
-       DECLARE_MAC_BUF(mac4);
 
        if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
                return -1;
@@ -1279,7 +1266,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
        int remaining, err;
        u8 dst[ETH_ALEN];
        u8 src[ETH_ALEN];
-       DECLARE_MAC_BUF(mac);
 
        if (unlikely(!ieee80211_is_data(fc)))
                return RX_CONTINUE;
@@ -1552,14 +1538,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
        if (len < IEEE80211_MIN_ACTION_SIZE + 1)
                return RX_DROP_MONITOR;
 
-       /*
-        * FIXME: revisit this, I'm sure we should handle most
-        *        of these frames in other modes as well!
-        */
-       if (sdata->vif.type != NL80211_IFTYPE_STATION &&
-           sdata->vif.type != NL80211_IFTYPE_ADHOC)
-               return RX_CONTINUE;
-
        switch (mgmt->u.action.category) {
        case WLAN_CATEGORY_BACK:
                switch (mgmt->u.action.u.addba_req.action_code) {
@@ -1632,8 +1610,6 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
 {
        int keyidx;
        unsigned int hdrlen;
-       DECLARE_MAC_BUF(mac);
-       DECLARE_MAC_BUF(mac2);
 
        hdrlen = ieee80211_hdrlen(hdr->frame_control);
        if (rx->skb->len >= hdrlen + 4)
@@ -2002,17 +1978,17 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 
 static inline int seq_less(u16 sq1, u16 sq2)
 {
-       return (((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1));
+       return ((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1);
 }
 
 static inline u16 seq_inc(u16 sq)
 {
-       return ((sq + 1) & SEQ_MASK);
+       return (sq + 1) & SEQ_MASK;
 }
 
 static inline u16 seq_sub(u16 sq1, u16 sq2)
 {
-       return ((sq1 - sq2) & SEQ_MASK);
+       return (sq1 - sq2) & SEQ_MASK;
 }
 
 
@@ -2020,10 +1996,11 @@ static inline u16 seq_sub(u16 sq1, u16 sq2)
  * As it function blongs to Rx path it must be called with
  * the proper rcu_read_lock protection for its flow.
  */
-u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
-                               struct tid_ampdu_rx *tid_agg_rx,
-                               struct sk_buff *skb, u16 mpdu_seq_num,
-                               int bar_req)
+static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
+                                          struct tid_ampdu_rx *tid_agg_rx,
+                                          struct sk_buff *skb,
+                                          u16 mpdu_seq_num,
+                                          int bar_req)
 {
        struct ieee80211_local *local = hw_to_local(hw);
        struct ieee80211_rx_status status;
index 416bb41099f361159d0bc578533d08a371a7de03..f5c7c3371929a5c41651bcbefa45771149b5c2d4 100644 (file)
@@ -159,7 +159,7 @@ ieee80211_rx_mesh_bss_add(struct ieee80211_local *local, u8 *mesh_id, int mesh_i
 {
        struct ieee80211_bss *bss;
 
-       if (mesh_config_len != MESH_CFG_LEN)
+       if (mesh_config_len != IEEE80211_MESH_CONFIG_LEN)
                return NULL;
 
        bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
@@ -448,18 +448,17 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
 
        if (local->hw_scanning) {
                local->hw_scanning = false;
-               if (ieee80211_hw_config(local))
-                       printk(KERN_DEBUG "%s: failed to restore operational "
-                              "channel after scan\n", wiphy_name(local->hw.wiphy));
-
+               /*
+                * Somebody might have requested channel change during scan
+                * that we won't have acted upon, try now. ieee80211_hw_config
+                * will set the flag based on actual changes.
+                */
+               ieee80211_hw_config(local, 0);
                goto done;
        }
 
        local->sw_scanning = false;
-       if (ieee80211_hw_config(local))
-               printk(KERN_DEBUG "%s: failed to restore operational "
-                      "channel after scan\n", wiphy_name(local->hw.wiphy));
-
+       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 
        netif_tx_lock_bh(local->mdev);
        netif_addr_lock(local->mdev);
@@ -546,12 +545,9 @@ void ieee80211_scan_work(struct work_struct *work)
 
                if (!skip) {
                        local->scan_channel = chan;
-                       if (ieee80211_hw_config(local)) {
-                               printk(KERN_DEBUG "%s: failed to set freq to "
-                                      "%d MHz for scan\n", wiphy_name(local->hw.wiphy),
-                                      chan->center_freq);
+                       if (ieee80211_hw_config(local,
+                                               IEEE80211_CONF_CHANGE_CHANNEL))
                                skip = 1;
-                       }
                }
 
                /* advance state machine to next channel/band */
index 7fef8ea1f5ecf53eaf5b1596479ef1d8a834b348..b22110a4a75e4b8d8f36efaf9dc43daaa93ad4a9 100644 (file)
@@ -137,14 +137,12 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx,
 static void __sta_info_free(struct ieee80211_local *local,
                            struct sta_info *sta)
 {
-       DECLARE_MAC_BUF(mbuf);
-
        rate_control_free_sta(sta);
        rate_control_put(sta->rate_ctrl);
 
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-       printk(KERN_DEBUG "%s: Destroyed STA %s\n",
-              wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->sta.addr));
+       printk(KERN_DEBUG "%s: Destroyed STA %pM\n",
+              wiphy_name(local->hw.wiphy), sta->sta.addr);
 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
 
        kfree(sta);
@@ -222,7 +220,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
        int i;
-       DECLARE_MAC_BUF(mbuf);
 
        sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp);
        if (!sta)
@@ -263,8 +260,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
        skb_queue_head_init(&sta->tx_filtered);
 
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-       printk(KERN_DEBUG "%s: Allocated STA %s\n",
-              wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->sta.addr));
+       printk(KERN_DEBUG "%s: Allocated STA %pM\n",
+              wiphy_name(local->hw.wiphy), sta->sta.addr);
 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
 
 #ifdef CONFIG_MAC80211_MESH
@@ -281,7 +278,6 @@ int sta_info_insert(struct sta_info *sta)
        struct ieee80211_sub_if_data *sdata = sta->sdata;
        unsigned long flags;
        int err = 0;
-       DECLARE_MAC_BUF(mac);
 
        /*
         * Can't be a WARN_ON because it can be triggered through a race:
@@ -294,7 +290,7 @@ int sta_info_insert(struct sta_info *sta)
        }
 
        if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->dev->dev_addr) == 0 ||
-                   is_multicast_ether_addr(sta->sta.addr))) {
+                   is_multicast_ether_addr(sta->sta.addr))) {
                err = -EINVAL;
                goto out_free;
        }
@@ -322,8 +318,8 @@ int sta_info_insert(struct sta_info *sta)
        }
 
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-       printk(KERN_DEBUG "%s: Inserted STA %s\n",
-              wiphy_name(local->hw.wiphy), print_mac(mac, sta->sta.addr));
+       printk(KERN_DEBUG "%s: Inserted STA %pM\n",
+              wiphy_name(local->hw.wiphy), sta->sta.addr);
 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
 
        spin_unlock_irqrestore(&local->sta_lock, flags);
@@ -423,9 +419,6 @@ static void __sta_info_unlink(struct sta_info **sta)
 {
        struct ieee80211_local *local = (*sta)->local;
        struct ieee80211_sub_if_data *sdata = (*sta)->sdata;
-#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-       DECLARE_MAC_BUF(mbuf);
-#endif
        /*
         * pull caller's reference if we're already gone.
         */
@@ -468,8 +461,8 @@ static void __sta_info_unlink(struct sta_info **sta)
        }
 
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-       printk(KERN_DEBUG "%s: Removed STA %s\n",
-              wiphy_name(local->hw.wiphy), print_mac(mbuf, (*sta)->sta.addr));
+       printk(KERN_DEBUG "%s: Removed STA %pM\n",
+              wiphy_name(local->hw.wiphy), (*sta)->sta.addr);
 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
 
        /*
@@ -544,7 +537,6 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
        unsigned long flags;
        struct sk_buff *skb;
        struct ieee80211_sub_if_data *sdata;
-       DECLARE_MAC_BUF(mac);
 
        if (skb_queue_empty(&sta->ps_tx_buf))
                return;
@@ -564,8 +556,8 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
                sdata = sta->sdata;
                local->total_ps_buffered--;
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
-               printk(KERN_DEBUG "Buffered frame expired (STA "
-                      "%s)\n", print_mac(mac, sta->sta.addr));
+               printk(KERN_DEBUG "Buffered frame expired (STA %pM)\n",
+                      sta->sta.addr);
 #endif
                dev_kfree_skb(skb);
 
@@ -809,15 +801,14 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta, *tmp;
        LIST_HEAD(tmp_list);
-       DECLARE_MAC_BUF(mac);
        unsigned long flags;
 
        spin_lock_irqsave(&local->sta_lock, flags);
        list_for_each_entry_safe(sta, tmp, &local->sta_list, list)
                if (time_after(jiffies, sta->last_rx + exp_time)) {
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
-                       printk(KERN_DEBUG "%s: expiring inactive STA %s\n",
-                              sdata->dev->name, print_mac(mac, sta->sta.addr));
+                       printk(KERN_DEBUG "%s: expiring inactive STA %pM\n",
+                              sdata->dev->name, sta->sta.addr);
 #endif
                        __sta_info_unlink(&sta);
                        if (sta)
@@ -830,7 +821,7 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
 }
 
 struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw,
-                                         const u8 *addr)
+                                        const u8 *addr)
 {
        struct sta_info *sta = sta_info_get(hw_to_local(hw), addr);
 
index 168a39a298bdc1f754de9ad1d0ac04f311466d33..5ad9250b63abb0340b58827c5b60454108d9f6e1 100644 (file)
@@ -160,18 +160,20 @@ struct sta_ampdu_mlme {
  * @list: global linked list entry
  * @hnext: hash table linked list pointer
  * @local: pointer to the global information
- * @sdata: TBD
- * @key: TBD
- * @rate_ctrl: TBD
- * @rate_ctrl_priv: TBD
+ * @sdata: virtual interface this station belongs to
+ * @key: peer key negotiated with this station, if any
+ * @rate_ctrl: rate control algorithm reference
+ * @rate_ctrl_priv: rate control private per-STA pointer
+ * @last_tx_rate: rate used for last transmit, to report to userspace as
+ *     "the" transmit rate
  * @lock: used for locking all fields that require locking, see comments
  *     in the header file.
  * @flaglock: spinlock for flags accesses
  * @addr: MAC address of this STA
  * @aid: STA's unique AID (1..2007, 0 = not assigned yet),
  *     only used in AP (and IBSS?) mode
- * @listen_interval: TBD
- * @pin_status: TBD
+ * @listen_interval: listen interval of this station, when we're acting as AP
+ * @pin_status: used internally for pinning a STA struct into memory
  * @flags: STA flags, see &enum ieee80211_sta_info_flags
  * @ps_tx_buf: buffer of frames to transmit to this station
  *     when it leaves power saving state
@@ -180,8 +182,8 @@ struct sta_ampdu_mlme {
  *     power saving state
  * @rx_packets: Number of MSDUs received from this STA
  * @rx_bytes: Number of bytes received from this STA
- * @wep_weak_iv_count: TBD
- * @last_rx: TBD
+ * @wep_weak_iv_count: number of weak WEP IVs received from this station
+ * @last_rx: time (in jiffies) when last frame was received from this STA
  * @num_duplicates: number of duplicate frames received from this STA
  * @rx_fragments: number of received MPDUs
  * @rx_dropped: number of dropped MPDUs from this STA
@@ -189,26 +191,26 @@ 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)
- * @tx_filtered_count: TBD
- * @tx_retry_failed: TBD
- * @tx_retry_count: TBD
+ * @tx_filtered_count: number of frames the hardware filtered for this STA
+ * @tx_retry_failed: number of frames that failed retry
+ * @tx_retry_count: total number of retries for frames to this STA
  * @fail_avg: moving percentage of failed MSDUs
  * @tx_packets: number of RX/TX MSDUs
- * @tx_bytes: TBD
+ * @tx_bytes: number of bytes transmitted to this STA
  * @tx_fragments: number of transmitted MPDUs
- * @last_txrate_idx: Index of the last used transmit rate
- * @tid_seq: TBD
- * @ampdu_mlme: TBD
+ * @last_txrate: description of the last used transmit rate
+ * @tid_seq: per-TID sequence numbers for sending to this STA
+ * @ampdu_mlme: A-MPDU state machine state
  * @timer_to_tid: identity mapping to ID timers
  * @tid_to_tx_q: map tid to tx queue
  * @llid: Local link ID
  * @plid: Peer link ID
  * @reason: Cancel reason on PLINK_HOLDING state
  * @plink_retries: Retries in establishment
- * @ignore_plink_timer: TBD
- * @plink_state plink_state: TBD
- * @plink_timeout: TBD
- * @plink_timer: TBD
+ * @ignore_plink_timer: ignore the peer-link timer (used internally)
+ * @plink_state: peer link state
+ * @plink_timeout: timeout of peer link
+ * @plink_timer: peer link watch timer
  * @debugfs: debug filesystem info
  * @sta: station information we share with the driver
  */
@@ -267,7 +269,7 @@ struct sta_info {
        unsigned long tx_packets;
        unsigned long tx_bytes;
        unsigned long tx_fragments;
-       unsigned int last_txrate_idx;
+       struct ieee80211_tx_rate last_tx_rate;
        u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
 
        /*
index 34b32bc8f609d84d5a2fb0473d1be05e0f553930..38fa111d2dc6fff3720fd2990777ff75adc75b37 100644 (file)
@@ -263,10 +263,9 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
             (iv32 == key->u.tkip.rx[queue].iv32 &&
              iv16 <= key->u.tkip.rx[queue].iv16))) {
 #ifdef CONFIG_MAC80211_TKIP_DEBUG
-               DECLARE_MAC_BUF(mac);
                printk(KERN_DEBUG "TKIP replay detected for RX frame from "
-                      "%s (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n",
-                      print_mac(mac, ta),
+                      "%pM (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n",
+                      ta,
                       iv32, iv16, key->u.tkip.rx[queue].iv32,
                       key->u.tkip.rx[queue].iv16);
 #endif
@@ -287,9 +286,8 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
                {
                        int i;
                        u8 key_offset = NL80211_TKIP_DATA_OFFSET_ENCR_KEY;
-                       DECLARE_MAC_BUF(mac);
-                       printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=%s"
-                              " TK=", print_mac(mac, ta));
+                       printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=%pM"
+                              " TK=", ta);
                        for (i = 0; i < 16; i++)
                                printk("%02x ",
                                       key->conf.key[key_offset + i]);
index 1460537faf3335c64824ddd61704a212a43655de..0d81b2cfd1a6d7cbcca80a1d1b3a31dbbdc0ba26 100644 (file)
@@ -46,13 +46,20 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
        struct ieee80211_local *local = tx->local;
        struct ieee80211_supported_band *sband;
        struct ieee80211_hdr *hdr;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
+
+       /* assume HW handles this */
+       if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS)
+               return 0;
+
+       /* uh huh? */
+       if (WARN_ON_ONCE(info->control.rates[0].idx < 0))
+               return 0;
 
        sband = local->hw.wiphy->bands[tx->channel->band];
-       txrate = &sband->bitrates[tx->rate_idx];
+       txrate = &sband->bitrates[info->control.rates[0].idx];
 
-       erp = 0;
-       if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
-               erp = txrate->flags & IEEE80211_RATE_ERP_G;
+       erp = txrate->flags & IEEE80211_RATE_ERP_G;
 
        /*
         * data and mgmt (except PS Poll):
@@ -116,7 +123,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
                if (r->bitrate > txrate->bitrate)
                        break;
 
-               if (tx->sdata->bss_conf.basic_rates & BIT(i))
+               if (tx->sdata->vif.bss_conf.basic_rates & BIT(i))
                        rate = r->bitrate;
 
                switch (sband->band) {
@@ -150,7 +157,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
         * to closest integer */
 
        dur = ieee80211_frame_duration(local, 10, rate, erp,
-                               tx->sdata->bss_conf.use_short_preamble);
+                               tx->sdata->vif.bss_conf.use_short_preamble);
 
        if (next_frag_len) {
                /* Frame is fragmented: duration increases with time needed to
@@ -159,7 +166,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
                /* next fragment */
                dur += ieee80211_frame_duration(local, next_frag_len,
                                txrate->bitrate, erp,
-                               tx->sdata->bss_conf.use_short_preamble);
+                               tx->sdata->vif.bss_conf.use_short_preamble);
        }
 
        return cpu_to_le16(dur);
@@ -201,10 +208,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
                             tx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
                             ieee80211_is_data(hdr->frame_control))) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-                       DECLARE_MAC_BUF(mac);
                        printk(KERN_DEBUG "%s: dropped data frame to not "
-                              "associated station %s\n",
-                              tx->dev->name, print_mac(mac, hdr->addr1));
+                              "associated station %pM\n",
+                              tx->dev->name, hdr->addr1);
 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
                        I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc);
                        return TX_DROP;
@@ -331,7 +337,6 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
        u32 staflags;
-       DECLARE_MAC_BUF(mac);
 
        if (unlikely(!sta || ieee80211_is_probe_resp(hdr->frame_control)))
                return TX_CONTINUE;
@@ -341,9 +346,9 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
        if (unlikely((staflags & WLAN_STA_PS) &&
                     !(staflags & WLAN_STA_PSPOLL))) {
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
-               printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries "
+               printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries "
                       "before %d)\n",
-                      print_mac(mac, sta->sta.addr), sta->sta.aid,
+                      sta->sta.addr, sta->sta.aid,
                       skb_queue_len(&sta->ps_tx_buf));
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
                if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
@@ -352,9 +357,9 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
                        struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf);
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
                        if (net_ratelimit()) {
-                               printk(KERN_DEBUG "%s: STA %s TX "
+                               printk(KERN_DEBUG "%s: STA %pM TX "
                                       "buffer full - dropping oldest frame\n",
-                                      tx->dev->name, print_mac(mac, sta->sta.addr));
+                                      tx->dev->name, sta->sta.addr);
                        }
 #endif
                        dev_kfree_skb(old);
@@ -371,9 +376,9 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
        }
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
        else if (unlikely(test_sta_flags(sta, WLAN_STA_PS))) {
-               printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll "
+               printk(KERN_DEBUG "%s: STA %pM in PS mode, but pspoll "
                       "set -> send frame\n", tx->dev->name,
-                      print_mac(mac, sta->sta.addr));
+                      sta->sta.addr);
        }
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
        clear_sta_flags(sta, WLAN_STA_PSPOLL);
@@ -439,140 +444,154 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
 static ieee80211_tx_result debug_noinline
 ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
 {
-       struct rate_selection rsel;
-       struct ieee80211_supported_band *sband;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
+       struct ieee80211_hdr *hdr = (void *)tx->skb->data;
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_rate *rate;
+       int i, len;
+       bool inval = false, rts = false, short_preamble = false;
+       struct ieee80211_tx_rate_control txrc;
 
-       sband = tx->local->hw.wiphy->bands[tx->channel->band];
+       memset(&txrc, 0, sizeof(txrc));
 
-       if (likely(tx->rate_idx < 0)) {
-               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;
-               if (unlikely(rsel.probe_idx >= 0)) {
-                       info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
-                       tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG;
-                       info->control.retries[0].rate_idx = tx->rate_idx;
-                       info->control.retries[0].limit = tx->local->hw.max_altrate_tries;
-                       tx->rate_idx = rsel.probe_idx;
-               } else if (info->control.retries[0].limit == 0)
-                       info->control.retries[0].rate_idx = -1;
-
-               if (unlikely(tx->rate_idx < 0))
-                       return TX_DROP;
-       } else
-               info->control.retries[0].rate_idx = -1;
+       sband = tx->local->hw.wiphy->bands[tx->channel->band];
 
-       if (tx->sdata->bss_conf.use_cts_prot &&
-           (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) {
-               tx->last_frag_rate_idx = tx->rate_idx;
-               if (rsel.probe_idx >= 0)
-                       tx->flags &= ~IEEE80211_TX_PROBE_LAST_FRAG;
-               else
-                       tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG;
-               tx->rate_idx = rsel.nonerp_idx;
-               info->tx_rate_idx = rsel.nonerp_idx;
-               info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE;
-       } else {
-               tx->last_frag_rate_idx = tx->rate_idx;
-               info->tx_rate_idx = tx->rate_idx;
+       len = min_t(int, tx->skb->len + FCS_LEN,
+                        tx->local->fragmentation_threshold);
+
+       /* set up the tx rate control struct we give the RC algo */
+       txrc.hw = local_to_hw(tx->local);
+       txrc.sband = sband;
+       txrc.bss_conf = &tx->sdata->vif.bss_conf;
+       txrc.skb = tx->skb;
+       txrc.reported_rate.idx = -1;
+       txrc.max_rate_idx = tx->sdata->max_ratectrl_rateidx;
+
+       /* set up RTS protection if desired */
+       if (tx->local->rts_threshold < IEEE80211_MAX_RTS_THRESHOLD &&
+           len > tx->local->rts_threshold) {
+               txrc.rts = rts = true;
        }
-       info->tx_rate_idx = tx->rate_idx;
 
-       return TX_CONTINUE;
-}
+       /*
+        * Use short preamble if the BSS can handle it, but not for
+        * management frames unless we know the receiver can handle
+        * that -- the management frame might be to a station that
+        * just wants a probe response.
+        */
+       if (tx->sdata->vif.bss_conf.use_short_preamble &&
+           (ieee80211_is_data(hdr->frame_control) ||
+            (tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))))
+               txrc.short_preamble = short_preamble = true;
 
-static ieee80211_tx_result debug_noinline
-ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
-{
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
-       struct ieee80211_supported_band *sband;
 
-       sband = tx->local->hw.wiphy->bands[tx->channel->band];
+       rate_control_get_rate(tx->sdata, tx->sta, &txrc);
+
+       if (unlikely(info->control.rates[0].idx < 0))
+               return TX_DROP;
+
+       if (txrc.reported_rate.idx < 0)
+               txrc.reported_rate = info->control.rates[0];
 
        if (tx->sta)
-               info->control.sta = &tx->sta->sta;
+               tx->sta->last_tx_rate = txrc.reported_rate;
 
-       if (!info->control.retry_limit) {
-               if (!is_multicast_ether_addr(hdr->addr1)) {
-                       int len = min_t(int, tx->skb->len + FCS_LEN,
-                                       tx->local->fragmentation_threshold);
-                       if (len > tx->local->rts_threshold
-                           && tx->local->rts_threshold <
-                                               IEEE80211_MAX_RTS_THRESHOLD) {
-                               info->flags |= IEEE80211_TX_CTL_USE_RTS_CTS;
-                               info->flags |=
-                                       IEEE80211_TX_CTL_LONG_RETRY_LIMIT;
-                               info->control.retry_limit =
-                                       tx->local->long_retry_limit;
-                       } else {
-                               info->control.retry_limit =
-                                       tx->local->short_retry_limit;
-                       }
-               } else {
-                       info->control.retry_limit = 1;
-               }
-       }
+       if (unlikely(!info->control.rates[0].count))
+               info->control.rates[0].count = 1;
 
-       if (tx->flags & IEEE80211_TX_FRAGMENTED) {
-               /* Do not use multiple retry rates when sending fragmented
-                * frames.
-                * TODO: The last fragment could still use multiple retry
-                * rates. */
-               info->control.retries[0].rate_idx = -1;
+       if (is_multicast_ether_addr(hdr->addr1)) {
+               /*
+                * XXX: verify the rate is in the basic rateset
+                */
+               return TX_CONTINUE;
        }
 
-       /* Use CTS protection for unicast frames sent using extended rates if
-        * there are associated non-ERP stations and RTS/CTS is not configured
-        * for the frame. */
-       if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) &&
-           (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_ERP_G) &&
-           (tx->flags & IEEE80211_TX_UNICAST) &&
-           tx->sdata->bss_conf.use_cts_prot &&
-           !(info->flags & IEEE80211_TX_CTL_USE_RTS_CTS))
-               info->flags |= IEEE80211_TX_CTL_USE_CTS_PROTECT;
-
-       /* Transmit data frames using short preambles if the driver supports
-        * short preambles at the selected rate and short preambles are
-        * available on the network at the current point in time. */
-       if (ieee80211_is_data(hdr->frame_control) &&
-           (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
-           tx->sdata->bss_conf.use_short_preamble &&
-           (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) {
-               info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
+       /*
+        * set up the RTS/CTS rate as the fastest basic rate
+        * that is not faster than the data rate
+        *
+        * XXX: Should this check all retry rates?
+        */
+       if (!(info->control.rates[0].flags & IEEE80211_TX_RC_MCS)) {
+               s8 baserate = 0;
+
+               rate = &sband->bitrates[info->control.rates[0].idx];
+
+               for (i = 0; i < sband->n_bitrates; i++) {
+                       /* must be a basic rate */
+                       if (!(tx->sdata->vif.bss_conf.basic_rates & BIT(i)))
+                               continue;
+                       /* must not be faster than the data rate */
+                       if (sband->bitrates[i].bitrate > rate->bitrate)
+                               continue;
+                       /* maximum */
+                       if (sband->bitrates[baserate].bitrate <
+                            sband->bitrates[i].bitrate)
+                               baserate = i;
+               }
+
+               info->control.rts_cts_rate_idx = baserate;
        }
 
-       if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
-           (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) {
-               struct ieee80211_rate *rate;
-               s8 baserate = -1;
-               int idx;
+       for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
+               /*
+                * make sure there's no valid rate following
+                * an invalid one, just in case drivers don't
+                * take the API seriously to stop at -1.
+                */
+               if (inval) {
+                       info->control.rates[i].idx = -1;
+                       continue;
+               }
+               if (info->control.rates[i].idx < 0) {
+                       inval = true;
+                       continue;
+               }
 
-               /* Do not use multiple retry rates when using RTS/CTS */
-               info->control.retries[0].rate_idx = -1;
+               /*
+                * For now assume MCS is already set up correctly, this
+                * needs to be fixed.
+                */
+               if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS) {
+                       WARN_ON(info->control.rates[i].idx > 76);
+                       continue;
+               }
 
-               /* Use min(data rate, max base rate) as CTS/RTS rate */
-               rate = &sband->bitrates[tx->rate_idx];
+               /* set up RTS protection if desired */
+               if (rts)
+                       info->control.rates[i].flags |=
+                               IEEE80211_TX_RC_USE_RTS_CTS;
 
-               for (idx = 0; idx < sband->n_bitrates; idx++) {
-                       if (sband->bitrates[idx].bitrate > rate->bitrate)
-                               continue;
-                       if (tx->sdata->bss_conf.basic_rates & BIT(idx) &&
-                           (baserate < 0 ||
-                            (sband->bitrates[baserate].bitrate
-                             < sband->bitrates[idx].bitrate)))
-                               baserate = idx;
+               /* RC is busted */
+               if (WARN_ON_ONCE(info->control.rates[i].idx >=
+                                sband->n_bitrates)) {
+                       info->control.rates[i].idx = -1;
+                       continue;
                }
 
-               if (baserate >= 0)
-                       info->control.rts_cts_rate_idx = baserate;
-               else
-                       info->control.rts_cts_rate_idx = 0;
+               rate = &sband->bitrates[info->control.rates[i].idx];
+
+               /* set up short preamble */
+               if (short_preamble &&
+                   rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
+                       info->control.rates[i].flags |=
+                               IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
+
+               /* set up G protection */
+               if (!rts && tx->sdata->vif.bss_conf.use_cts_prot &&
+                   rate->flags & IEEE80211_RATE_ERP_G)
+                       info->control.rates[i].flags |=
+                               IEEE80211_TX_RC_USE_CTS_PROTECT;
        }
 
+       return TX_CONTINUE;
+}
+
+static ieee80211_tx_result debug_noinline
+ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
+{
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
+
        if (tx->sta)
                info->control.sta = &tx->sta->sta;
 
@@ -602,8 +621,18 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
        if (ieee80211_hdrlen(hdr->frame_control) < 24)
                return TX_CONTINUE;
 
+       /*
+        * Anything but QoS data that has a sequence number field
+        * (is long enough) gets a sequence number from the global
+        * counter.
+        */
        if (!ieee80211_is_data_qos(hdr->frame_control)) {
+               /* driver should assign sequence number */
                info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
+               /* for pure STA mode without beacons, we can do it */
+               hdr->seq_ctrl = cpu_to_le16(tx->sdata->sequence_number);
+               tx->sdata->sequence_number += 0x10;
+               tx->sdata->sequence_number &= IEEE80211_SCTL_SEQ;
                return TX_CONTINUE;
        }
 
@@ -632,6 +661,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
 static ieee80211_tx_result debug_noinline
 ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
 {
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
        size_t hdrlen, per_fragm, num_fragm, payload_len, left;
        struct sk_buff **frags, *first, *frag;
@@ -648,9 +678,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
         * This scenario is handled in __ieee80211_tx_prepare but extra
         * caution taken here as fragmented ampdu may cause Tx stop.
         */
-       if (WARN_ON(tx->flags & IEEE80211_TX_CTL_AMPDU ||
-                   skb_get_queue_mapping(tx->skb) >=
-                       ieee80211_num_regular_queues(&tx->local->hw)))
+       if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU))
                return TX_DROP;
 
        first = tx->skb;
@@ -684,20 +712,45 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
                                      IEEE80211_ENCRYPT_TAILROOM);
                if (!frag)
                        goto fail;
+
                /* Make sure that all fragments use the same priority so
                 * that they end up using the same TX queue */
                frag->priority = first->priority;
+
                skb_reserve(frag, tx->local->tx_headroom +
                                  IEEE80211_ENCRYPT_HEADROOM);
+
+               /* copy TX information */
+               info = IEEE80211_SKB_CB(frag);
+               memcpy(info, first->cb, sizeof(frag->cb));
+
+               /* copy/fill in 802.11 header */
                fhdr = (struct ieee80211_hdr *) skb_put(frag, hdrlen);
                memcpy(fhdr, first->data, hdrlen);
-               if (i == num_fragm - 2)
-                       fhdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREFRAGS);
                fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG));
+
+               if (i == num_fragm - 2) {
+                       /* clear MOREFRAGS bit for the last fragment */
+                       fhdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREFRAGS);
+               } else {
+                       /*
+                        * No multi-rate retries for fragmented frames, that
+                        * would completely throw off the NAV at other STAs.
+                        */
+                       info->control.rates[1].idx = -1;
+                       info->control.rates[2].idx = -1;
+                       info->control.rates[3].idx = -1;
+                       info->control.rates[4].idx = -1;
+                       BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5);
+                       info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE;
+               }
+
+               /* copy data */
                copylen = left > per_fragm ? per_fragm : left;
                memcpy(skb_put(frag, copylen), pos, copylen);
-               memcpy(frag->cb, first->cb, sizeof(frag->cb));
+
                skb_copy_queue_mapping(frag, first);
+
                frag->do_not_encrypt = first->do_not_encrypt;
 
                pos += copylen;
@@ -757,12 +810,10 @@ ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx)
                                              tx->extra_frag[0]->len);
 
        for (i = 0; i < tx->num_extra_frag; i++) {
-               if (i + 1 < tx->num_extra_frag) {
+               if (i + 1 < tx->num_extra_frag)
                        next_len = tx->extra_frag[i + 1]->len;
-               } else {
+               else
                        next_len = 0;
-                       tx->rate_idx = tx->last_frag_rate_idx;
-               }
 
                hdr = (struct ieee80211_hdr *)tx->extra_frag[i]->data;
                hdr->duration_id = ieee80211_duration(tx, 0, next_len);
@@ -815,7 +866,6 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
                (struct ieee80211_radiotap_header *) skb->data;
        struct ieee80211_supported_band *sband;
        int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len);
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
        sband = tx->local->hw.wiphy->bands[tx->channel->band];
 
@@ -829,8 +879,6 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
         */
 
        while (!ret) {
-               int i, target_rate;
-
                ret = ieee80211_radiotap_iterator_next(&iterator);
 
                if (ret)
@@ -844,38 +892,6 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
                 * get_unaligned((type *)iterator.this_arg) to dereference
                 * iterator.this_arg for type "type" safely on all arches.
                */
-               case IEEE80211_RADIOTAP_RATE:
-                       /*
-                        * radiotap rate u8 is in 500kbps units eg, 0x02=1Mbps
-                        * ieee80211 rate int is in 100kbps units eg, 0x0a=1Mbps
-                        */
-                       target_rate = (*iterator.this_arg) * 5;
-                       for (i = 0; i < sband->n_bitrates; i++) {
-                               struct ieee80211_rate *r;
-
-                               r = &sband->bitrates[i];
-
-                               if (r->bitrate == target_rate) {
-                                       tx->rate_idx = i;
-                                       break;
-                               }
-                       }
-                       break;
-
-               case IEEE80211_RADIOTAP_ANTENNA:
-                       /*
-                        * radiotap uses 0 for 1st ant, mac80211 is 1 for
-                        * 1st ant
-                        */
-                       info->antenna_sel_tx = (*iterator.this_arg) + 1;
-                       break;
-
-#if 0
-               case IEEE80211_RADIOTAP_DBM_TX_POWER:
-                       control->power_level = *iterator.this_arg;
-                       break;
-#endif
-
                case IEEE80211_RADIOTAP_FLAGS:
                        if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) {
                                /*
@@ -933,7 +949,8 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
-       int hdrlen;
+       int hdrlen, tid;
+       u8 *qc, *state;
 
        memset(tx, 0, sizeof(*tx));
        tx->skb = skb;
@@ -941,8 +958,6 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
        tx->local = local;
        tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        tx->channel = local->hw.conf.channel;
-       tx->rate_idx = -1;
-       tx->last_frag_rate_idx = -1;
        /*
         * Set this flag (used below to indicate "automatic fragmentation"),
         * it will be cleared/left by radiotap as desired.
@@ -966,6 +981,15 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
 
        tx->sta = sta_info_get(local, hdr->addr1);
 
+       if (tx->sta && ieee80211_is_data_qos(hdr->frame_control)) {
+               qc = ieee80211_get_qos_ctl(hdr);
+               tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
+
+               state = &tx->sta->ampdu_mlme.tid_state_tx[tid];
+               if (*state == HT_AGG_STATE_OPERATIONAL)
+                       info->flags |= IEEE80211_TX_CTL_AMPDU;
+       }
+
        if (is_multicast_ether_addr(hdr->addr1)) {
                tx->flags &= ~IEEE80211_TX_UNICAST;
                info->flags |= IEEE80211_TX_CTL_NO_ACK;
@@ -1043,23 +1067,11 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
                        if (!tx->extra_frag[i])
                                continue;
                        info = IEEE80211_SKB_CB(tx->extra_frag[i]);
-                       info->flags &= ~(IEEE80211_TX_CTL_USE_RTS_CTS |
-                                        IEEE80211_TX_CTL_USE_CTS_PROTECT |
-                                        IEEE80211_TX_CTL_CLEAR_PS_FILT |
+                       info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT |
                                         IEEE80211_TX_CTL_FIRST_FRAGMENT);
                        if (netif_subqueue_stopped(local->mdev,
                                                   tx->extra_frag[i]))
                                return IEEE80211_TX_FRAG_AGAIN;
-                       if (i == tx->num_extra_frag) {
-                               info->tx_rate_idx = tx->last_frag_rate_idx;
-
-                               if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG)
-                                       info->flags |=
-                                               IEEE80211_TX_CTL_RATE_CTRL_PROBE;
-                               else
-                                       info->flags &=
-                                               ~IEEE80211_TX_CTL_RATE_CTRL_PROBE;
-                       }
 
                        ret = local->ops->tx(local_to_hw(local),
                                            tx->extra_frag[i]);
@@ -1168,7 +1180,7 @@ retry:
                 * queues, there's no reason for a driver to reject
                 * a frame there, warn and drop it.
                 */
-               if (WARN_ON(queue >= ieee80211_num_regular_queues(&local->hw)))
+               if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU))
                        goto drop;
 
                store = &local->pending_packet[queue];
@@ -1196,9 +1208,6 @@ retry:
                store->skb = skb;
                store->extra_frag = tx.extra_frag;
                store->num_extra_frag = tx.num_extra_frag;
-               store->last_frag_rate_idx = tx.last_frag_rate_idx;
-               store->last_frag_rate_ctrl_probe =
-                       !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG);
        }
  out:
        rcu_read_unlock();
@@ -1593,12 +1602,10 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
                       compare_ether_addr(dev->dev_addr,
                                          skb->data + ETH_ALEN) == 0))) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-               DECLARE_MAC_BUF(mac);
-
                if (net_ratelimit())
-                       printk(KERN_DEBUG "%s: dropped frame to %s"
+                       printk(KERN_DEBUG "%s: dropped frame to %pM"
                               " (unauthorized port)\n", dev->name,
-                              print_mac(mac, hdr.addr1));
+                              hdr.addr1);
 #endif
 
                I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
@@ -1757,10 +1764,7 @@ void ieee80211_tx_pending(unsigned long data)
                store = &local->pending_packet[i];
                tx.extra_frag = store->extra_frag;
                tx.num_extra_frag = store->num_extra_frag;
-               tx.last_frag_rate_idx = store->last_frag_rate_idx;
                tx.flags = 0;
-               if (store->last_frag_rate_ctrl_probe)
-                       tx.flags |= IEEE80211_TX_PROBE_LAST_FRAG;
                ret = __ieee80211_tx(local, store->skb, &tx);
                if (ret) {
                        if (ret == IEEE80211_TX_FRAG_AGAIN)
@@ -1848,7 +1852,6 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
        struct ieee80211_sub_if_data *sdata = NULL;
        struct ieee80211_if_ap *ap = NULL;
        struct ieee80211_if_sta *ifsta = NULL;
-       struct rate_selection rsel;
        struct beacon_data *beacon;
        struct ieee80211_supported_band *sband;
        enum ieee80211_band band = local->hw.conf.channel->band;
@@ -1952,33 +1955,23 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
        skb->do_not_encrypt = 1;
 
        info->band = band;
-       rate_control_get_rate(sdata, sband, NULL, skb, &rsel);
-
-       if (unlikely(rsel.rate_idx < 0)) {
-               if (net_ratelimit()) {
-                       printk(KERN_DEBUG "%s: ieee80211_beacon_get: "
-                              "no rate found\n",
-                              wiphy_name(local->hw.wiphy));
-               }
-               dev_kfree_skb_any(skb);
-               skb = NULL;
-               goto out;
-       }
+       /*
+        * XXX: For now, always use the lowest rate
+        */
+       info->control.rates[0].idx = 0;
+       info->control.rates[0].count = 1;
+       info->control.rates[1].idx = -1;
+       info->control.rates[2].idx = -1;
+       info->control.rates[3].idx = -1;
+       info->control.rates[4].idx = -1;
+       BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5);
 
        info->control.vif = vif;
-       info->tx_rate_idx = rsel.rate_idx;
 
        info->flags |= IEEE80211_TX_CTL_NO_ACK;
        info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
        info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
-       if (sdata->bss_conf.use_short_preamble &&
-           sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE)
-               info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
-
-       info->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
-       info->control.retry_limit = 1;
-
-out:
+ out:
        rcu_read_unlock();
        return skb;
 }
index cee4884b9d06215f86b73630362fae1f9ab87168..0f841317c7e9ef25568e9cdca41dfe78f7bbb60b 100644 (file)
@@ -239,7 +239,7 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
        erp = 0;
        if (vif) {
                sdata = vif_to_sdata(vif);
-               short_preamble = sdata->bss_conf.use_short_preamble;
+               short_preamble = sdata->vif.bss_conf.use_short_preamble;
                if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
                        erp = rate->flags & IEEE80211_RATE_ERP_G;
        }
@@ -272,7 +272,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
        erp = 0;
        if (vif) {
                sdata = vif_to_sdata(vif);
-               short_preamble = sdata->bss_conf.use_short_preamble;
+               short_preamble = sdata->vif.bss_conf.use_short_preamble;
                if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
                        erp = rate->flags & IEEE80211_RATE_ERP_G;
        }
@@ -312,7 +312,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
        erp = 0;
        if (vif) {
                sdata = vif_to_sdata(vif);
-               short_preamble = sdata->bss_conf.use_short_preamble;
+               short_preamble = sdata->vif.bss_conf.use_short_preamble;
                if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
                        erp = rate->flags & IEEE80211_RATE_ERP_G;
        }
@@ -532,8 +532,8 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
                        if (elen >= sizeof(struct ieee80211_ht_cap))
                                elems->ht_cap_elem = (void *)pos;
                        break;
-               case WLAN_EID_HT_EXTRA_INFO:
-                       if (elen >= sizeof(struct ieee80211_ht_addt_info))
+               case WLAN_EID_HT_INFORMATION:
+                       if (elen >= sizeof(struct ieee80211_ht_info))
                                elems->ht_info_elem = (void *)pos;
                        break;
                case WLAN_EID_MESH_ID:
@@ -638,19 +638,15 @@ int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz)
 
        if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
                if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
-                   chan->flags & IEEE80211_CHAN_NO_IBSS) {
-                       printk(KERN_DEBUG "%s: IBSS not allowed on frequency "
-                               "%d MHz\n", sdata->dev->name, chan->center_freq);
+                   chan->flags & IEEE80211_CHAN_NO_IBSS)
                        return ret;
-               }
                local->oper_channel = chan;
 
                if (local->sw_scanning || local->hw_scanning)
                        ret = 0;
                else
-                       ret = ieee80211_hw_config(local);
-
-               rate_control_clear(local);
+                       ret = ieee80211_hw_config(
+                               local, IEEE80211_CONF_CHANGE_CHANNEL);
        }
 
        return ret;
index f0e2d3ecb5c49d5ca1ac6b8752c67bcf48a2350d..7bbb98e846a3f1e26014b2b04f6a78dec35966ed 100644 (file)
@@ -49,17 +49,19 @@ void ieee80211_wep_free(struct ieee80211_local *local)
        crypto_free_blkcipher(local->wep_rx_tfm);
 }
 
-static inline int ieee80211_wep_weak_iv(u32 iv, int keylen)
+static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen)
 {
-       /* Fluhrer, Mantin, and Shamir have reported weaknesses in the
+       /*
+        * Fluhrer, Mantin, and Shamir have reported weaknesses in the
         * key scheduling algorithm of RC4. At least IVs (KeyByte + 3,
-        * 0xff, N) can be used to speedup attacks, so avoid using them. */
+        * 0xff, N) can be used to speedup attacks, so avoid using them.
+        */
        if ((iv & 0xff00) == 0xff00) {
                u8 B = (iv >> 16) & 0xff;
                if (B >= 3 && B < 3 + keylen)
-                       return 1;
+                       return true;
        }
-       return 0;
+       return false;
 }
 
 
@@ -268,7 +270,7 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
 }
 
 
-u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)
+bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        unsigned int hdrlen;
@@ -276,16 +278,13 @@ u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)
        u32 iv;
 
        if (!ieee80211_has_protected(hdr->frame_control))
-               return NULL;
+               return false;
 
        hdrlen = ieee80211_hdrlen(hdr->frame_control);
        ivpos = skb->data + hdrlen;
        iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2];
 
-       if (ieee80211_wep_weak_iv(iv, key->conf.keylen))
-               return ivpos;
-
-       return NULL;
+       return ieee80211_wep_weak_iv(iv, key->conf.keylen);
 }
 
 ieee80211_rx_result
@@ -329,6 +328,8 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
 ieee80211_tx_result
 ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx)
 {
+       int i;
+
        ieee80211_tx_set_protected(tx);
 
        if (wep_encrypt_skb(tx, tx->skb) < 0) {
@@ -337,9 +338,8 @@ ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx)
        }
 
        if (tx->extra_frag) {
-               int i;
                for (i = 0; i < tx->num_extra_frag; i++) {
-                       if (wep_encrypt_skb(tx, tx->extra_frag[i]) < 0) {
+                       if (wep_encrypt_skb(tx, tx->extra_frag[i])) {
                                I802_DEBUG_INC(tx->local->
                                               tx_handlers_drop_wep);
                                return TX_DROP;
index e587172115b8397acc0ce4f92d401e5b288101a4..d3f0db48314e11f00fed332a046798dcaeff4913 100644 (file)
@@ -26,7 +26,7 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb,
                          struct ieee80211_key *key);
 int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
                          struct ieee80211_key *key);
-u8 *ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
+bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
 
 ieee80211_rx_result
 ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx);
index 742f811ca416e5b16701ce2ae49f582ed32317a6..63f36e9d1af8714f82ea8f6d9ba503ad5c9179d4 100644 (file)
@@ -147,7 +147,7 @@ static int ieee80211_ioctl_giwname(struct net_device *dev,
        sband = local->hw.wiphy->bands[IEEE80211_BAND_5GHZ];
        if (sband) {
                is_a = 1;
-               is_ht |= sband->ht_info.ht_supported;
+               is_ht |= sband->ht_cap.ht_supported;
        }
 
        sband = local->hw.wiphy->bands[IEEE80211_BAND_2GHZ];
@@ -160,7 +160,7 @@ static int ieee80211_ioctl_giwname(struct net_device *dev,
                        if (sband->bitrates[i].bitrate == 60)
                                is_g = 1;
                }
-               is_ht |= sband->ht_info.ht_supported;
+               is_ht |= sband->ht_cap.ht_supported;
        }
 
        strcpy(name, "IEEE 802.11");
@@ -407,13 +407,6 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
                return 0;
        }
 
-       if (sdata->vif.type == NL80211_IFTYPE_AP) {
-               memcpy(sdata->u.ap.ssid, ssid, len);
-               memset(sdata->u.ap.ssid + len, 0,
-                      IEEE80211_MAX_SSID_LEN - len);
-               sdata->u.ap.ssid_len = len;
-               return ieee80211_if_config(sdata, IEEE80211_IFCC_SSID);
-       }
        return -EOPNOTSUPP;
 }
 
@@ -437,15 +430,6 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
                return res;
        }
 
-       if (sdata->vif.type == NL80211_IFTYPE_AP) {
-               len = sdata->u.ap.ssid_len;
-               if (len > IW_ESSID_MAX_SIZE)
-                       len = IW_ESSID_MAX_SIZE;
-               memcpy(ssid, sdata->u.ap.ssid, len);
-               data->length = len;
-               data->flags = 1;
-               return 0;
-       }
        return -EOPNOTSUPP;
 }
 
@@ -636,8 +620,8 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev,
 
        sta = sta_info_get(local, sdata->u.sta.bssid);
 
-       if (sta && sta->last_txrate_idx < sband->n_bitrates)
-               rate->value = sband->bitrates[sta->last_txrate_idx].bitrate;
+       if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS))
+               rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate;
        else
                rate->value = 0;
 
@@ -656,45 +640,35 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev,
                                      union iwreq_data *data, char *extra)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       bool need_reconfig = 0;
+       struct ieee80211_channel* chan = local->hw.conf.channel;
+       u32 reconf_flags = 0;
        int new_power_level;
 
        if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
                return -EINVAL;
        if (data->txpower.flags & IW_TXPOW_RANGE)
                return -EINVAL;
+       if (!chan)
+               return -EINVAL;
 
-       if (data->txpower.fixed) {
-               new_power_level = data->txpower.value;
-       } else {
-               /*
-                * Automatic power level. Use maximum power for the current
-                * channel. Should be part of rate control.
-                */
-               struct ieee80211_channel* chan = local->hw.conf.channel;
-               if (!chan)
-                       return -EINVAL;
-
+       if (data->txpower.fixed)
+               new_power_level = min(data->txpower.value, chan->max_power);
+       else /* Automatic power level setting */
                new_power_level = chan->max_power;
-       }
 
        if (local->hw.conf.power_level != new_power_level) {
                local->hw.conf.power_level = new_power_level;
-               need_reconfig = 1;
+               reconf_flags |= IEEE80211_CONF_CHANGE_POWER;
        }
 
        if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) {
                local->hw.conf.radio_enabled = !(data->txpower.disabled);
-               need_reconfig = 1;
+               reconf_flags |= IEEE80211_CONF_CHANGE_RADIO_ENABLED;
                ieee80211_led_radio(local, local->hw.conf.radio_enabled);
        }
 
-       if (need_reconfig) {
-               ieee80211_hw_config(local);
-               /* The return value of hw_config is not of big interest here,
-                * as it doesn't say that it failed because of _this_ config
-                * change or something else. Ignore it. */
-       }
+       if (reconf_flags)
+               ieee80211_hw_config(local, reconf_flags);
 
        return 0;
 }
@@ -806,21 +780,16 @@ static int ieee80211_ioctl_siwretry(struct net_device *dev,
            (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
                return -EINVAL;
 
-       if (retry->flags & IW_RETRY_MAX)
-               local->long_retry_limit = retry->value;
-       else if (retry->flags & IW_RETRY_MIN)
-               local->short_retry_limit = retry->value;
-       else {
-               local->long_retry_limit = retry->value;
-               local->short_retry_limit = retry->value;
+       if (retry->flags & IW_RETRY_MAX) {
+               local->hw.conf.long_frame_max_tx_count = retry->value;
+       } else if (retry->flags & IW_RETRY_MIN) {
+               local->hw.conf.short_frame_max_tx_count = retry->value;
+       else {
+               local->hw.conf.long_frame_max_tx_count = retry->value;
+               local->hw.conf.short_frame_max_tx_count = retry->value;
        }
 
-       if (local->ops->set_retry_limit) {
-               return local->ops->set_retry_limit(
-                       local_to_hw(local),
-                       local->short_retry_limit,
-                       local->long_retry_limit);
-       }
+       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
 
        return 0;
 }
@@ -837,14 +806,15 @@ static int ieee80211_ioctl_giwretry(struct net_device *dev,
                /* first return min value, iwconfig will ask max value
                 * later if needed */
                retry->flags |= IW_RETRY_LIMIT;
-               retry->value = local->short_retry_limit;
-               if (local->long_retry_limit != local->short_retry_limit)
+               retry->value = local->hw.conf.short_frame_max_tx_count;
+               if (local->hw.conf.long_frame_max_tx_count !=
+                   local->hw.conf.short_frame_max_tx_count)
                        retry->flags |= IW_RETRY_MIN;
                return 0;
        }
        if (retry->flags & IW_RETRY_MAX) {
                retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
-               retry->value = local->long_retry_limit;
+               retry->value = local->hw.conf.long_frame_max_tx_count;
        }
 
        return 0;
@@ -980,7 +950,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
 
        if (wrq->disabled) {
                conf->flags &= ~IEEE80211_CONF_PS;
-               return ieee80211_hw_config(local);
+               return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
        }
 
        switch (wrq->flags & IW_POWER_MODE) {
@@ -993,7 +963,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
                return -EINVAL;
        }
 
-       return ieee80211_hw_config(local);
+       return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
 }
 
 static int ieee80211_ioctl_giwpower(struct net_device *dev,
index 139b5f267b34b4e38d2925996936ab7f389061a9..ac71b38f7cb5cb217180bb2cef3bcfa4b6540b40 100644 (file)
@@ -114,8 +114,8 @@ 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_hw *hw = &local->hw;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct sta_info *sta;
        u16 queue;
        u8 tid;
@@ -124,21 +124,19 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb)
        if (unlikely(queue >= local->hw.queues))
                queue = local->hw.queues - 1;
 
-       if (info->flags & IEEE80211_TX_CTL_REQUEUE) {
+       if (skb->requeue) {
+               if (!hw->ampdu_queues)
+                       return queue;
+
                rcu_read_lock();
                sta = sta_info_get(local, hdr->addr1);
                tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
                if (sta) {
-                       struct ieee80211_hw *hw = &local->hw;
                        int ampdu_queue = sta->tid_to_tx_q[tid];
 
                        if ((ampdu_queue < ieee80211_num_queues(hw)) &&
-                           test_bit(ampdu_queue, local->queue_pool)) {
+                           test_bit(ampdu_queue, local->queue_pool))
                                queue = ampdu_queue;
-                               info->flags |= IEEE80211_TX_CTL_AMPDU;
-                       } else {
-                               info->flags &= ~IEEE80211_TX_CTL_AMPDU;
-                       }
                }
                rcu_read_unlock();
 
@@ -159,20 +157,18 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb)
                *p++ = ack_policy | tid;
                *p = 0;
 
+               if (!hw->ampdu_queues)
+                       return queue;
+
                rcu_read_lock();
 
                sta = sta_info_get(local, hdr->addr1);
                if (sta) {
                        int ampdu_queue = sta->tid_to_tx_q[tid];
-                       struct ieee80211_hw *hw = &local->hw;
 
                        if ((ampdu_queue < ieee80211_num_queues(hw)) &&
-                           test_bit(ampdu_queue, local->queue_pool)) {
+                           test_bit(ampdu_queue, local->queue_pool))
                                queue = ampdu_queue;
-                               info->flags |= IEEE80211_TX_CTL_AMPDU;
-                       } else {
-                               info->flags &= ~IEEE80211_TX_CTL_AMPDU;
-                       }
                }
 
                rcu_read_unlock();
@@ -206,13 +202,11 @@ int ieee80211_ht_agg_queue_add(struct ieee80211_local *local,
                         * on the previous queue
                         * since HT is strict in order */
 #ifdef CONFIG_MAC80211_HT_DEBUG
-                       if (net_ratelimit()) {
-                               DECLARE_MAC_BUF(mac);
+                       if (net_ratelimit())
                                printk(KERN_DEBUG "allocated aggregation queue"
-                                       " %d tid %d addr %s pool=0x%lX\n",
-                                       i, tid, print_mac(mac, sta->sta.addr),
+                                       " %d tid %d addr %pM pool=0x%lX\n",
+                                       i, tid, sta->sta.addr,
                                        local->queue_pool[0]);
-                       }
 #endif /* CONFIG_MAC80211_HT_DEBUG */
                        return 0;
                }
index 6db649480e8ff2ae1aa8369be77c2e1e7220b562..7aa63caf8d50c3c7c8b2b87b77b9a3515fd5a4ca 100644 (file)
@@ -49,8 +49,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
            !(tx->flags & IEEE80211_TX_FRAGMENTED) &&
            !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) &&
            !wpa_test) {
-               /* hwaccel - with no need for preallocated room for Michael MIC
-                */
+               /* hwaccel - with no need for preallocated room for MMIC */
                return TX_CONTINUE;
        }
 
@@ -67,8 +66,6 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
 #else
        authenticator = 1;
 #endif
-       /* At this point we know we're using ALG_TKIP. To get the MIC key
-        * we now will rely on the offset from the ieee80211_key_conf::key */
        key_offset = authenticator ?
                NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY :
                NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
@@ -90,11 +87,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
        u8 mic[MICHAEL_MIC_LEN];
        struct sk_buff *skb = rx->skb;
        int authenticator = 1, wpa_test = 0;
-       DECLARE_MAC_BUF(mac);
 
-       /*
-        * No way to verify the MIC if the hardware stripped it
-        */
+       /* No way to verify the MIC if the hardware stripped it */
        if (rx->status->flag & RX_FLAG_MMIC_STRIPPED)
                return RX_CONTINUE;
 
@@ -116,8 +110,6 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
 #else
        authenticator = 1;
 #endif
-       /* At this point we know we're using ALG_TKIP. To get the MIC key
-        * we now will rely on the offset from the ieee80211_key_conf::key */
        key_offset = authenticator ?
                NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY :
                NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
@@ -202,6 +194,7 @@ ieee80211_tx_result
 ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx)
 {
        struct sk_buff *skb = tx->skb;
+       int i;
 
        ieee80211_tx_set_protected(tx);
 
@@ -209,9 +202,8 @@ ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx)
                return TX_DROP;
 
        if (tx->extra_frag) {
-               int i;
                for (i = 0; i < tx->num_extra_frag; i++) {
-                       if (tkip_encrypt_skb(tx, tx->extra_frag[i]) < 0)
+                       if (tkip_encrypt_skb(tx, tx->extra_frag[i]))
                                return TX_DROP;
                }
        }
@@ -227,7 +219,6 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
        int hdrlen, res, hwaccel = 0, wpa_test = 0;
        struct ieee80211_key *key = rx->key;
        struct sk_buff *skb = rx->skb;
-       DECLARE_MAC_BUF(mac);
 
        hdrlen = ieee80211_hdrlen(hdr->frame_control);
 
@@ -350,7 +341,7 @@ static inline void ccmp_pn2hdr(u8 *hdr, u8 *pn, int key_id)
 }
 
 
-static inline int ccmp_hdr2pn(u8 *pn, u8 *hdr)
+static inline void ccmp_hdr2pn(u8 *pn, u8 *hdr)
 {
        pn[0] = hdr[7];
        pn[1] = hdr[6];
@@ -358,7 +349,6 @@ static inline int ccmp_hdr2pn(u8 *pn, u8 *hdr)
        pn[3] = hdr[4];
        pn[4] = hdr[1];
        pn[5] = hdr[0];
-       return (hdr[3] >> 6) & 0x03;
 }
 
 
@@ -373,7 +363,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
 
        if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
            !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
-               /* hwaccel - with no need for preallocated room for CCMP "
+               /* hwaccel - with no need for preallocated room for CCMP
                 * header or MIC fields */
                info->control.hw_key = &tx->key->conf;
                return 0;
@@ -426,6 +416,7 @@ ieee80211_tx_result
 ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx)
 {
        struct sk_buff *skb = tx->skb;
+       int i;
 
        ieee80211_tx_set_protected(tx);
 
@@ -433,9 +424,8 @@ ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx)
                return TX_DROP;
 
        if (tx->extra_frag) {
-               int i;
                for (i = 0; i < tx->num_extra_frag; i++) {
-                       if (ccmp_encrypt_skb(tx, tx->extra_frag[i]) < 0)
+                       if (ccmp_encrypt_skb(tx, tx->extra_frag[i]))
                                return TX_DROP;
                }
        }
@@ -453,7 +443,6 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
        struct sk_buff *skb = rx->skb;
        u8 pn[CCMP_PN_LEN];
        int data_len;
-       DECLARE_MAC_BUF(mac);
 
        hdrlen = ieee80211_hdrlen(hdr->frame_control);
 
@@ -468,7 +457,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
            (rx->status->flag & RX_FLAG_IV_STRIPPED))
                return RX_CONTINUE;
 
-       (void) ccmp_hdr2pn(pn, skb->data + hdrlen);
+       ccmp_hdr2pn(pn, skb->data + hdrlen);
 
        if (memcmp(pn, key->u.ccmp.rx_pn[rx->queue], CCMP_PN_LEN) <= 0) {
                key->u.ccmp.replays++;
@@ -483,9 +472,8 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
                            key->u.ccmp.tfm, key->u.ccmp.rx_crypto_buf,
                            skb->data + hdrlen + CCMP_HDR_LEN, data_len,
                            skb->data + skb->len - CCMP_MIC_LEN,
-                           skb->data + hdrlen + CCMP_HDR_LEN)) {
+                           skb->data + hdrlen + CCMP_HDR_LEN))
                        return RX_DROP_UNUSABLE;
-               }
        }
 
        memcpy(key->u.ccmp.rx_pn[rx->queue], pn, CCMP_PN_LEN);
index 9a24332fbed878ec43c54a7db45dee81108a9be2..60aba45023ff7e9d687d356c1aaf4edfebde7e2d 100644 (file)
@@ -820,13 +820,11 @@ static int ip_vs_conn_seq_show(struct seq_file *seq, void *v)
 
 #ifdef CONFIG_IP_VS_IPV6
                if (cp->af == AF_INET6)
-                       seq_printf(seq,
-                               "%-3s " NIP6_FMT " %04X " NIP6_FMT
-                               " %04X " NIP6_FMT " %04X %-11s %7lu\n",
+                       seq_printf(seq, "%-3s %pI6 %04X %pI6 %04X %pI6 %04X %-11s %7lu\n",
                                ip_vs_proto_name(cp->protocol),
-                               NIP6(cp->caddr.in6), ntohs(cp->cport),
-                               NIP6(cp->vaddr.in6), ntohs(cp->vport),
-                               NIP6(cp->daddr.in6), ntohs(cp->dport),
+                               &cp->caddr.in6, ntohs(cp->cport),
+                               &cp->vaddr.in6, ntohs(cp->vport),
+                               &cp->daddr.in6, ntohs(cp->dport),
                                ip_vs_state_name(cp->protocol, cp->state),
                                (cp->timer.expires-jiffies)/HZ);
                else
@@ -883,13 +881,11 @@ static int ip_vs_conn_sync_seq_show(struct seq_file *seq, void *v)
 
 #ifdef CONFIG_IP_VS_IPV6
                if (cp->af == AF_INET6)
-                       seq_printf(seq,
-                               "%-3s " NIP6_FMT " %04X " NIP6_FMT
-                               " %04X " NIP6_FMT " %04X %-11s %-6s %7lu\n",
+                       seq_printf(seq, "%-3s %pI6 %04X %pI6 %04X %pI6 %04X %-11s %-6s %7lu\n",
                                ip_vs_proto_name(cp->protocol),
-                               NIP6(cp->caddr.in6), ntohs(cp->cport),
-                               NIP6(cp->vaddr.in6), ntohs(cp->vport),
-                               NIP6(cp->daddr.in6), ntohs(cp->dport),
+                               &cp->caddr.in6, ntohs(cp->cport),
+                               &cp->vaddr.in6, ntohs(cp->vport),
+                               &cp->daddr.in6, ntohs(cp->dport),
                                ip_vs_state_name(cp->protocol, cp->state),
                                ip_vs_origin_name(cp->flags),
                                (cp->timer.expires-jiffies)/HZ);
index 958abf3e5f8cd3baceb46fedb6ec4b2f0cd4a15e..cb3e031335ebc4af9a95e5a359c10c3805c8754d 100644 (file)
@@ -730,9 +730,9 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related)
        if (ic == NULL)
                return NF_DROP;
 
-       IP_VS_DBG(12, "Outgoing ICMP (%d,%d) %u.%u.%u.%u->%u.%u.%u.%u\n",
+       IP_VS_DBG(12, "Outgoing ICMP (%d,%d) %pI4->%pI4\n",
                  ic->type, ntohs(icmp_id(ic)),
-                 NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
+                 &iph->saddr, &iph->daddr);
 
        /*
         * Work through seeing if this is for us.
@@ -805,9 +805,9 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related)
        if (ic == NULL)
                return NF_DROP;
 
-       IP_VS_DBG(12, "Outgoing ICMPv6 (%d,%d) " NIP6_FMT "->" NIP6_FMT "\n",
+       IP_VS_DBG(12, "Outgoing ICMPv6 (%d,%d) %pI6->%pI6\n",
                  ic->icmp6_type, ntohs(icmpv6_id(ic)),
-                 NIP6(iph->saddr), NIP6(iph->daddr));
+                 &iph->saddr, &iph->daddr);
 
        /*
         * Work through seeing if this is for us.
@@ -1070,9 +1070,9 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
        if (ic == NULL)
                return NF_DROP;
 
-       IP_VS_DBG(12, "Incoming ICMP (%d,%d) %u.%u.%u.%u->%u.%u.%u.%u\n",
+       IP_VS_DBG(12, "Incoming ICMP (%d,%d) %pI4->%pI4\n",
                  ic->type, ntohs(icmp_id(ic)),
-                 NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
+                 &iph->saddr, &iph->daddr);
 
        /*
         * Work through seeing if this is for us.
@@ -1127,8 +1127,8 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
        /* Ensure the checksum is correct */
        if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
                /* Failed checksum! */
-               IP_VS_DBG(1, "Incoming ICMP: failed checksum from %d.%d.%d.%d!\n",
-                         NIPQUAD(iph->saddr));
+               IP_VS_DBG(1, "Incoming ICMP: failed checksum from %pI4!\n",
+                         &iph->saddr);
                goto out;
        }
 
@@ -1175,9 +1175,9 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
        if (ic == NULL)
                return NF_DROP;
 
-       IP_VS_DBG(12, "Incoming ICMPv6 (%d,%d) " NIP6_FMT "->" NIP6_FMT "\n",
+       IP_VS_DBG(12, "Incoming ICMPv6 (%d,%d) %pI6->%pI6\n",
                  ic->icmp6_type, ntohs(icmpv6_id(ic)),
-                 NIP6(iph->saddr), NIP6(iph->daddr));
+                 &iph->saddr, &iph->daddr);
 
        /*
         * Work through seeing if this is for us.
index 0302cf3e503968f5a4a2b8a89b3828b536e71871..e01061f49cdc644b0fe99d48457795458f55aa91 100644 (file)
@@ -1168,15 +1168,9 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u,
        }
 
 #ifdef CONFIG_IP_VS_IPV6
-       if (u->af == AF_INET6) {
-               if (!sched->supports_ipv6) {
-                       ret = -EAFNOSUPPORT;
-                       goto out_err;
-               }
-               if ((u->netmask < 1) || (u->netmask > 128)) {
-                       ret = -EINVAL;
-                       goto out_err;
-               }
+       if (u->af == AF_INET6 && (u->netmask < 1 || u->netmask > 128)) {
+               ret = -EINVAL;
+               goto out_err;
        }
 #endif
 
@@ -1272,15 +1266,9 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u)
        old_sched = sched;
 
 #ifdef CONFIG_IP_VS_IPV6
-       if (u->af == AF_INET6) {
-               if (!sched->supports_ipv6) {
-                       ret = -EAFNOSUPPORT;
-                       goto out;
-               }
-               if ((u->netmask < 1) || (u->netmask > 128)) {
-                       ret = -EINVAL;
-                       goto out;
-               }
+       if (u->af == AF_INET6 && (u->netmask < 1 || u->netmask > 128)) {
+               ret = -EINVAL;
+               goto out;
        }
 #endif
 
@@ -1557,7 +1545,7 @@ static struct ctl_table vs_vars[] = {
                .data           = &sysctl_ip_vs_amemthresh,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
 #ifdef CONFIG_IP_VS_DEBUG
        {
@@ -1565,7 +1553,7 @@ static struct ctl_table vs_vars[] = {
                .data           = &sysctl_ip_vs_debug_level,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
 #endif
        {
@@ -1573,28 +1561,28 @@ static struct ctl_table vs_vars[] = {
                .data           = &sysctl_ip_vs_am_droprate,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .procname       = "drop_entry",
                .data           = &sysctl_ip_vs_drop_entry,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_do_defense_mode,
+               .proc_handler   = proc_do_defense_mode,
        },
        {
                .procname       = "drop_packet",
                .data           = &sysctl_ip_vs_drop_packet,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_do_defense_mode,
+               .proc_handler   = proc_do_defense_mode,
        },
        {
                .procname       = "secure_tcp",
                .data           = &sysctl_ip_vs_secure_tcp,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_do_defense_mode,
+               .proc_handler   = proc_do_defense_mode,
        },
 #if 0
        {
@@ -1602,84 +1590,84 @@ static struct ctl_table vs_vars[] = {
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_ESTABLISHED],
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "timeout_synsent",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_SYN_SENT],
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "timeout_synrecv",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_SYN_RECV],
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "timeout_finwait",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_FIN_WAIT],
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "timeout_timewait",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_TIME_WAIT],
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "timeout_close",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_CLOSE],
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "timeout_closewait",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_CLOSE_WAIT],
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "timeout_lastack",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_LAST_ACK],
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "timeout_listen",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_LISTEN],
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "timeout_synack",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_SYNACK],
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "timeout_udp",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_UDP],
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "timeout_icmp",
                .data   = &vs_timeout_table_dos.timeout[IP_VS_S_ICMP],
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
 #endif
        {
@@ -1687,35 +1675,35 @@ static struct ctl_table vs_vars[] = {
                .data           = &sysctl_ip_vs_cache_bypass,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .procname       = "expire_nodest_conn",
                .data           = &sysctl_ip_vs_expire_nodest_conn,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .procname       = "expire_quiescent_template",
                .data           = &sysctl_ip_vs_expire_quiescent_template,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .procname       = "sync_threshold",
                .data           = &sysctl_ip_vs_sync_threshold,
                .maxlen         = sizeof(sysctl_ip_vs_sync_threshold),
                .mode           = 0644,
-               .proc_handler   = &proc_do_sync_threshold,
+               .proc_handler   = proc_do_sync_threshold,
        },
        {
                .procname       = "nat_icmp_send",
                .data           = &sysctl_ip_vs_nat_icmp_send,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        { .ctl_name = 0 }
 };
@@ -1867,9 +1855,9 @@ static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
                if (iter->table == ip_vs_svc_table) {
 #ifdef CONFIG_IP_VS_IPV6
                        if (svc->af == AF_INET6)
-                               seq_printf(seq, "%s  [" NIP6_FMT "]:%04X %s ",
+                               seq_printf(seq, "%s  [%pI6]:%04X %s ",
                                           ip_vs_proto_name(svc->protocol),
-                                          NIP6(svc->addr.in6),
+                                          &svc->addr.in6,
                                           ntohs(svc->port),
                                           svc->scheduler->name);
                        else
@@ -1895,9 +1883,9 @@ static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
 #ifdef CONFIG_IP_VS_IPV6
                        if (dest->af == AF_INET6)
                                seq_printf(seq,
-                                          "  -> [" NIP6_FMT "]:%04X"
+                                          "  -> [%pI6]:%04X"
                                           "      %-7s %-6d %-10d %-10d\n",
-                                          NIP6(dest->addr.in6),
+                                          &dest->addr.in6,
                                           ntohs(dest->port),
                                           ip_vs_fwd_name(atomic_read(&dest->conn_flags)),
                                           atomic_read(&dest->weight),
@@ -2141,8 +2129,8 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
 
        /* Check for valid protocol: TCP or UDP, even for fwmark!=0 */
        if (usvc.protocol != IPPROTO_TCP && usvc.protocol != IPPROTO_UDP) {
-               IP_VS_ERR("set_ctl: invalid protocol: %d %d.%d.%d.%d:%d %s\n",
-                         usvc.protocol, NIPQUAD(usvc.addr.ip),
+               IP_VS_ERR("set_ctl: invalid protocol: %d %pI4:%d %s\n",
+                         usvc.protocol, &usvc.addr.ip,
                          ntohs(usvc.port), usvc.sched_name);
                ret = -EFAULT;
                goto out_unlock;
index a16943fd72f175646ffa8406ac741ca56a2015db..a9dac74bb13f7550a4aa9c6b95a84566d4e1fd68 100644 (file)
@@ -64,9 +64,16 @@ struct ip_vs_dh_bucket {
 /*
  *     Returns hash value for IPVS DH entry
  */
-static inline unsigned ip_vs_dh_hashkey(__be32 addr)
+static inline unsigned ip_vs_dh_hashkey(int af, const union nf_inet_addr *addr)
 {
-       return (ntohl(addr)*2654435761UL) & IP_VS_DH_TAB_MASK;
+       __be32 addr_fold = addr->ip;
+
+#ifdef CONFIG_IP_VS_IPV6
+       if (af == AF_INET6)
+               addr_fold = addr->ip6[0]^addr->ip6[1]^
+                           addr->ip6[2]^addr->ip6[3];
+#endif
+       return (ntohl(addr_fold)*2654435761UL) & IP_VS_DH_TAB_MASK;
 }
 
 
@@ -74,9 +81,10 @@ static inline unsigned ip_vs_dh_hashkey(__be32 addr)
  *      Get ip_vs_dest associated with supplied parameters.
  */
 static inline struct ip_vs_dest *
-ip_vs_dh_get(struct ip_vs_dh_bucket *tbl, __be32 addr)
+ip_vs_dh_get(int af, struct ip_vs_dh_bucket *tbl,
+            const union nf_inet_addr *addr)
 {
-       return (tbl[ip_vs_dh_hashkey(addr)]).dest;
+       return (tbl[ip_vs_dh_hashkey(af, addr)]).dest;
 }
 
 
@@ -202,12 +210,14 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 {
        struct ip_vs_dest *dest;
        struct ip_vs_dh_bucket *tbl;
-       struct iphdr *iph = ip_hdr(skb);
+       struct ip_vs_iphdr iph;
+
+       ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
 
        IP_VS_DBG(6, "ip_vs_dh_schedule(): Scheduling...\n");
 
        tbl = (struct ip_vs_dh_bucket *)svc->sched_data;
-       dest = ip_vs_dh_get(tbl, iph->daddr);
+       dest = ip_vs_dh_get(svc->af, tbl, &iph.daddr);
        if (!dest
            || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
            || atomic_read(&dest->weight) <= 0
@@ -215,11 +225,10 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
                return NULL;
        }
 
-       IP_VS_DBG(6, "DH: destination IP address %u.%u.%u.%u "
-                 "--> server %u.%u.%u.%u:%d\n",
-                 NIPQUAD(iph->daddr),
-                 NIPQUAD(dest->addr.ip),
-                 ntohs(dest->port));
+       IP_VS_DBG_BUF(6, "DH: destination IP address %s --> server %s:%d\n",
+                     IP_VS_DBG_ADDR(svc->af, &iph.daddr),
+                     IP_VS_DBG_ADDR(svc->af, &dest->addr),
+                     ntohs(dest->port));
 
        return dest;
 }
@@ -234,9 +243,6 @@ static struct ip_vs_scheduler ip_vs_dh_scheduler =
        .refcnt =               ATOMIC_INIT(0),
        .module =               THIS_MODULE,
        .n_list =               LIST_HEAD_INIT(ip_vs_dh_scheduler.n_list),
-#ifdef CONFIG_IP_VS_IPV6
-       .supports_ipv6 =        0,
-#endif
        .init_service =         ip_vs_dh_init_svc,
        .done_service =         ip_vs_dh_done_svc,
        .update_service =       ip_vs_dh_update_svc,
index 2e7dbd8b73a431fd4ef2b4cdb2346e497e853854..428edbf481cce9814ac860ca20ee3b89aeb38ab3 100644 (file)
@@ -178,10 +178,8 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
                                           &start, &end) != 1)
                        return 1;
 
-               IP_VS_DBG(7, "PASV response (%u.%u.%u.%u:%d) -> "
-                         "%u.%u.%u.%u:%d detected\n",
-                         NIPQUAD(from.ip), ntohs(port),
-                         NIPQUAD(cp->caddr.ip), 0);
+               IP_VS_DBG(7, "PASV response (%pI4:%d) -> %pI4:%d detected\n",
+                         &from.ip, ntohs(port), &cp->caddr.ip, 0);
 
                /*
                 * Now update or create an connection entry for it
@@ -312,8 +310,7 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
                                   &start, &end) != 1)
                return 1;
 
-       IP_VS_DBG(7, "PORT %u.%u.%u.%u:%d detected\n",
-                 NIPQUAD(to.ip), ntohs(port));
+       IP_VS_DBG(7, "PORT %pI4:%d detected\n", &to.ip, ntohs(port));
 
        /* Passive mode off */
        cp->app_data = NULL;
@@ -321,9 +318,9 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
        /*
         * Now update or create a connection entry for it
         */
-       IP_VS_DBG(7, "protocol %s %u.%u.%u.%u:%d %u.%u.%u.%u:%d\n",
+       IP_VS_DBG(7, "protocol %s %pI4:%d %pI4:%d\n",
                  ip_vs_proto_name(iph->protocol),
-                 NIPQUAD(to.ip), ntohs(port), NIPQUAD(cp->vaddr.ip), 0);
+                 &to.ip, ntohs(port), &cp->vaddr.ip, 0);
 
        n_cp = ip_vs_conn_in_get(AF_INET, iph->protocol,
                                 &to, port,
index 6ecef3518cac190090e3748039c7aa4e4f2053c6..9394f539966aea9f91dd37a6165969d31b5a8ee8 100644 (file)
@@ -86,7 +86,8 @@ static int sysctl_ip_vs_lblc_expiration = 24*60*60*HZ;
  */
 struct ip_vs_lblc_entry {
        struct list_head        list;
-       __be32                  addr;           /* destination IP address */
+       int                     af;             /* address family */
+       union nf_inet_addr      addr;           /* destination IP address */
        struct ip_vs_dest       *dest;          /* real server (cache) */
        unsigned long           lastuse;        /* last used time */
 };
@@ -115,7 +116,7 @@ static ctl_table vs_vars_table[] = {
                .data           = &sysctl_ip_vs_lblc_expiration,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        { .ctl_name = 0 }
 };
@@ -137,9 +138,17 @@ static inline void ip_vs_lblc_free(struct ip_vs_lblc_entry *en)
 /*
  *     Returns hash value for IPVS LBLC entry
  */
-static inline unsigned ip_vs_lblc_hashkey(__be32 addr)
+static inline unsigned
+ip_vs_lblc_hashkey(int af, const union nf_inet_addr *addr)
 {
-       return (ntohl(addr)*2654435761UL) & IP_VS_LBLC_TAB_MASK;
+       __be32 addr_fold = addr->ip;
+
+#ifdef CONFIG_IP_VS_IPV6
+       if (af == AF_INET6)
+               addr_fold = addr->ip6[0]^addr->ip6[1]^
+                           addr->ip6[2]^addr->ip6[3];
+#endif
+       return (ntohl(addr_fold)*2654435761UL) & IP_VS_LBLC_TAB_MASK;
 }
 
 
@@ -150,7 +159,7 @@ static inline unsigned ip_vs_lblc_hashkey(__be32 addr)
 static void
 ip_vs_lblc_hash(struct ip_vs_lblc_table *tbl, struct ip_vs_lblc_entry *en)
 {
-       unsigned hash = ip_vs_lblc_hashkey(en->addr);
+       unsigned hash = ip_vs_lblc_hashkey(en->af, &en->addr);
 
        list_add(&en->list, &tbl->bucket[hash]);
        atomic_inc(&tbl->entries);
@@ -162,13 +171,14 @@ ip_vs_lblc_hash(struct ip_vs_lblc_table *tbl, struct ip_vs_lblc_entry *en)
  *  lock
  */
 static inline struct ip_vs_lblc_entry *
-ip_vs_lblc_get(struct ip_vs_lblc_table *tbl, __be32 addr)
+ip_vs_lblc_get(int af, struct ip_vs_lblc_table *tbl,
+              const union nf_inet_addr *addr)
 {
-       unsigned hash = ip_vs_lblc_hashkey(addr);
+       unsigned hash = ip_vs_lblc_hashkey(af, addr);
        struct ip_vs_lblc_entry *en;
 
        list_for_each_entry(en, &tbl->bucket[hash], list)
-               if (en->addr == addr)
+               if (ip_vs_addr_equal(af, &en->addr, addr))
                        return en;
 
        return NULL;
@@ -180,12 +190,12 @@ ip_vs_lblc_get(struct ip_vs_lblc_table *tbl, __be32 addr)
  * address to a server. Called under write lock.
  */
 static inline struct ip_vs_lblc_entry *
-ip_vs_lblc_new(struct ip_vs_lblc_table *tbl, __be32 daddr,
+ip_vs_lblc_new(struct ip_vs_lblc_table *tbl, const union nf_inet_addr *daddr,
               struct ip_vs_dest *dest)
 {
        struct ip_vs_lblc_entry *en;
 
-       en = ip_vs_lblc_get(tbl, daddr);
+       en = ip_vs_lblc_get(dest->af, tbl, daddr);
        if (!en) {
                en = kmalloc(sizeof(*en), GFP_ATOMIC);
                if (!en) {
@@ -193,7 +203,8 @@ ip_vs_lblc_new(struct ip_vs_lblc_table *tbl, __be32 daddr,
                        return NULL;
                }
 
-               en->addr = daddr;
+               en->af = dest->af;
+               ip_vs_addr_copy(dest->af, &en->addr, daddr);
                en->lastuse = jiffies;
 
                atomic_inc(&dest->refcnt);
@@ -369,7 +380,7 @@ static int ip_vs_lblc_done_svc(struct ip_vs_service *svc)
 
 
 static inline struct ip_vs_dest *
-__ip_vs_lblc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+__ip_vs_lblc_schedule(struct ip_vs_service *svc)
 {
        struct ip_vs_dest *dest, *least;
        int loh, doh;
@@ -420,12 +431,13 @@ __ip_vs_lblc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
                }
        }
 
-       IP_VS_DBG(6, "LBLC: server %d.%d.%d.%d:%d "
-                 "activeconns %d refcnt %d weight %d overhead %d\n",
-                 NIPQUAD(least->addr.ip), ntohs(least->port),
-                 atomic_read(&least->activeconns),
-                 atomic_read(&least->refcnt),
-                 atomic_read(&least->weight), loh);
+       IP_VS_DBG_BUF(6, "LBLC: server %s:%d "
+                     "activeconns %d refcnt %d weight %d overhead %d\n",
+                     IP_VS_DBG_ADDR(least->af, &least->addr),
+                     ntohs(least->port),
+                     atomic_read(&least->activeconns),
+                     atomic_read(&least->refcnt),
+                     atomic_read(&least->weight), loh);
 
        return least;
 }
@@ -459,15 +471,17 @@ static struct ip_vs_dest *
 ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 {
        struct ip_vs_lblc_table *tbl = svc->sched_data;
-       struct iphdr *iph = ip_hdr(skb);
+       struct ip_vs_iphdr iph;
        struct ip_vs_dest *dest = NULL;
        struct ip_vs_lblc_entry *en;
 
+       ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
+
        IP_VS_DBG(6, "ip_vs_lblc_schedule(): Scheduling...\n");
 
        /* First look in our cache */
        read_lock(&svc->sched_lock);
-       en = ip_vs_lblc_get(tbl, iph->daddr);
+       en = ip_vs_lblc_get(svc->af, tbl, &iph.daddr);
        if (en) {
                /* We only hold a read lock, but this is atomic */
                en->lastuse = jiffies;
@@ -491,7 +505,7 @@ ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
                goto out;
 
        /* No cache entry or it is invalid, time to schedule */
-       dest = __ip_vs_lblc_schedule(svc, iph);
+       dest = __ip_vs_lblc_schedule(svc);
        if (!dest) {
                IP_VS_DBG(1, "no destination available\n");
                return NULL;
@@ -499,15 +513,13 @@ ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 
        /* If we fail to create a cache entry, we'll just use the valid dest */
        write_lock(&svc->sched_lock);
-       ip_vs_lblc_new(tbl, iph->daddr, dest);
+       ip_vs_lblc_new(tbl, &iph.daddr, dest);
        write_unlock(&svc->sched_lock);
 
 out:
-       IP_VS_DBG(6, "LBLC: destination IP address %u.%u.%u.%u "
-                 "--> server %u.%u.%u.%u:%d\n",
-                 NIPQUAD(iph->daddr),
-                 NIPQUAD(dest->addr.ip),
-                 ntohs(dest->port));
+       IP_VS_DBG_BUF(6, "LBLC: destination IP address %s --> server %s:%d\n",
+                     IP_VS_DBG_ADDR(svc->af, &iph.daddr),
+                     IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port));
 
        return dest;
 }
@@ -522,9 +534,6 @@ static struct ip_vs_scheduler ip_vs_lblc_scheduler =
        .refcnt =               ATOMIC_INIT(0),
        .module =               THIS_MODULE,
        .n_list =               LIST_HEAD_INIT(ip_vs_lblc_scheduler.n_list),
-#ifdef CONFIG_IP_VS_IPV6
-       .supports_ipv6 =        0,
-#endif
        .init_service =         ip_vs_lblc_init_svc,
        .done_service =         ip_vs_lblc_done_svc,
        .schedule =             ip_vs_lblc_schedule,
index 1f75ea83bcf8654256912317a4d8c4d8ce92e77a..92dc76a6842cc101a1f14afed07ae65841d10440 100644 (file)
@@ -202,12 +202,13 @@ static inline struct ip_vs_dest *ip_vs_dest_set_min(struct ip_vs_dest_set *set)
                }
        }
 
-       IP_VS_DBG(6, "ip_vs_dest_set_min: server %d.%d.%d.%d:%d "
-                 "activeconns %d refcnt %d weight %d overhead %d\n",
-                 NIPQUAD(least->addr.ip), ntohs(least->port),
-                 atomic_read(&least->activeconns),
-                 atomic_read(&least->refcnt),
-                 atomic_read(&least->weight), loh);
+       IP_VS_DBG_BUF(6, "ip_vs_dest_set_min: server %s:%d "
+                     "activeconns %d refcnt %d weight %d overhead %d\n",
+                     IP_VS_DBG_ADDR(least->af, &least->addr),
+                     ntohs(least->port),
+                     atomic_read(&least->activeconns),
+                     atomic_read(&least->refcnt),
+                     atomic_read(&least->weight), loh);
        return least;
 }
 
@@ -248,12 +249,12 @@ static inline struct ip_vs_dest *ip_vs_dest_set_max(struct ip_vs_dest_set *set)
                }
        }
 
-       IP_VS_DBG(6, "ip_vs_dest_set_max: server %d.%d.%d.%d:%d "
-                 "activeconns %d refcnt %d weight %d overhead %d\n",
-                 NIPQUAD(most->addr.ip), ntohs(most->port),
-                 atomic_read(&most->activeconns),
-                 atomic_read(&most->refcnt),
-                 atomic_read(&most->weight), moh);
+       IP_VS_DBG_BUF(6, "ip_vs_dest_set_max: server %s:%d "
+                     "activeconns %d refcnt %d weight %d overhead %d\n",
+                     IP_VS_DBG_ADDR(most->af, &most->addr), ntohs(most->port),
+                     atomic_read(&most->activeconns),
+                     atomic_read(&most->refcnt),
+                     atomic_read(&most->weight), moh);
        return most;
 }
 
@@ -264,7 +265,8 @@ static inline struct ip_vs_dest *ip_vs_dest_set_max(struct ip_vs_dest_set *set)
  */
 struct ip_vs_lblcr_entry {
        struct list_head        list;
-       __be32                   addr;           /* destination IP address */
+       int                     af;             /* address family */
+       union nf_inet_addr      addr;           /* destination IP address */
        struct ip_vs_dest_set   set;            /* destination server set */
        unsigned long           lastuse;        /* last used time */
 };
@@ -293,7 +295,7 @@ static ctl_table vs_vars_table[] = {
                .data           = &sysctl_ip_vs_lblcr_expiration,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        { .ctl_name = 0 }
 };
@@ -311,9 +313,17 @@ static inline void ip_vs_lblcr_free(struct ip_vs_lblcr_entry *en)
 /*
  *     Returns hash value for IPVS LBLCR entry
  */
-static inline unsigned ip_vs_lblcr_hashkey(__be32 addr)
+static inline unsigned
+ip_vs_lblcr_hashkey(int af, const union nf_inet_addr *addr)
 {
-       return (ntohl(addr)*2654435761UL) & IP_VS_LBLCR_TAB_MASK;
+       __be32 addr_fold = addr->ip;
+
+#ifdef CONFIG_IP_VS_IPV6
+       if (af == AF_INET6)
+               addr_fold = addr->ip6[0]^addr->ip6[1]^
+                           addr->ip6[2]^addr->ip6[3];
+#endif
+       return (ntohl(addr_fold)*2654435761UL) & IP_VS_LBLCR_TAB_MASK;
 }
 
 
@@ -324,7 +334,7 @@ static inline unsigned ip_vs_lblcr_hashkey(__be32 addr)
 static void
 ip_vs_lblcr_hash(struct ip_vs_lblcr_table *tbl, struct ip_vs_lblcr_entry *en)
 {
-       unsigned hash = ip_vs_lblcr_hashkey(en->addr);
+       unsigned hash = ip_vs_lblcr_hashkey(en->af, &en->addr);
 
        list_add(&en->list, &tbl->bucket[hash]);
        atomic_inc(&tbl->entries);
@@ -336,13 +346,14 @@ ip_vs_lblcr_hash(struct ip_vs_lblcr_table *tbl, struct ip_vs_lblcr_entry *en)
  *  read lock.
  */
 static inline struct ip_vs_lblcr_entry *
-ip_vs_lblcr_get(struct ip_vs_lblcr_table *tbl, __be32 addr)
+ip_vs_lblcr_get(int af, struct ip_vs_lblcr_table *tbl,
+               const union nf_inet_addr *addr)
 {
-       unsigned hash = ip_vs_lblcr_hashkey(addr);
+       unsigned hash = ip_vs_lblcr_hashkey(af, addr);
        struct ip_vs_lblcr_entry *en;
 
        list_for_each_entry(en, &tbl->bucket[hash], list)
-               if (en->addr == addr)
+               if (ip_vs_addr_equal(af, &en->addr, addr))
                        return en;
 
        return NULL;
@@ -354,12 +365,12 @@ ip_vs_lblcr_get(struct ip_vs_lblcr_table *tbl, __be32 addr)
  * IP address to a server. Called under write lock.
  */
 static inline struct ip_vs_lblcr_entry *
-ip_vs_lblcr_new(struct ip_vs_lblcr_table *tbl,  __be32 daddr,
+ip_vs_lblcr_new(struct ip_vs_lblcr_table *tbl, const union nf_inet_addr *daddr,
                struct ip_vs_dest *dest)
 {
        struct ip_vs_lblcr_entry *en;
 
-       en = ip_vs_lblcr_get(tbl, daddr);
+       en = ip_vs_lblcr_get(dest->af, tbl, daddr);
        if (!en) {
                en = kmalloc(sizeof(*en), GFP_ATOMIC);
                if (!en) {
@@ -367,7 +378,8 @@ ip_vs_lblcr_new(struct ip_vs_lblcr_table *tbl,  __be32 daddr,
                        return NULL;
                }
 
-               en->addr = daddr;
+               en->af = dest->af;
+               ip_vs_addr_copy(dest->af, &en->addr, daddr);
                en->lastuse = jiffies;
 
                /* initilize its dest set */
@@ -544,7 +556,7 @@ static int ip_vs_lblcr_done_svc(struct ip_vs_service *svc)
 
 
 static inline struct ip_vs_dest *
-__ip_vs_lblcr_schedule(struct ip_vs_service *svc, struct iphdr *iph)
+__ip_vs_lblcr_schedule(struct ip_vs_service *svc)
 {
        struct ip_vs_dest *dest, *least;
        int loh, doh;
@@ -596,12 +608,13 @@ __ip_vs_lblcr_schedule(struct ip_vs_service *svc, struct iphdr *iph)
                }
        }
 
-       IP_VS_DBG(6, "LBLCR: server %d.%d.%d.%d:%d "
-                 "activeconns %d refcnt %d weight %d overhead %d\n",
-                 NIPQUAD(least->addr.ip), ntohs(least->port),
-                 atomic_read(&least->activeconns),
-                 atomic_read(&least->refcnt),
-                 atomic_read(&least->weight), loh);
+       IP_VS_DBG_BUF(6, "LBLCR: server %s:%d "
+                     "activeconns %d refcnt %d weight %d overhead %d\n",
+                     IP_VS_DBG_ADDR(least->af, &least->addr),
+                     ntohs(least->port),
+                     atomic_read(&least->activeconns),
+                     atomic_read(&least->refcnt),
+                     atomic_read(&least->weight), loh);
 
        return least;
 }
@@ -635,15 +648,17 @@ static struct ip_vs_dest *
 ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 {
        struct ip_vs_lblcr_table *tbl = svc->sched_data;
-       struct iphdr *iph = ip_hdr(skb);
+       struct ip_vs_iphdr iph;
        struct ip_vs_dest *dest = NULL;
        struct ip_vs_lblcr_entry *en;
 
+       ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
+
        IP_VS_DBG(6, "ip_vs_lblcr_schedule(): Scheduling...\n");
 
        /* First look in our cache */
        read_lock(&svc->sched_lock);
-       en = ip_vs_lblcr_get(tbl, iph->daddr);
+       en = ip_vs_lblcr_get(svc->af, tbl, &iph.daddr);
        if (en) {
                /* We only hold a read lock, but this is atomic */
                en->lastuse = jiffies;
@@ -673,7 +688,7 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
                }
 
                /* The cache entry is invalid, time to schedule */
-               dest = __ip_vs_lblcr_schedule(svc, iph);
+               dest = __ip_vs_lblcr_schedule(svc);
                if (!dest) {
                        IP_VS_DBG(1, "no destination available\n");
                        read_unlock(&svc->sched_lock);
@@ -691,7 +706,7 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
                goto out;
 
        /* No cache entry, time to schedule */
-       dest = __ip_vs_lblcr_schedule(svc, iph);
+       dest = __ip_vs_lblcr_schedule(svc);
        if (!dest) {
                IP_VS_DBG(1, "no destination available\n");
                return NULL;
@@ -699,15 +714,13 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 
        /* If we fail to create a cache entry, we'll just use the valid dest */
        write_lock(&svc->sched_lock);
-       ip_vs_lblcr_new(tbl, iph->daddr, dest);
+       ip_vs_lblcr_new(tbl, &iph.daddr, dest);
        write_unlock(&svc->sched_lock);
 
 out:
-       IP_VS_DBG(6, "LBLCR: destination IP address %u.%u.%u.%u "
-                 "--> server %u.%u.%u.%u:%d\n",
-                 NIPQUAD(iph->daddr),
-                 NIPQUAD(dest->addr.ip),
-                 ntohs(dest->port));
+       IP_VS_DBG_BUF(6, "LBLCR: destination IP address %s --> server %s:%d\n",
+                     IP_VS_DBG_ADDR(svc->af, &iph.daddr),
+                     IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port));
 
        return dest;
 }
@@ -722,9 +735,6 @@ static struct ip_vs_scheduler ip_vs_lblcr_scheduler =
        .refcnt =               ATOMIC_INIT(0),
        .module =               THIS_MODULE,
        .n_list =               LIST_HEAD_INIT(ip_vs_lblcr_scheduler.n_list),
-#ifdef CONFIG_IP_VS_IPV6
-       .supports_ipv6 =        0,
-#endif
        .init_service =         ip_vs_lblcr_init_svc,
        .done_service =         ip_vs_lblcr_done_svc,
        .schedule =             ip_vs_lblcr_schedule,
index b69f808ac461215f0f07be0556e355e4b5e27707..51912cab777bb5349012709639c1efa1ff774005 100644 (file)
@@ -81,9 +81,6 @@ static struct ip_vs_scheduler ip_vs_lc_scheduler = {
        .refcnt =               ATOMIC_INIT(0),
        .module =               THIS_MODULE,
        .n_list =               LIST_HEAD_INIT(ip_vs_lc_scheduler.n_list),
-#ifdef CONFIG_IP_VS_IPV6
-       .supports_ipv6 =        1,
-#endif
        .schedule =             ip_vs_lc_schedule,
 };
 
index 9a2d8033f08f1f2b0d8707d3650361f231d3500a..6758ad2ceaaf66130f881ff672cc0d9444d1416a 100644 (file)
@@ -116,9 +116,6 @@ static struct ip_vs_scheduler ip_vs_nq_scheduler =
        .refcnt =               ATOMIC_INIT(0),
        .module =               THIS_MODULE,
        .n_list =               LIST_HEAD_INIT(ip_vs_nq_scheduler.n_list),
-#ifdef CONFIG_IP_VS_IPV6
-       .supports_ipv6 =        1,
-#endif
        .schedule =             ip_vs_nq_schedule,
 };
 
index 0791f9e08feb7f04d8e2ea56aa08f1064fe6232f..a01520e3d6b8266c671f57aedfb251f70bba61f4 100644 (file)
@@ -164,26 +164,21 @@ ip_vs_tcpudp_debug_packet_v4(struct ip_vs_protocol *pp,
        if (ih == NULL)
                sprintf(buf, "%s TRUNCATED", pp->name);
        else if (ih->frag_off & htons(IP_OFFSET))
-               sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u frag",
-                       pp->name, NIPQUAD(ih->saddr),
-                       NIPQUAD(ih->daddr));
+               sprintf(buf, "%s %pI4->%pI4 frag",
+                       pp->name, &ih->saddr, &ih->daddr);
        else {
                __be16 _ports[2], *pptr
 ;
                pptr = skb_header_pointer(skb, offset + ih->ihl*4,
                                          sizeof(_ports), _ports);
                if (pptr == NULL)
-                       sprintf(buf, "%s TRUNCATED %u.%u.%u.%u->%u.%u.%u.%u",
-                               pp->name,
-                               NIPQUAD(ih->saddr),
-                               NIPQUAD(ih->daddr));
+                       sprintf(buf, "%s TRUNCATED %pI4->%pI4",
+                               pp->name, &ih->saddr, &ih->daddr);
                else
-                       sprintf(buf, "%s %u.%u.%u.%u:%u->%u.%u.%u.%u:%u",
+                       sprintf(buf, "%s %pI4:%u->%pI4:%u",
                                pp->name,
-                               NIPQUAD(ih->saddr),
-                               ntohs(pptr[0]),
-                               NIPQUAD(ih->daddr),
-                               ntohs(pptr[1]));
+                               &ih->saddr, ntohs(pptr[0]),
+                               &ih->daddr, ntohs(pptr[1]));
        }
 
        printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
@@ -203,26 +198,21 @@ ip_vs_tcpudp_debug_packet_v6(struct ip_vs_protocol *pp,
        if (ih == NULL)
                sprintf(buf, "%s TRUNCATED", pp->name);
        else if (ih->nexthdr == IPPROTO_FRAGMENT)
-               sprintf(buf, "%s " NIP6_FMT "->" NIP6_FMT " frag",
-                       pp->name, NIP6(ih->saddr),
-                       NIP6(ih->daddr));
+               sprintf(buf, "%s %pI6->%pI6 frag",
+                       pp->name, &ih->saddr, &ih->daddr);
        else {
                __be16 _ports[2], *pptr;
 
                pptr = skb_header_pointer(skb, offset + sizeof(struct ipv6hdr),
                                          sizeof(_ports), _ports);
                if (pptr == NULL)
-                       sprintf(buf, "%s TRUNCATED " NIP6_FMT "->" NIP6_FMT,
-                               pp->name,
-                               NIP6(ih->saddr),
-                               NIP6(ih->daddr));
+                       sprintf(buf, "%s TRUNCATED %pI6->%pI6",
+                               pp->name, &ih->saddr, &ih->daddr);
                else
-                       sprintf(buf, "%s " NIP6_FMT ":%u->" NIP6_FMT ":%u",
+                       sprintf(buf, "%s %pI6:%u->%pI6:%u",
                                pp->name,
-                               NIP6(ih->saddr),
-                               ntohs(pptr[0]),
-                               NIP6(ih->daddr),
-                               ntohs(pptr[1]));
+                               &ih->saddr, ntohs(pptr[0]),
+                               &ih->daddr, ntohs(pptr[1]));
        }
 
        printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
index 80ab0c8e5b4af113e7a67fa0f4032a808d248119..79f56c1e7c19b0ef771ed553ea90d743e736b9f8 100644 (file)
@@ -135,9 +135,8 @@ ah_esp_debug_packet_v4(struct ip_vs_protocol *pp, const struct sk_buff *skb,
        if (ih == NULL)
                sprintf(buf, "%s TRUNCATED", pp->name);
        else
-               sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u",
-                       pp->name, NIPQUAD(ih->saddr),
-                       NIPQUAD(ih->daddr));
+               sprintf(buf, "%s %pI4->%pI4",
+                       pp->name, &ih->saddr, &ih->daddr);
 
        printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
 }
@@ -154,9 +153,8 @@ ah_esp_debug_packet_v6(struct ip_vs_protocol *pp, const struct sk_buff *skb,
        if (ih == NULL)
                sprintf(buf, "%s TRUNCATED", pp->name);
        else
-               sprintf(buf, "%s " NIP6_FMT "->" NIP6_FMT,
-                       pp->name, NIP6(ih->saddr),
-                       NIP6(ih->daddr));
+               sprintf(buf, "%s %pI6->%pI6",
+                       pp->name, &ih->saddr, &ih->daddr);
 
        printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
 }
index dd4566ea2bff7bce68baabf916eb4b9ae25c9a6f..8cba41802850b041e5062c38f786da00f3ed6697 100644 (file)
@@ -192,8 +192,8 @@ tcp_snat_handler(struct sk_buff *skb,
        /* Adjust TCP checksums */
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
                tcp_partial_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr,
-                                       htonl(oldlen),
-                                       htonl(skb->len - tcphoff));
+                                       htons(oldlen),
+                                       htons(skb->len - tcphoff));
        } else if (!cp->app) {
                /* Only port and addr are changed, do fast csum update */
                tcp_fast_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr,
@@ -267,8 +267,8 @@ tcp_dnat_handler(struct sk_buff *skb,
         */
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
                tcp_partial_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr,
-                                       htonl(oldlen),
-                                       htonl(skb->len - tcphoff));
+                                       htons(oldlen),
+                                       htons(skb->len - tcphoff));
        } else if (!cp->app) {
                /* Only port and addr are changed, do fast csum update */
                tcp_fast_csum_update(cp->af, tcph, &cp->vaddr, &cp->daddr,
index 6eb6039d63434f6ecc4bd511edb390e0e91bbd6a..d2930a71084bd3079e980ba7af0ecdb4d00204fa 100644 (file)
@@ -203,8 +203,8 @@ udp_snat_handler(struct sk_buff *skb,
         */
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
                udp_partial_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr,
-                                       htonl(oldlen),
-                                       htonl(skb->len - udphoff));
+                                       htons(oldlen),
+                                       htons(skb->len - udphoff));
        } else if (!cp->app && (udph->check != 0)) {
                /* Only port and addr are changed, do fast csum update */
                udp_fast_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr,
@@ -279,8 +279,8 @@ udp_dnat_handler(struct sk_buff *skb,
         */
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
                udp_partial_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr,
-                                       htonl(oldlen),
-                                       htonl(skb->len - udphoff));
+                                       htons(oldlen),
+                                       htons(skb->len - udphoff));
        } else if (!cp->app && (udph->check != 0)) {
                /* Only port and addr are changed, do fast csum update */
                udp_fast_csum_update(cp->af, udph, &cp->vaddr, &cp->daddr,
index a22195f68ac4cf102b536be9d1a40354eab76723..8fb51c169eb852daeb9e1117fde96f07a9d2b595 100644 (file)
@@ -89,9 +89,6 @@ static struct ip_vs_scheduler ip_vs_rr_scheduler = {
        .refcnt =               ATOMIC_INIT(0),
        .module =               THIS_MODULE,
        .n_list =               LIST_HEAD_INIT(ip_vs_rr_scheduler.n_list),
-#ifdef CONFIG_IP_VS_IPV6
-       .supports_ipv6 =        1,
-#endif
        .init_service =         ip_vs_rr_init_svc,
        .update_service =       ip_vs_rr_update_svc,
        .schedule =             ip_vs_rr_schedule,
index 7d2f22f04b8389f2cd2f1ba8b20f72e49e7f511f..691a6a0086e18c90f2b0548951b1218fc9a4958f 100644 (file)
@@ -118,9 +118,6 @@ static struct ip_vs_scheduler ip_vs_sed_scheduler =
        .refcnt =               ATOMIC_INIT(0),
        .module =               THIS_MODULE,
        .n_list =               LIST_HEAD_INIT(ip_vs_sed_scheduler.n_list),
-#ifdef CONFIG_IP_VS_IPV6
-       .supports_ipv6 =        1,
-#endif
        .schedule =             ip_vs_sed_schedule,
 };
 
index 1d96de27fefdbaab3022f0178218a7207e8a2fc5..0e53955ef1396ec0d157163eb66ab00f2e590506 100644 (file)
@@ -61,9 +61,16 @@ struct ip_vs_sh_bucket {
 /*
  *     Returns hash value for IPVS SH entry
  */
-static inline unsigned ip_vs_sh_hashkey(__be32 addr)
+static inline unsigned ip_vs_sh_hashkey(int af, const union nf_inet_addr *addr)
 {
-       return (ntohl(addr)*2654435761UL) & IP_VS_SH_TAB_MASK;
+       __be32 addr_fold = addr->ip;
+
+#ifdef CONFIG_IP_VS_IPV6
+       if (af == AF_INET6)
+               addr_fold = addr->ip6[0]^addr->ip6[1]^
+                           addr->ip6[2]^addr->ip6[3];
+#endif
+       return (ntohl(addr_fold)*2654435761UL) & IP_VS_SH_TAB_MASK;
 }
 
 
@@ -71,9 +78,10 @@ static inline unsigned ip_vs_sh_hashkey(__be32 addr)
  *      Get ip_vs_dest associated with supplied parameters.
  */
 static inline struct ip_vs_dest *
-ip_vs_sh_get(struct ip_vs_sh_bucket *tbl, __be32 addr)
+ip_vs_sh_get(int af, struct ip_vs_sh_bucket *tbl,
+            const union nf_inet_addr *addr)
 {
-       return (tbl[ip_vs_sh_hashkey(addr)]).dest;
+       return (tbl[ip_vs_sh_hashkey(af, addr)]).dest;
 }
 
 
@@ -199,12 +207,14 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 {
        struct ip_vs_dest *dest;
        struct ip_vs_sh_bucket *tbl;
-       struct iphdr *iph = ip_hdr(skb);
+       struct ip_vs_iphdr iph;
+
+       ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
 
        IP_VS_DBG(6, "ip_vs_sh_schedule(): Scheduling...\n");
 
        tbl = (struct ip_vs_sh_bucket *)svc->sched_data;
-       dest = ip_vs_sh_get(tbl, iph->saddr);
+       dest = ip_vs_sh_get(svc->af, tbl, &iph.saddr);
        if (!dest
            || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
            || atomic_read(&dest->weight) <= 0
@@ -212,11 +222,10 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
                return NULL;
        }
 
-       IP_VS_DBG(6, "SH: source IP address %u.%u.%u.%u "
-                 "--> server %u.%u.%u.%u:%d\n",
-                 NIPQUAD(iph->saddr),
-                 NIPQUAD(dest->addr.ip),
-                 ntohs(dest->port));
+       IP_VS_DBG_BUF(6, "SH: source IP address %s --> server %s:%d\n",
+                     IP_VS_DBG_ADDR(svc->af, &iph.saddr),
+                     IP_VS_DBG_ADDR(svc->af, &dest->addr),
+                     ntohs(dest->port));
 
        return dest;
 }
@@ -231,9 +240,6 @@ static struct ip_vs_scheduler ip_vs_sh_scheduler =
        .refcnt =               ATOMIC_INIT(0),
        .module =               THIS_MODULE,
        .n_list  =              LIST_HEAD_INIT(ip_vs_sh_scheduler.n_list),
-#ifdef CONFIG_IP_VS_IPV6
-       .supports_ipv6 =        0,
-#endif
        .init_service =         ip_vs_sh_init_svc,
        .done_service =         ip_vs_sh_done_svc,
        .update_service =       ip_vs_sh_update_svc,
index de5e7e118eed51e9b10be8f9c76cc91e9f7ed9d0..6be5d4efa51ba58c9f13bb40b475bcb58c6795ca 100644 (file)
@@ -580,8 +580,8 @@ static int bind_mcastif_addr(struct socket *sock, char *ifname)
                IP_VS_ERR("You probably need to specify IP address on "
                          "multicast interface.\n");
 
-       IP_VS_DBG(7, "binding socket with (%s) %u.%u.%u.%u\n",
-                 ifname, NIPQUAD(addr));
+       IP_VS_DBG(7, "binding socket with (%s) %pI4\n",
+                 ifname, &addr);
 
        /* Now bind the socket with the address of multicast interface */
        sin.sin_family       = AF_INET;
index 8c596e712599fd12ff4b03edceae590d22226325..57b452bbb4eab71f106e5e56f23259b3df7b18d8 100644 (file)
@@ -106,9 +106,6 @@ static struct ip_vs_scheduler ip_vs_wlc_scheduler =
        .refcnt =               ATOMIC_INIT(0),
        .module =               THIS_MODULE,
        .n_list =               LIST_HEAD_INIT(ip_vs_wlc_scheduler.n_list),
-#ifdef CONFIG_IP_VS_IPV6
-       .supports_ipv6 =        1,
-#endif
        .schedule =             ip_vs_wlc_schedule,
 };
 
index 7ea92fed50bf86c21ec75abfa779d9db1bf3d71f..2f618dc29c5b69468b21ded446b13f18c1efebab 100644 (file)
@@ -213,9 +213,6 @@ static struct ip_vs_scheduler ip_vs_wrr_scheduler = {
        .refcnt =               ATOMIC_INIT(0),
        .module =               THIS_MODULE,
        .n_list =               LIST_HEAD_INIT(ip_vs_wrr_scheduler.n_list),
-#ifdef CONFIG_IP_VS_IPV6
-       .supports_ipv6 =        1,
-#endif
        .init_service =         ip_vs_wrr_init_svc,
        .done_service =         ip_vs_wrr_done_svc,
        .update_service =       ip_vs_wrr_update_svc,
index e90d52f199bc1d98d3cf8e2c8fe93008d60b02f6..425ab144f15d4e29d90a9c6078d5221588b18fbb 100644 (file)
@@ -82,14 +82,13 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos)
 
                        if (ip_route_output_key(&init_net, &rt, &fl)) {
                                spin_unlock(&dest->dst_lock);
-                               IP_VS_DBG_RL("ip_route_output error, "
-                                            "dest: %u.%u.%u.%u\n",
-                                            NIPQUAD(dest->addr.ip));
+                               IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n",
+                                            &dest->addr.ip);
                                return NULL;
                        }
                        __ip_vs_dst_set(dest, rtos, dst_clone(&rt->u.dst));
-                       IP_VS_DBG(10, "new dst %u.%u.%u.%u, refcnt=%d, rtos=%X\n",
-                                 NIPQUAD(dest->addr.ip),
+                       IP_VS_DBG(10, "new dst %pI4, refcnt=%d, rtos=%X\n",
+                                 &dest->addr.ip,
                                  atomic_read(&rt->u.dst.__refcnt), rtos);
                }
                spin_unlock(&dest->dst_lock);
@@ -104,8 +103,8 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos)
                };
 
                if (ip_route_output_key(&init_net, &rt, &fl)) {
-                       IP_VS_DBG_RL("ip_route_output error, dest: "
-                                    "%u.%u.%u.%u\n", NIPQUAD(cp->daddr.ip));
+                       IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n",
+                                    &cp->daddr.ip);
                        return NULL;
                }
        }
@@ -141,14 +140,13 @@ __ip_vs_get_out_rt_v6(struct ip_vs_conn *cp)
                                                                 NULL, &fl);
                        if (!rt) {
                                spin_unlock(&dest->dst_lock);
-                               IP_VS_DBG_RL("ip6_route_output error, "
-                                            "dest: " NIP6_FMT "\n",
-                                            NIP6(dest->addr.in6));
+                               IP_VS_DBG_RL("ip6_route_output error, dest: %pI6\n",
+                                            &dest->addr.in6);
                                return NULL;
                        }
                        __ip_vs_dst_set(dest, 0, dst_clone(&rt->u.dst));
-                       IP_VS_DBG(10, "new dst " NIP6_FMT ", refcnt=%d\n",
-                                 NIP6(dest->addr.in6),
+                       IP_VS_DBG(10, "new dst %pI6, refcnt=%d\n",
+                                 &dest->addr.in6,
                                  atomic_read(&rt->u.dst.__refcnt));
                }
                spin_unlock(&dest->dst_lock);
@@ -167,8 +165,8 @@ __ip_vs_get_out_rt_v6(struct ip_vs_conn *cp)
 
                rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl);
                if (!rt) {
-                       IP_VS_DBG_RL("ip6_route_output error, dest: "
-                                    NIP6_FMT "\n", NIP6(cp->daddr.in6));
+                       IP_VS_DBG_RL("ip6_route_output error, dest: %pI6\n",
+                                    &cp->daddr.in6);
                        return NULL;
                }
        }
@@ -237,8 +235,8 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
        EnterFunction(10);
 
        if (ip_route_output_key(&init_net, &rt, &fl)) {
-               IP_VS_DBG_RL("ip_vs_bypass_xmit(): ip_route_output error, "
-                            "dest: %u.%u.%u.%u\n", NIPQUAD(iph->daddr));
+               IP_VS_DBG_RL("ip_vs_bypass_xmit(): ip_route_output error, dest: %pI4\n",
+                            &iph->daddr);
                goto tx_error_icmp;
        }
 
@@ -301,8 +299,8 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 
        rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl);
        if (!rt) {
-               IP_VS_DBG_RL("ip_vs_bypass_xmit_v6(): ip6_route_output error, "
-                            "dest: " NIP6_FMT "\n", NIP6(iph->daddr));
+               IP_VS_DBG_RL("ip_vs_bypass_xmit_v6(): ip6_route_output error, dest: %pI6\n",
+                            &iph->daddr);
                goto tx_error_icmp;
        }
 
index b92df5c1dfcf395078ca2f766f57206f2ffad047..9fe8982bd7c905d67086b5073fd72df407dade7a 100644 (file)
@@ -35,7 +35,7 @@ static struct ctl_table acct_sysctl_table[] = {
                .data           = &init_net.ct.sysctl_acct,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {}
 };
index 4f7107107e9974655a47fa7715615774a2259bc1..629500901bd4d1eb5f2e05a03939ef06c24f2d62 100644 (file)
@@ -462,16 +462,13 @@ static int help(struct sk_buff *skb,
                   different IP address.  Simply don't record it for
                   NAT. */
                if (cmd.l3num == PF_INET) {
-                       pr_debug("conntrack_ftp: NOT RECORDING: " NIPQUAD_FMT
-                                " != " NIPQUAD_FMT "\n",
-                                NIPQUAD(cmd.u3.ip),
-                                NIPQUAD(ct->tuplehash[dir].tuple.src.u3.ip));
+                       pr_debug("conntrack_ftp: NOT RECORDING: %pI4 != %pI4\n",
+                                &cmd.u3.ip,
+                                &ct->tuplehash[dir].tuple.src.u3.ip);
                } else {
-                       pr_debug("conntrack_ftp: NOT RECORDING: " NIP6_FMT
-                                " != " NIP6_FMT "\n",
-                                NIP6(*((struct in6_addr *)cmd.u3.ip6)),
-                                NIP6(*((struct in6_addr *)
-                                       ct->tuplehash[dir].tuple.src.u3.ip6)));
+                       pr_debug("conntrack_ftp: NOT RECORDING: %pI6 != %pI6\n",
+                                cmd.u3.ip6,
+                                ct->tuplehash[dir].tuple.src.u3.ip6);
                }
 
                /* Thanks to Cristiano Lincoln Mattos
index c1504f71cdff08d8ad98685d73b2bba4e5a6c10f..99bc803d1dd14ae9e30dc83f53e1f5ae147c2ce2 100644 (file)
@@ -850,10 +850,8 @@ static int process_setup(struct sk_buff *skb, struct nf_conn *ct,
            get_h225_addr(ct, *data, &setup->destCallSignalAddress,
                          &addr, &port) &&
            memcmp(&addr, &ct->tuplehash[!dir].tuple.src.u3, sizeof(addr))) {
-               pr_debug("nf_ct_q931: set destCallSignalAddress "
-                        NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n",
-                        NIP6(*(struct in6_addr *)&addr), ntohs(port),
-                        NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.src.u3),
+               pr_debug("nf_ct_q931: set destCallSignalAddress %pI6:%hu->%pI6:%hu\n",
+                        &addr, ntohs(port), &ct->tuplehash[!dir].tuple.src.u3,
                         ntohs(ct->tuplehash[!dir].tuple.src.u.tcp.port));
                ret = set_h225_addr(skb, data, dataoff,
                                    &setup->destCallSignalAddress,
@@ -868,10 +866,8 @@ static int process_setup(struct sk_buff *skb, struct nf_conn *ct,
            get_h225_addr(ct, *data, &setup->sourceCallSignalAddress,
                          &addr, &port) &&
            memcmp(&addr, &ct->tuplehash[!dir].tuple.dst.u3, sizeof(addr))) {
-               pr_debug("nf_ct_q931: set sourceCallSignalAddress "
-                        NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n",
-                        NIP6(*(struct in6_addr *)&addr), ntohs(port),
-                        NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.dst.u3),
+               pr_debug("nf_ct_q931: set sourceCallSignalAddress %pI6:%hu->%pI6:%hu\n",
+                        &addr, ntohs(port), &ct->tuplehash[!dir].tuple.dst.u3,
                         ntohs(ct->tuplehash[!dir].tuple.dst.u.tcp.port));
                ret = set_h225_addr(skb, data, dataoff,
                                    &setup->sourceCallSignalAddress,
index 20633fdf7e6bb48b48e485b9ba0d110ab1f8459b..4d681a04447e4792d5371984975042c0612df345 100644 (file)
@@ -156,9 +156,9 @@ static int help(struct sk_buff *skb, unsigned int protoff,
                /* we have at least (19+MINMATCHLEN)-5 bytes valid data left */
 
                iph = ip_hdr(skb);
-               pr_debug("DCC found in master %u.%u.%u.%u:%u %u.%u.%u.%u:%u\n",
-                        NIPQUAD(iph->saddr), ntohs(th->source),
-                        NIPQUAD(iph->daddr), ntohs(th->dest));
+               pr_debug("DCC found in master %pI4:%u %pI4:%u\n",
+                        &iph->saddr, ntohs(th->source),
+                        &iph->daddr, ntohs(th->dest));
 
                for (i = 0; i < ARRAY_SIZE(dccprotos); i++) {
                        if (memcmp(data, dccprotos[i], strlen(dccprotos[i]))) {
@@ -185,10 +185,9 @@ static int help(struct sk_buff *skb, unsigned int protoff,
                            tuple->dst.u3.ip != htonl(dcc_ip)) {
                                if (net_ratelimit())
                                        printk(KERN_WARNING
-                                               "Forged DCC command from "
-                                               "%u.%u.%u.%u: %u.%u.%u.%u:%u\n",
-                                               NIPQUAD(tuple->src.u3.ip),
-                                               HIPQUAD(dcc_ip), dcc_port);
+                                               "Forged DCC command from %pI4: %pI4:%u\n",
+                                               &tuple->src.u3.ip,
+                                               &dcc_ip, dcc_port);
                                continue;
                        }
 
index dbe680af85d2daa2aa3aaceb2c668e48847de643..4be80d7b87958253f16e86bc550686544e06385d 100644 (file)
@@ -67,7 +67,7 @@ static struct ctl_table generic_sysctl_table[] = {
                .data           = &nf_ct_generic_timeout,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name       = 0
@@ -80,7 +80,7 @@ static struct ctl_table generic_compat_sysctl_table[] = {
                .data           = &nf_ct_generic_timeout,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name       = 0
index ae8c2609e230b6323598521f8cc606bac7c5074e..c2bd457bc2f24bcae0b0804a595a6368cdae1091 100644 (file)
@@ -548,49 +548,49 @@ static struct ctl_table sctp_sysctl_table[] = {
                .data           = &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_sctp_timeout_cookie_wait",
                .data           = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_sctp_timeout_cookie_echoed",
                .data           = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_sctp_timeout_established",
                .data           = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_sctp_timeout_shutdown_sent",
                .data           = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_sctp_timeout_shutdown_recd",
                .data           = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
                .data           = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name = 0
@@ -604,49 +604,49 @@ static struct ctl_table sctp_compat_sysctl_table[] = {
                .data           = &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_sctp_timeout_cookie_wait",
                .data           = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_sctp_timeout_cookie_echoed",
                .data           = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_sctp_timeout_established",
                .data           = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_sctp_timeout_shutdown_sent",
                .data           = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_sctp_timeout_shutdown_recd",
                .data           = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_sctp_timeout_shutdown_ack_sent",
                .data           = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name = 0
index f947ec41e391f7ae565f6017ae51feae29b0487a..a1edb9c1adee8625e5d81800c0fa8bb96ec483cc 100644 (file)
@@ -1192,70 +1192,70 @@ static struct ctl_table tcp_sysctl_table[] = {
                .data           = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_syn_recv",
                .data           = &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_established",
                .data           = &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_fin_wait",
                .data           = &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_close_wait",
                .data           = &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_last_ack",
                .data           = &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_time_wait",
                .data           = &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_close",
                .data           = &tcp_timeouts[TCP_CONNTRACK_CLOSE],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_max_retrans",
                .data           = &nf_ct_tcp_timeout_max_retrans,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_unacknowledged",
                .data           = &nf_ct_tcp_timeout_unacknowledged,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name       = NET_NF_CONNTRACK_TCP_LOOSE,
@@ -1263,7 +1263,7 @@ static struct ctl_table tcp_sysctl_table[] = {
                .data           = &nf_ct_tcp_loose,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_NF_CONNTRACK_TCP_BE_LIBERAL,
@@ -1271,7 +1271,7 @@ static struct ctl_table tcp_sysctl_table[] = {
                .data           = &nf_ct_tcp_be_liberal,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_NF_CONNTRACK_TCP_MAX_RETRANS,
@@ -1279,7 +1279,7 @@ static struct ctl_table tcp_sysctl_table[] = {
                .data           = &nf_ct_tcp_max_retrans,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = 0
@@ -1293,63 +1293,63 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
                .data           = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_tcp_timeout_syn_recv",
                .data           = &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_tcp_timeout_established",
                .data           = &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_tcp_timeout_fin_wait",
                .data           = &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_tcp_timeout_close_wait",
                .data           = &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_tcp_timeout_last_ack",
                .data           = &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_tcp_timeout_time_wait",
                .data           = &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_tcp_timeout_close",
                .data           = &tcp_timeouts[TCP_CONNTRACK_CLOSE],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_tcp_timeout_max_retrans",
                .data           = &nf_ct_tcp_timeout_max_retrans,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_LOOSE,
@@ -1357,7 +1357,7 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
                .data           = &nf_ct_tcp_loose,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL,
@@ -1365,7 +1365,7 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
                .data           = &nf_ct_tcp_be_liberal,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS,
@@ -1373,7 +1373,7 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
                .data           = &nf_ct_tcp_max_retrans,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = 0
index 7c2ca48698bed1d4ea1ea2b54375e9aa4aecbb89..2b8b1f579f930f523e4733073a176a95ef29549b 100644 (file)
@@ -143,14 +143,14 @@ static struct ctl_table udp_sysctl_table[] = {
                .data           = &nf_ct_udp_timeout,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_udp_timeout_stream",
                .data           = &nf_ct_udp_timeout_stream,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name       = 0
@@ -163,14 +163,14 @@ static struct ctl_table udp_compat_sysctl_table[] = {
                .data           = &nf_ct_udp_timeout,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_udp_timeout_stream",
                .data           = &nf_ct_udp_timeout_stream,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name       = 0
index d22d839e4f94b9f3f1466e666c5f1fe3a425f9a2..4579d8de13b15d75f69181c7e4bd36ed3d7e39db 100644 (file)
@@ -151,7 +151,7 @@ static struct ctl_table udplite_sysctl_table[] = {
                .data           = &nf_ct_udplite_timeout,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name       = CTL_UNNUMBERED,
@@ -159,7 +159,7 @@ static struct ctl_table udplite_sysctl_table[] = {
                .data           = &nf_ct_udplite_timeout_stream,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
+               .proc_handler   = proc_dointvec_jiffies,
        },
        {
                .ctl_name       = 0
index 98106d4e89f033f5d6e22b17a0de9b2d6a709b5d..f37b9b74c6a8c78ea372569d4ffba09f69be9f9d 100644 (file)
@@ -336,7 +336,7 @@ static ctl_table nf_ct_sysctl_table[] = {
                .data           = &nf_conntrack_max,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_NF_CONNTRACK_COUNT,
@@ -344,7 +344,7 @@ static ctl_table nf_ct_sysctl_table[] = {
                .data           = &init_net.ct.count,
                .maxlen         = sizeof(int),
                .mode           = 0444,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_NF_CONNTRACK_BUCKETS,
@@ -352,7 +352,7 @@ static ctl_table nf_ct_sysctl_table[] = {
                .data           = &nf_conntrack_htable_size,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0444,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_NF_CONNTRACK_CHECKSUM,
@@ -360,7 +360,7 @@ static ctl_table nf_ct_sysctl_table[] = {
                .data           = &init_net.ct.sysctl_checksum,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = NET_NF_CONNTRACK_LOG_INVALID,
@@ -368,8 +368,8 @@ static ctl_table nf_ct_sysctl_table[] = {
                .data           = &init_net.ct.sysctl_log_invalid,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &log_invalid_proto_min,
                .extra2         = &log_invalid_proto_max,
        },
@@ -379,7 +379,7 @@ static ctl_table nf_ct_sysctl_table[] = {
                .data           = &nf_ct_expect_max,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        { .ctl_name = 0 }
 };
@@ -393,7 +393,7 @@ static ctl_table nf_ct_netfilter_table[] = {
                .data           = &nf_conntrack_max,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        { .ctl_name = 0 }
 };
index 6fc4292d46e6b33e18863878285af99ef34af3e7..f97fded024c46d5d8c28c57b2146b0c2c5e14c67 100644 (file)
@@ -893,23 +893,21 @@ static int dl_seq_real_show(struct dsthash_ent *ent, u_int8_t family,
 
        switch (family) {
        case NFPROTO_IPV4:
-               return seq_printf(s, "%ld %u.%u.%u.%u:%u->"
-                                    "%u.%u.%u.%u:%u %u %u %u\n",
+               return seq_printf(s, "%ld %pI4:%u->%pI4:%u %u %u %u\n",
                                 (long)(ent->expires - jiffies)/HZ,
-                                NIPQUAD(ent->dst.ip.src),
+                                &ent->dst.ip.src,
                                 ntohs(ent->dst.src_port),
-                                NIPQUAD(ent->dst.ip.dst),
+                                &ent->dst.ip.dst,
                                 ntohs(ent->dst.dst_port),
                                 ent->rateinfo.credit, ent->rateinfo.credit_cap,
                                 ent->rateinfo.cost);
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
        case NFPROTO_IPV6:
-               return seq_printf(s, "%ld " NIP6_FMT ":%u->"
-                                    NIP6_FMT ":%u %u %u %u\n",
+               return seq_printf(s, "%ld %pI6:%u->%pI6:%u %u %u %u\n",
                                 (long)(ent->expires - jiffies)/HZ,
-                                NIP6(*(struct in6_addr *)&ent->dst.ip6.src),
+                                &ent->dst.ip6.src,
                                 ntohs(ent->dst.src_port),
-                                NIP6(*(struct in6_addr *)&ent->dst.ip6.dst),
+                                &ent->dst.ip6.dst,
                                 ntohs(ent->dst.dst_port),
                                 ent->rateinfo.credit, ent->rateinfo.credit_cap,
                                 ent->rateinfo.cost);
index 7ac54eab0b00a6a0249afcc43ca6afea807410a0..501f9b6231886cb21fcf112f8fbbf01ed8ca2a76 100644 (file)
@@ -26,12 +26,11 @@ iprange_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
                if ((ntohl(iph->saddr) < ntohl(info->src.min_ip)
                          || ntohl(iph->saddr) > ntohl(info->src.max_ip))
                         ^ !!(info->flags & IPRANGE_SRC_INV)) {
-                       pr_debug("src IP %u.%u.%u.%u NOT in range %s"
-                                "%u.%u.%u.%u-%u.%u.%u.%u\n",
-                                NIPQUAD(iph->saddr),
+                       pr_debug("src IP %pI4 NOT in range %s%pI4-%pI4\n",
+                                &iph->saddr,
                                 info->flags & IPRANGE_SRC_INV ? "(INV) " : "",
-                                NIPQUAD(info->src.min_ip),
-                                NIPQUAD(info->src.max_ip));
+                                &info->src.min_ip,
+                                &info->src.max_ip);
                        return false;
                }
        }
@@ -39,12 +38,11 @@ iprange_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
                if ((ntohl(iph->daddr) < ntohl(info->dst.min_ip)
                          || ntohl(iph->daddr) > ntohl(info->dst.max_ip))
                         ^ !!(info->flags & IPRANGE_DST_INV)) {
-                       pr_debug("dst IP %u.%u.%u.%u NOT in range %s"
-                                "%u.%u.%u.%u-%u.%u.%u.%u\n",
-                                NIPQUAD(iph->daddr),
+                       pr_debug("dst IP %pI4 NOT in range %s%pI4-%pI4\n",
+                                &iph->daddr,
                                 info->flags & IPRANGE_DST_INV ? "(INV) " : "",
-                                NIPQUAD(info->dst.min_ip),
-                                NIPQUAD(info->dst.max_ip));
+                                &info->dst.min_ip,
+                                &info->dst.max_ip);
                        return false;
                }
        }
@@ -63,12 +61,11 @@ iprange_mt4(const struct sk_buff *skb, const struct xt_match_param *par)
                m |= ntohl(iph->saddr) > ntohl(info->src_max.ip);
                m ^= !!(info->flags & IPRANGE_SRC_INV);
                if (m) {
-                       pr_debug("src IP " NIPQUAD_FMT " NOT in range %s"
-                                NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
-                                NIPQUAD(iph->saddr),
+                       pr_debug("src IP %pI4 NOT in range %s%pI4-%pI4\n",
+                                &iph->saddr,
                                 (info->flags & IPRANGE_SRC_INV) ? "(INV) " : "",
-                                NIPQUAD(info->src_max.ip),
-                                NIPQUAD(info->src_max.ip));
+                                &info->src_max.ip,
+                                &info->src_max.ip);
                        return false;
                }
        }
@@ -77,12 +74,11 @@ iprange_mt4(const struct sk_buff *skb, const struct xt_match_param *par)
                m |= ntohl(iph->daddr) > ntohl(info->dst_max.ip);
                m ^= !!(info->flags & IPRANGE_DST_INV);
                if (m) {
-                       pr_debug("dst IP " NIPQUAD_FMT " NOT in range %s"
-                                NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
-                                NIPQUAD(iph->daddr),
+                       pr_debug("dst IP %pI4 NOT in range %s%pI4-%pI4\n",
+                                &iph->daddr,
                                 (info->flags & IPRANGE_DST_INV) ? "(INV) " : "",
-                                NIPQUAD(info->dst_min.ip),
-                                NIPQUAD(info->dst_max.ip));
+                                &info->dst_min.ip,
+                                &info->dst_max.ip);
                        return false;
                }
        }
index 280c471bcdf444fdc2228a46895c2b44baf8d549..3c3dd22b1d061e946079261d00670158d9ff4b9e 100644 (file)
@@ -422,13 +422,11 @@ static int recent_seq_show(struct seq_file *seq, void *v)
 
        i = (e->index - 1) % ip_pkt_list_tot;
        if (e->family == NFPROTO_IPV4)
-               seq_printf(seq, "src=" NIPQUAD_FMT " ttl: %u last_seen: %lu "
-                          "oldest_pkt: %u", NIPQUAD(e->addr.ip), e->ttl,
-                          e->stamps[i], e->index);
+               seq_printf(seq, "src=%pI4 ttl: %u last_seen: %lu oldest_pkt: %u",
+                          &e->addr.ip, e->ttl, e->stamps[i], e->index);
        else
-               seq_printf(seq, "src=" NIP6_FMT " ttl: %u last_seen: %lu "
-                          "oldest_pkt: %u", NIP6(e->addr.in6), e->ttl,
-                          e->stamps[i], e->index);
+               seq_printf(seq, "src=%pI6 ttl: %u last_seen: %lu oldest_pkt: %u",
+                          &e->addr.in6, e->ttl, e->stamps[i], e->index);
        for (i = 0; i < e->nstamps; i++)
                seq_printf(seq, "%s %lu", i ? "," : "", e->stamps[i]);
        seq_printf(seq, "\n");
index 249f6b92f153b675cb7895b0b3b4f57b8fb74799..834c6eb7f484cfe9ccab1523ac4f8733d6c6dda8 100644 (file)
@@ -337,7 +337,7 @@ void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf,
 
        if (dev != NULL)
                audit_log_format(audit_buf, " netif=%s", dev);
-       audit_log_format(audit_buf, " %s=" NIPQUAD_FMT, dir, NIPQUAD(addr));
+       audit_log_format(audit_buf, " %s=%pI4", dir, &addr);
        if (mask_val != 0xffffffff) {
                u32 mask_len = 0;
                while (mask_val > 0) {
@@ -371,7 +371,7 @@ void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf,
 
        if (dev != NULL)
                audit_log_format(audit_buf, " netif=%s", dev);
-       audit_log_format(audit_buf, " %s=" NIP6_FMT, dir, NIP6(*addr));
+       audit_log_format(audit_buf, " %s=%pI6", dir, addr);
        if (ntohl(mask->s6_addr32[3]) != 0xffffffff) {
                u32 mask_len = 0;
                u32 mask_val;
index 2d106cfe1d276bf5e234195753eb091cba7b7f1e..c83fea7da9a8246dce2b4fb137e357c395a83f9f 100644 (file)
@@ -233,7 +233,7 @@ size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
  *
  * Returns the number of bytes copied.
  */
-int nla_memcpy(void *dest, struct nlattr *src, int count)
+int nla_memcpy(void *dest, const struct nlattr *src, int count)
 {
        int minlen = min_t(int, count, nla_len(src));
 
index 34c96c9674dfd838c9061d2a0afde9211ea4bed3..7b49591fe87c7e4dccdfb521db62cf306f641266 100644 (file)
@@ -41,8 +41,8 @@ static ctl_table nr_table[] = {
                .data           = &sysctl_netrom_default_path_quality,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_quality,
                .extra2         = &max_quality
        },
@@ -52,8 +52,8 @@ static ctl_table nr_table[] = {
                .data           = &sysctl_netrom_obsolescence_count_initialiser,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_obs,
                .extra2         = &max_obs
        },
@@ -63,8 +63,8 @@ static ctl_table nr_table[] = {
                .data           = &sysctl_netrom_network_ttl_initialiser,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_ttl,
                .extra2         = &max_ttl
        },
@@ -74,8 +74,8 @@ static ctl_table nr_table[] = {
                .data           = &sysctl_netrom_transport_timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_t1,
                .extra2         = &max_t1
        },
@@ -85,8 +85,8 @@ static ctl_table nr_table[] = {
                .data           = &sysctl_netrom_transport_maximum_tries,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_n2,
                .extra2         = &max_n2
        },
@@ -96,8 +96,8 @@ static ctl_table nr_table[] = {
                .data           = &sysctl_netrom_transport_acknowledge_delay,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_t2,
                .extra2         = &max_t2
        },
@@ -107,8 +107,8 @@ static ctl_table nr_table[] = {
                .data           = &sysctl_netrom_transport_busy_delay,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_t4,
                .extra2         = &max_t4
        },
@@ -118,8 +118,8 @@ static ctl_table nr_table[] = {
                .data           = &sysctl_netrom_transport_requested_window_size,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_window,
                .extra2         = &max_window
        },
@@ -129,8 +129,8 @@ static ctl_table nr_table[] = {
                .data           = &sysctl_netrom_transport_no_activity_timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_idle,
                .extra2         = &max_idle
        },
@@ -140,8 +140,8 @@ static ctl_table nr_table[] = {
                .data           = &sysctl_netrom_routing_control,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_route,
                .extra2         = &max_route
        },
@@ -151,8 +151,8 @@ static ctl_table nr_table[] = {
                .data           = &sysctl_netrom_link_fails_count,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_fails,
                .extra2         = &max_fails
        },
@@ -162,8 +162,8 @@ static ctl_table nr_table[] = {
                .data           = &sysctl_netrom_reset_circuit,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_reset,
                .extra2         = &max_reset
        },
index 7ab30f668b5a8226a6342118c96322e33f04a0c4..62af1d8a8dd2d8ea03ea429199a165f27bd05316 100644 (file)
 
 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);
+
+static inline void phonet_proto_put(struct phonet_protocol *pp)
+{
+       module_put(pp->prot->owner);
+}
 
 /* protocol family functions */
 
@@ -428,11 +432,6 @@ static struct phonet_protocol *phonet_proto_get(int protocol)
        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)
 {
index 9978afbd9f2ad5033375df896358f88b929ecfcc..e6e8e44852e51187990d38695d7ed108c1a935a4 100644 (file)
@@ -41,7 +41,6 @@ struct gprs_dev {
        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;
@@ -49,14 +48,14 @@ struct gprs_dev {
        unsigned                tx_max;
 };
 
-static int gprs_type_trans(struct sk_buff *skb)
+static __be16 gprs_type_trans(struct sk_buff *skb)
 {
        const u8 *pvfc;
        u8 buf;
 
        pvfc = skb_header_pointer(skb, 0, 1, &buf);
        if (!pvfc)
-               return 0;
+               return htons(0);
        /* Look at IP version field */
        switch (*pvfc >> 4) {
        case 4:
@@ -64,7 +63,7 @@ static int gprs_type_trans(struct sk_buff *skb)
        case 6:
                return htons(ETH_P_IPV6);
        }
-       return 0;
+       return htons(0);
 }
 
 /*
@@ -83,8 +82,9 @@ static void gprs_state_change(struct sock *sk)
 
 static int gprs_recv(struct gprs_dev *dev, struct sk_buff *skb)
 {
+       struct net_device *net = dev->net;
        int err = 0;
-       u16 protocol = gprs_type_trans(skb);
+       __be16 protocol = gprs_type_trans(skb);
 
        if (!protocol) {
                err = -EINVAL;
@@ -99,7 +99,7 @@ static int gprs_recv(struct gprs_dev *dev, struct sk_buff *skb)
                 * 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);
+               rskb = netdev_alloc_skb(net, 0);
                if (!rskb) {
                        err = -ENOBUFS;
                        goto drop;
@@ -123,11 +123,11 @@ static int gprs_recv(struct gprs_dev *dev, struct sk_buff *skb)
 
        skb->protocol = protocol;
        skb_reset_mac_header(skb);
-       skb->dev = dev->net;
+       skb->dev = net;
 
-       if (likely(dev->net->flags & IFF_UP)) {
-               dev->stats.rx_packets++;
-               dev->stats.rx_bytes += skb->len;
+       if (likely(net->flags & IFF_UP)) {
+               net->stats.rx_packets++;
+               net->stats.rx_bytes += skb->len;
                netif_rx(skb);
                skb = NULL;
        } else
@@ -136,7 +136,7 @@ static int gprs_recv(struct gprs_dev *dev, struct sk_buff *skb)
 drop:
        if (skb) {
                dev_kfree_skb(skb);
-               dev->stats.rx_dropped++;
+               net->stats.rx_dropped++;
        }
        return err;
 }
@@ -199,14 +199,15 @@ static int gprs_xmit(struct sk_buff *skb, struct net_device *net)
 static void gprs_tx(struct work_struct *work)
 {
        struct gprs_dev *dev = container_of(work, struct gprs_dev, tx_work);
+       struct net_device *net = dev->net;
        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++;
+               net->stats.tx_bytes += skb->len;
+               net->stats.tx_packets++;
 
                skb_orphan(skb);
                skb_set_owner_w(skb, sk);
@@ -215,9 +216,9 @@ static void gprs_tx(struct work_struct *work)
                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++;
+                                       net->name, err);
+                       net->stats.tx_aborted_errors++;
+                       net->stats.tx_errors++;
                }
                release_sock(sk);
        }
@@ -236,13 +237,6 @@ static int gprs_set_mtu(struct net_device *net, int 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;
@@ -256,7 +250,6 @@ static void gprs_setup(struct net_device *net)
        net->destructor         = free_netdev;
        net->hard_start_xmit    = gprs_xmit; /* mandatory */
        net->change_mtu         = gprs_set_mtu;
-       net->get_stats          = gprs_get_stats;
 }
 
 /*
index 600a4309b8c8f447c4f8560cf0a8095adf4a5b1d..0e3347bbdb123099868f275944db9a2c6743065f 100644 (file)
@@ -89,7 +89,7 @@ static struct ctl_table phonet_table[] = {
                .data           = &local_port_range,
                .maxlen         = sizeof(local_port_range),
                .mode           = 0644,
-               .proc_handler   = &proc_local_port_range,
+               .proc_handler   = proc_local_port_range,
                .strategy       = NULL,
        },
        { .ctl_name = 0 }
index bfdade72e066f65c52a3bd82a70807b51de6a3f0..84efde97c5a773fe027d051cb3522e55534b8eb1 100644 (file)
@@ -24,138 +24,318 @@ MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
 MODULE_DESCRIPTION("Input layer to RF switch connector");
 MODULE_LICENSE("GPL");
 
+enum rfkill_input_master_mode {
+       RFKILL_INPUT_MASTER_DONOTHING = 0,
+       RFKILL_INPUT_MASTER_RESTORE = 1,
+       RFKILL_INPUT_MASTER_UNBLOCKALL = 2,
+       RFKILL_INPUT_MASTER_MAX,        /* marker */
+};
+
+/* Delay (in ms) between consecutive switch ops */
+#define RFKILL_OPS_DELAY 200
+
+static enum rfkill_input_master_mode rfkill_master_switch_mode =
+                                       RFKILL_INPUT_MASTER_UNBLOCKALL;
+module_param_named(master_switch_mode, rfkill_master_switch_mode, uint, 0);
+MODULE_PARM_DESC(master_switch_mode,
+       "SW_RFKILL_ALL ON should: 0=do nothing; 1=restore; 2=unblock all");
+
+enum rfkill_global_sched_op {
+       RFKILL_GLOBAL_OP_EPO = 0,
+       RFKILL_GLOBAL_OP_RESTORE,
+       RFKILL_GLOBAL_OP_UNLOCK,
+       RFKILL_GLOBAL_OP_UNBLOCK,
+};
+
+/*
+ * Currently, the code marked with RFKILL_NEED_SWSET is inactive.
+ * If handling of EV_SW SW_WLAN/WWAN/BLUETOOTH/etc is needed in the
+ * future, when such events are added, that code will be necessary.
+ */
+
 struct rfkill_task {
-       struct work_struct work;
-       enum rfkill_type type;
-       struct mutex mutex; /* ensures that task is serialized */
-       spinlock_t lock; /* for accessing last and desired state */
-       unsigned long last; /* last schedule */
-       enum rfkill_state desired_state; /* on/off */
+       struct delayed_work dwork;
+
+       /* ensures that task is serialized */
+       struct mutex mutex;
+
+       /* protects everything below */
+       spinlock_t lock;
+
+       /* pending regular switch operations (1=pending) */
+       unsigned long sw_pending[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
+
+#ifdef RFKILL_NEED_SWSET
+       /* set operation pending (1=pending) */
+       unsigned long sw_setpending[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
+
+       /* desired state for pending set operation (1=unblock) */
+       unsigned long sw_newstate[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
+#endif
+
+       /* should the state be complemented (1=yes) */
+       unsigned long sw_togglestate[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
+
+       bool global_op_pending;
+       enum rfkill_global_sched_op op;
+
+       /* last time it was scheduled */
+       unsigned long last_scheduled;
 };
 
+static void __rfkill_handle_global_op(enum rfkill_global_sched_op op)
+{
+       unsigned int i;
+
+       switch (op) {
+       case RFKILL_GLOBAL_OP_EPO:
+               rfkill_epo();
+               break;
+       case RFKILL_GLOBAL_OP_RESTORE:
+               rfkill_restore_states();
+               break;
+       case RFKILL_GLOBAL_OP_UNLOCK:
+               rfkill_remove_epo_lock();
+               break;
+       case RFKILL_GLOBAL_OP_UNBLOCK:
+               rfkill_remove_epo_lock();
+               for (i = 0; i < RFKILL_TYPE_MAX; i++)
+                       rfkill_switch_all(i, RFKILL_STATE_UNBLOCKED);
+               break;
+       default:
+               /* memory corruption or bug, fail safely */
+               rfkill_epo();
+               WARN(1, "Unknown requested operation %d! "
+                       "rfkill Emergency Power Off activated\n",
+                       op);
+       }
+}
+
+#ifdef RFKILL_NEED_SWSET
+static void __rfkill_handle_normal_op(const enum rfkill_type type,
+                       const bool sp, const bool s, const bool c)
+{
+       enum rfkill_state state;
+
+       if (sp)
+               state = (s) ? RFKILL_STATE_UNBLOCKED :
+                             RFKILL_STATE_SOFT_BLOCKED;
+       else
+               state = rfkill_get_global_state(type);
+
+       if (c)
+               state = rfkill_state_complement(state);
+
+       rfkill_switch_all(type, state);
+}
+#else
+static void __rfkill_handle_normal_op(const enum rfkill_type type,
+                       const bool c)
+{
+       enum rfkill_state state;
+
+       state = rfkill_get_global_state(type);
+       if (c)
+               state = rfkill_state_complement(state);
+
+       rfkill_switch_all(type, state);
+}
+#endif
+
 static void rfkill_task_handler(struct work_struct *work)
 {
-       struct rfkill_task *task = container_of(work, struct rfkill_task, work);
+       struct rfkill_task *task = container_of(work,
+                                       struct rfkill_task, dwork.work);
+       bool doit = true;
 
        mutex_lock(&task->mutex);
 
-       rfkill_switch_all(task->type, task->desired_state);
+       spin_lock_irq(&task->lock);
+       while (doit) {
+               if (task->global_op_pending) {
+                       enum rfkill_global_sched_op op = task->op;
+                       task->global_op_pending = false;
+                       memset(task->sw_pending, 0, sizeof(task->sw_pending));
+                       spin_unlock_irq(&task->lock);
+
+                       __rfkill_handle_global_op(op);
+
+                       /* make sure we do at least one pass with
+                        * !task->global_op_pending */
+                       spin_lock_irq(&task->lock);
+                       continue;
+               } else if (!rfkill_is_epo_lock_active()) {
+                       unsigned int i = 0;
+
+                       while (!task->global_op_pending &&
+                                               i < RFKILL_TYPE_MAX) {
+                               if (test_and_clear_bit(i, task->sw_pending)) {
+                                       bool c;
+#ifdef RFKILL_NEED_SWSET
+                                       bool sp, s;
+                                       sp = test_and_clear_bit(i,
+                                                       task->sw_setpending);
+                                       s = test_bit(i, task->sw_newstate);
+#endif
+                                       c = test_and_clear_bit(i,
+                                                       task->sw_togglestate);
+                                       spin_unlock_irq(&task->lock);
+
+#ifdef RFKILL_NEED_SWSET
+                                       __rfkill_handle_normal_op(i, sp, s, c);
+#else
+                                       __rfkill_handle_normal_op(i, c);
+#endif
+
+                                       spin_lock_irq(&task->lock);
+                               }
+                               i++;
+                       }
+               }
+               doit = task->global_op_pending;
+       }
+       spin_unlock_irq(&task->lock);
 
        mutex_unlock(&task->mutex);
 }
 
-static void rfkill_task_epo_handler(struct work_struct *work)
+static struct rfkill_task rfkill_task = {
+       .dwork = __DELAYED_WORK_INITIALIZER(rfkill_task.dwork,
+                               rfkill_task_handler),
+       .mutex = __MUTEX_INITIALIZER(rfkill_task.mutex),
+       .lock = __SPIN_LOCK_UNLOCKED(rfkill_task.lock),
+};
+
+static unsigned long rfkill_ratelimit(const unsigned long last)
 {
-       rfkill_epo();
+       const unsigned long delay = msecs_to_jiffies(RFKILL_OPS_DELAY);
+       return (time_after(jiffies, last + delay)) ? 0 : delay;
 }
 
-static DECLARE_WORK(epo_work, rfkill_task_epo_handler);
+static void rfkill_schedule_ratelimited(void)
+{
+       if (!delayed_work_pending(&rfkill_task.dwork)) {
+               schedule_delayed_work(&rfkill_task.dwork,
+                               rfkill_ratelimit(rfkill_task.last_scheduled));
+               rfkill_task.last_scheduled = jiffies;
+       }
+}
 
-static void rfkill_schedule_epo(void)
+static void rfkill_schedule_global_op(enum rfkill_global_sched_op op)
 {
-       schedule_work(&epo_work);
+       unsigned long flags;
+
+       spin_lock_irqsave(&rfkill_task.lock, flags);
+       rfkill_task.op = op;
+       rfkill_task.global_op_pending = true;
+       if (op == RFKILL_GLOBAL_OP_EPO && !rfkill_is_epo_lock_active()) {
+               /* bypass the limiter for EPO */
+               cancel_delayed_work(&rfkill_task.dwork);
+               schedule_delayed_work(&rfkill_task.dwork, 0);
+               rfkill_task.last_scheduled = jiffies;
+       } else
+               rfkill_schedule_ratelimited();
+       spin_unlock_irqrestore(&rfkill_task.lock, flags);
 }
 
-static void rfkill_schedule_set(struct rfkill_task *task,
+#ifdef RFKILL_NEED_SWSET
+/* Use this if you need to add EV_SW SW_WLAN/WWAN/BLUETOOTH/etc handling */
+
+static void rfkill_schedule_set(enum rfkill_type type,
                                enum rfkill_state desired_state)
 {
        unsigned long flags;
 
-       if (unlikely(work_pending(&epo_work)))
+       if (rfkill_is_epo_lock_active())
                return;
 
-       spin_lock_irqsave(&task->lock, flags);
-
-       if (time_after(jiffies, task->last + msecs_to_jiffies(200))) {
-               task->desired_state = desired_state;
-               task->last = jiffies;
-               schedule_work(&task->work);
+       spin_lock_irqsave(&rfkill_task.lock, flags);
+       if (!rfkill_task.global_op_pending) {
+               set_bit(type, rfkill_task.sw_pending);
+               set_bit(type, rfkill_task.sw_setpending);
+               clear_bit(type, rfkill_task.sw_togglestate);
+               if (desired_state)
+                       set_bit(type,  rfkill_task.sw_newstate);
+               else
+                       clear_bit(type, rfkill_task.sw_newstate);
+               rfkill_schedule_ratelimited();
        }
-
-       spin_unlock_irqrestore(&task->lock, flags);
+       spin_unlock_irqrestore(&rfkill_task.lock, flags);
 }
+#endif
 
-static void rfkill_schedule_toggle(struct rfkill_task *task)
+static void rfkill_schedule_toggle(enum rfkill_type type)
 {
        unsigned long flags;
 
-       if (unlikely(work_pending(&epo_work)))
+       if (rfkill_is_epo_lock_active())
                return;
 
-       spin_lock_irqsave(&task->lock, flags);
-
-       if (time_after(jiffies, task->last + msecs_to_jiffies(200))) {
-               task->desired_state =
-                               rfkill_state_complement(task->desired_state);
-               task->last = jiffies;
-               schedule_work(&task->work);
+       spin_lock_irqsave(&rfkill_task.lock, flags);
+       if (!rfkill_task.global_op_pending) {
+               set_bit(type, rfkill_task.sw_pending);
+               change_bit(type, rfkill_task.sw_togglestate);
+               rfkill_schedule_ratelimited();
        }
-
-       spin_unlock_irqrestore(&task->lock, flags);
+       spin_unlock_irqrestore(&rfkill_task.lock, flags);
 }
 
-#define DEFINE_RFKILL_TASK(n, t)                               \
-       struct rfkill_task n = {                                \
-               .work = __WORK_INITIALIZER(n.work,              \
-                               rfkill_task_handler),           \
-               .type = t,                                      \
-               .mutex = __MUTEX_INITIALIZER(n.mutex),          \
-               .lock = __SPIN_LOCK_UNLOCKED(n.lock),           \
-               .desired_state = RFKILL_STATE_UNBLOCKED,        \
-       }
-
-static DEFINE_RFKILL_TASK(rfkill_wlan, RFKILL_TYPE_WLAN);
-static DEFINE_RFKILL_TASK(rfkill_bt, RFKILL_TYPE_BLUETOOTH);
-static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB);
-static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX);
-static DEFINE_RFKILL_TASK(rfkill_wwan, RFKILL_TYPE_WWAN);
-
 static void rfkill_schedule_evsw_rfkillall(int state)
 {
-       /* EVERY radio type. state != 0 means radios ON */
-       /* handle EPO (emergency power off) through shortcut */
        if (state) {
-               rfkill_schedule_set(&rfkill_wwan,
-                                   RFKILL_STATE_UNBLOCKED);
-               rfkill_schedule_set(&rfkill_wimax,
-                                   RFKILL_STATE_UNBLOCKED);
-               rfkill_schedule_set(&rfkill_uwb,
-                                   RFKILL_STATE_UNBLOCKED);
-               rfkill_schedule_set(&rfkill_bt,
-                                   RFKILL_STATE_UNBLOCKED);
-               rfkill_schedule_set(&rfkill_wlan,
-                                   RFKILL_STATE_UNBLOCKED);
+               switch (rfkill_master_switch_mode) {
+               case RFKILL_INPUT_MASTER_UNBLOCKALL:
+                       rfkill_schedule_global_op(RFKILL_GLOBAL_OP_UNBLOCK);
+                       break;
+               case RFKILL_INPUT_MASTER_RESTORE:
+                       rfkill_schedule_global_op(RFKILL_GLOBAL_OP_RESTORE);
+                       break;
+               case RFKILL_INPUT_MASTER_DONOTHING:
+                       rfkill_schedule_global_op(RFKILL_GLOBAL_OP_UNLOCK);
+                       break;
+               default:
+                       /* memory corruption or driver bug! fail safely */
+                       rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO);
+                       WARN(1, "Unknown rfkill_master_switch_mode (%d), "
+                               "driver bug or memory corruption detected!\n",
+                               rfkill_master_switch_mode);
+                       break;
+               }
        } else
-               rfkill_schedule_epo();
+               rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO);
 }
 
 static void rfkill_event(struct input_handle *handle, unsigned int type,
                        unsigned int code, int data)
 {
        if (type == EV_KEY && data == 1) {
+               enum rfkill_type t;
+
                switch (code) {
                case KEY_WLAN:
-                       rfkill_schedule_toggle(&rfkill_wlan);
+                       t = RFKILL_TYPE_WLAN;
                        break;
                case KEY_BLUETOOTH:
-                       rfkill_schedule_toggle(&rfkill_bt);
+                       t = RFKILL_TYPE_BLUETOOTH;
                        break;
                case KEY_UWB:
-                       rfkill_schedule_toggle(&rfkill_uwb);
+                       t = RFKILL_TYPE_UWB;
                        break;
                case KEY_WIMAX:
-                       rfkill_schedule_toggle(&rfkill_wimax);
+                       t = RFKILL_TYPE_WIMAX;
                        break;
                default:
-                       break;
+                       return;
                }
+               rfkill_schedule_toggle(t);
+               return;
        } else if (type == EV_SW) {
                switch (code) {
                case SW_RFKILL_ALL:
                        rfkill_schedule_evsw_rfkillall(data);
-                       break;
+                       return;
                default:
-                       break;
+                       return;
                }
        }
 }
@@ -256,18 +436,23 @@ static struct input_handler rfkill_handler = {
 
 static int __init rfkill_handler_init(void)
 {
-       unsigned long last_run = jiffies - msecs_to_jiffies(500);
-       rfkill_wlan.last = last_run;
-       rfkill_bt.last = last_run;
-       rfkill_uwb.last = last_run;
-       rfkill_wimax.last = last_run;
+       if (rfkill_master_switch_mode >= RFKILL_INPUT_MASTER_MAX)
+               return -EINVAL;
+
+       /*
+        * The penalty to not doing this is a possible RFKILL_OPS_DELAY delay
+        * at the first use.  Acceptable, but if we can avoid it, why not?
+        */
+       rfkill_task.last_scheduled =
+                       jiffies - msecs_to_jiffies(RFKILL_OPS_DELAY) - 1;
        return input_register_handler(&rfkill_handler);
 }
 
 static void __exit rfkill_handler_exit(void)
 {
        input_unregister_handler(&rfkill_handler);
-       flush_scheduled_work();
+       cancel_delayed_work_sync(&rfkill_task.dwork);
+       rfkill_remove_epo_lock();
 }
 
 module_init(rfkill_handler_init);
index bbfa646157c63a1668968bf90658f81ac3f976ad..fe8df6b5b935f4b9a3848f646c3d074e906c22f6 100644 (file)
@@ -14,5 +14,8 @@
 void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state);
 void rfkill_epo(void);
 void rfkill_restore_states(void);
+void rfkill_remove_epo_lock(void);
+bool rfkill_is_epo_lock_active(void);
+enum rfkill_state rfkill_get_global_state(const enum rfkill_type type);
 
 #endif /* __RFKILL_INPUT_H */
index 25ba3bd57e66405e64adef4455b66614fd273ea6..ec26eae8004d5c298d0e6c175e563c309532b7f9 100644 (file)
@@ -51,6 +51,7 @@ struct rfkill_gsw_state {
 
 static struct rfkill_gsw_state rfkill_global_states[RFKILL_TYPE_MAX];
 static unsigned long rfkill_states_lockdflt[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
+static bool rfkill_epo_lock_active;
 
 static BLOCKING_NOTIFIER_HEAD(rfkill_notifier_list);
 
@@ -264,11 +265,14 @@ static void __rfkill_switch_all(const enum rfkill_type type,
  *
  * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state).
  * Please refer to __rfkill_switch_all() for details.
+ *
+ * Does nothing if the EPO lock is active.
  */
 void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
 {
        mutex_lock(&rfkill_global_mutex);
-       __rfkill_switch_all(type, state);
+       if (!rfkill_epo_lock_active)
+               __rfkill_switch_all(type, state);
        mutex_unlock(&rfkill_global_mutex);
 }
 EXPORT_SYMBOL(rfkill_switch_all);
@@ -289,6 +293,7 @@ void rfkill_epo(void)
 
        mutex_lock(&rfkill_global_mutex);
 
+       rfkill_epo_lock_active = true;
        list_for_each_entry(rfkill, &rfkill_list, node) {
                mutex_lock(&rfkill->mutex);
                rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
@@ -317,12 +322,55 @@ void rfkill_restore_states(void)
 
        mutex_lock(&rfkill_global_mutex);
 
+       rfkill_epo_lock_active = false;
        for (i = 0; i < RFKILL_TYPE_MAX; i++)
                __rfkill_switch_all(i, rfkill_global_states[i].default_state);
        mutex_unlock(&rfkill_global_mutex);
 }
 EXPORT_SYMBOL_GPL(rfkill_restore_states);
 
+/**
+ * rfkill_remove_epo_lock - unlock state changes
+ *
+ * Used by rfkill-input manually unlock state changes, when
+ * the EPO switch is deactivated.
+ */
+void rfkill_remove_epo_lock(void)
+{
+       mutex_lock(&rfkill_global_mutex);
+       rfkill_epo_lock_active = false;
+       mutex_unlock(&rfkill_global_mutex);
+}
+EXPORT_SYMBOL_GPL(rfkill_remove_epo_lock);
+
+/**
+ * rfkill_is_epo_lock_active - returns true EPO is active
+ *
+ * Returns 0 (false) if there is NOT an active EPO contidion,
+ * and 1 (true) if there is an active EPO contition, which
+ * locks all radios in one of the BLOCKED states.
+ *
+ * Can be called in atomic context.
+ */
+bool rfkill_is_epo_lock_active(void)
+{
+       return rfkill_epo_lock_active;
+}
+EXPORT_SYMBOL_GPL(rfkill_is_epo_lock_active);
+
+/**
+ * rfkill_get_global_state - returns global state for a type
+ * @type: the type to get the global state of
+ *
+ * Returns the current global state for a given wireless
+ * device type.
+ */
+enum rfkill_state rfkill_get_global_state(const enum rfkill_type type)
+{
+       return rfkill_global_states[type].current_state;
+}
+EXPORT_SYMBOL_GPL(rfkill_get_global_state);
+
 /**
  * rfkill_force_state - Force the internal rfkill radio state
  * @rfkill: pointer to the rfkill class to modify.
@@ -431,9 +479,15 @@ static ssize_t rfkill_state_store(struct device *dev,
            state != RFKILL_STATE_SOFT_BLOCKED)
                return -EINVAL;
 
-       if (mutex_lock_interruptible(&rfkill->mutex))
-               return -ERESTARTSYS;
-       error = rfkill_toggle_radio(rfkill, state, 0);
+       error = mutex_lock_killable(&rfkill->mutex);
+       if (error)
+               return error;
+
+       if (!rfkill_epo_lock_active)
+               error = rfkill_toggle_radio(rfkill, state, 0);
+       else
+               error = -EPERM;
+
        mutex_unlock(&rfkill->mutex);
 
        return error ? error : count;
@@ -472,12 +526,12 @@ static ssize_t rfkill_claim_store(struct device *dev,
         * Take the global lock to make sure the kernel is not in
         * the middle of rfkill_switch_all
         */
-       error = mutex_lock_interruptible(&rfkill_global_mutex);
+       error = mutex_lock_killable(&rfkill_global_mutex);
        if (error)
                return error;
 
        if (rfkill->user_claim != claim) {
-               if (!claim) {
+               if (!claim && !rfkill_epo_lock_active) {
                        mutex_lock(&rfkill->mutex);
                        rfkill_toggle_radio(rfkill,
                                        rfkill_global_states[rfkill->type].current_state,
@@ -527,8 +581,17 @@ static int rfkill_resume(struct device *dev)
 
                dev->power.power_state.event = PM_EVENT_ON;
 
-               /* restore radio state AND notify everybody */
-               rfkill_toggle_radio(rfkill, rfkill->state, 1);
+               /*
+                * If we are under EPO, kick transmitter offline,
+                * otherwise restore to pre-suspend state.
+                *
+                * Issue a notification in any case
+                */
+               rfkill_toggle_radio(rfkill,
+                               rfkill_epo_lock_active ?
+                                       RFKILL_STATE_SOFT_BLOCKED :
+                                       rfkill->state,
+                               1);
 
                mutex_unlock(&rfkill->mutex);
        }
@@ -711,7 +774,7 @@ static void rfkill_led_trigger_register(struct rfkill *rfkill)
        int error;
 
        if (!rfkill->led_trigger.name)
-               rfkill->led_trigger.name = rfkill->dev.bus_id;
+               rfkill->led_trigger.name = dev_name(&rfkill->dev);
        if (!rfkill->led_trigger.activate)
                rfkill->led_trigger.activate = rfkill_led_trigger_activate;
        error = led_trigger_register(&rfkill->led_trigger);
@@ -752,8 +815,7 @@ int __must_check rfkill_register(struct rfkill *rfkill)
                        "badly initialized rfkill struct\n"))
                return -EINVAL;
 
-       snprintf(dev->bus_id, sizeof(dev->bus_id),
-                "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1);
+       dev_set_name(dev, "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1);
 
        rfkill_led_trigger_register(rfkill);
 
@@ -833,6 +895,7 @@ int rfkill_set_default(enum rfkill_type type, enum rfkill_state state)
 
        if (!test_and_set_bit(type, rfkill_states_lockdflt)) {
                rfkill_global_states[type].default_state = state;
+               rfkill_global_states[type].current_state = state;
                error = 0;
        } else
                error = -EPERM;
index 20be3485a97f9981971481b0915a01157e0e24e1..3bfe504faf86c5ba156023443b8b4d9206301a83 100644 (file)
@@ -31,8 +31,8 @@ static ctl_table rose_table[] = {
                .data           = &sysctl_rose_restart_request_timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_timer,
                .extra2         = &max_timer
        },
@@ -42,8 +42,8 @@ static ctl_table rose_table[] = {
                .data           = &sysctl_rose_call_request_timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_timer,
                .extra2         = &max_timer
        },
@@ -53,8 +53,8 @@ static ctl_table rose_table[] = {
                .data           = &sysctl_rose_reset_request_timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_timer,
                .extra2         = &max_timer
        },
@@ -64,8 +64,8 @@ static ctl_table rose_table[] = {
                .data           = &sysctl_rose_clear_request_timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_timer,
                .extra2         = &max_timer
        },
@@ -75,8 +75,8 @@ static ctl_table rose_table[] = {
                .data           = &sysctl_rose_no_activity_timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_idle,
                .extra2         = &max_idle
        },
@@ -86,8 +86,8 @@ static ctl_table rose_table[] = {
                .data           = &sysctl_rose_ack_hold_back_timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_timer,
                .extra2         = &max_timer
        },
@@ -97,8 +97,8 @@ static ctl_table rose_table[] = {
                .data           = &sysctl_rose_routing_control,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_route,
                .extra2         = &max_route
        },
@@ -108,8 +108,8 @@ static ctl_table rose_table[] = {
                .data           = &sysctl_rose_link_fail_timeout,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_ftimer,
                .extra2         = &max_ftimer
        },
@@ -119,8 +119,8 @@ static ctl_table rose_table[] = {
                .data           = &sysctl_rose_maximum_vcs,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_maxvcs,
                .extra2         = &max_maxvcs
        },
@@ -130,8 +130,8 @@ static ctl_table rose_table[] = {
                .data           = &sysctl_rose_window_size,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &min_window,
                .extra2         = &max_window
        },
index 32e489118bebcc7462316456cf9a4e8dffeaae31..d7d2bed7a6995691eaedb13055f732d1efaa3ac6 100644 (file)
@@ -96,9 +96,9 @@ static int rxrpc_validate_address(struct rxrpc_sock *rx,
 
        switch (srx->transport.family) {
        case AF_INET:
-               _debug("INET: %x @ %u.%u.%u.%u",
+               _debug("INET: %x @ %pI4",
                       ntohs(srx->transport.sin.sin_port),
-                      NIPQUAD(srx->transport.sin.sin_addr));
+                      &srx->transport.sin.sin_addr);
                if (srx->transport_len > 8)
                        memset((void *)&srx->transport + 8, 0,
                               srx->transport_len - 8);
index 6cb3e8890e7e8305fb702ab933aff4cc18b58bf4..d4d1ae26d29313fffb1230a1fdcbe09d740a7cd0 100644 (file)
@@ -49,8 +49,7 @@ void rxrpc_UDP_error_report(struct sock *sk)
        addr = *(__be32 *)(skb_network_header(skb) + serr->addr_offset);
        port = serr->port;
 
-       _net("Rx UDP Error from "NIPQUAD_FMT":%hu",
-            NIPQUAD(addr), ntohs(port));
+       _net("Rx UDP Error from %pI4:%hu", &addr, ntohs(port));
        _debug("Msg l:%d d:%d", skb->len, skb->data_len);
 
        peer = rxrpc_find_peer(local, addr, port);
index f3a2bd747a8f6f09aa4e3006d3ddd66e24a5d370..807535ff29b52d0ebdb85ac6ba4fa5e4c5d18805 100644 (file)
@@ -131,10 +131,10 @@ struct rxrpc_local *rxrpc_lookup_local(struct sockaddr_rxrpc *srx)
        struct rxrpc_local *local;
        int ret;
 
-       _enter("{%d,%u,%u.%u.%u.%u+%hu}",
+       _enter("{%d,%u,%pI4+%hu}",
               srx->transport_type,
               srx->transport.family,
-              NIPQUAD(srx->transport.sin.sin_addr),
+              &srx->transport.sin.sin_addr,
               ntohs(srx->transport.sin.sin_port));
 
        down_write(&rxrpc_local_sem);
@@ -143,10 +143,10 @@ struct rxrpc_local *rxrpc_lookup_local(struct sockaddr_rxrpc *srx)
        read_lock_bh(&rxrpc_local_lock);
 
        list_for_each_entry(local, &rxrpc_locals, link) {
-               _debug("CMP {%d,%u,%u.%u.%u.%u+%hu}",
+               _debug("CMP {%d,%u,%pI4+%hu}",
                       local->srx.transport_type,
                       local->srx.transport.family,
-                      NIPQUAD(local->srx.transport.sin.sin_addr),
+                      &local->srx.transport.sin.sin_addr,
                       ntohs(local->srx.transport.sin.sin_port));
 
                if (local->srx.transport_type != srx->transport_type ||
@@ -188,11 +188,11 @@ struct rxrpc_local *rxrpc_lookup_local(struct sockaddr_rxrpc *srx)
 
        up_write(&rxrpc_local_sem);
 
-       _net("LOCAL new %d {%d,%u,%u.%u.%u.%u+%hu}",
+       _net("LOCAL new %d {%d,%u,%pI4+%hu}",
             local->debug_id,
             local->srx.transport_type,
             local->srx.transport.family,
-            NIPQUAD(local->srx.transport.sin.sin_addr),
+            &local->srx.transport.sin.sin_addr,
             ntohs(local->srx.transport.sin.sin_port));
 
        _leave(" = %p [new]", local);
@@ -203,11 +203,11 @@ found_local:
        read_unlock_bh(&rxrpc_local_lock);
        up_write(&rxrpc_local_sem);
 
-       _net("LOCAL old %d {%d,%u,%u.%u.%u.%u+%hu}",
+       _net("LOCAL old %d {%d,%u,%pI4+%hu}",
             local->debug_id,
             local->srx.transport_type,
             local->srx.transport.family,
-            NIPQUAD(local->srx.transport.sin.sin_addr),
+            &local->srx.transport.sin.sin_addr,
             ntohs(local->srx.transport.sin.sin_port));
 
        _leave(" = %p [reuse]", local);
index 2abe2081a5e83b9a9ea848872f266ab4f1a711a1..edc026c1eb763aeaf837d27ab9692374a4a7653b 100644 (file)
@@ -123,10 +123,10 @@ struct rxrpc_peer *rxrpc_get_peer(struct sockaddr_rxrpc *srx, gfp_t gfp)
        const char *new = "old";
        int usage;
 
-       _enter("{%d,%d,%u.%u.%u.%u+%hu}",
+       _enter("{%d,%d,%pI4+%hu}",
               srx->transport_type,
               srx->transport_len,
-              NIPQUAD(srx->transport.sin.sin_addr),
+              &srx->transport.sin.sin_addr,
               ntohs(srx->transport.sin.sin_port));
 
        /* search the peer list first */
@@ -177,12 +177,12 @@ struct rxrpc_peer *rxrpc_get_peer(struct sockaddr_rxrpc *srx, gfp_t gfp)
        new = "new";
 
 success:
-       _net("PEER %s %d {%d,%u,%u.%u.%u.%u+%hu}",
+       _net("PEER %s %d {%d,%u,%pI4+%hu}",
             new,
             peer->debug_id,
             peer->srx.transport_type,
             peer->srx.transport.family,
-            NIPQUAD(peer->srx.transport.sin.sin_addr),
+            &peer->srx.transport.sin.sin_addr,
             ntohs(peer->srx.transport.sin.sin_port));
 
        _leave(" = %p {u=%d}", peer, atomic_read(&peer->usage));
index 017322e2786dedb70f2da284e1a687b57c203cc6..38047f713f2cf0fb2b60261039c475bd7fe19f7e 100644 (file)
@@ -61,12 +61,12 @@ static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
        call = list_entry(v, struct rxrpc_call, link);
        trans = call->conn->trans;
 
-       sprintf(lbuff, NIPQUAD_FMT":%u",
-               NIPQUAD(trans->local->srx.transport.sin.sin_addr),
+       sprintf(lbuff, "%pI4:%u",
+               &trans->local->srx.transport.sin.sin_addr,
                ntohs(trans->local->srx.transport.sin.sin_port));
 
-       sprintf(rbuff, NIPQUAD_FMT":%u",
-               NIPQUAD(trans->peer->srx.transport.sin.sin_addr),
+       sprintf(rbuff, "%pI4:%u",
+               &trans->peer->srx.transport.sin.sin_addr,
                ntohs(trans->peer->srx.transport.sin.sin_port));
 
        seq_printf(seq,
@@ -144,12 +144,12 @@ static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
        conn = list_entry(v, struct rxrpc_connection, link);
        trans = conn->trans;
 
-       sprintf(lbuff, NIPQUAD_FMT":%u",
-               NIPQUAD(trans->local->srx.transport.sin.sin_addr),
+       sprintf(lbuff, "%pI4:%u",
+               &trans->local->srx.transport.sin.sin_addr,
                ntohs(trans->local->srx.transport.sin.sin_port));
 
-       sprintf(rbuff, NIPQUAD_FMT":%u",
-               NIPQUAD(trans->peer->srx.transport.sin.sin_addr),
+       sprintf(rbuff, "%pI4:%u",
+               &trans->peer->srx.transport.sin.sin_addr,
                ntohs(trans->peer->srx.transport.sin.sin_port));
 
        seq_printf(seq,
index 64069c8769a51e0ad629d377d79f847dd26a92d7..0936e1acc30ece6110313c01fb0ee78c0e5dd91e 100644 (file)
@@ -78,10 +78,10 @@ struct rxrpc_transport *rxrpc_get_transport(struct rxrpc_local *local,
        const char *new = "old";
        int usage;
 
-       _enter("{%u.%u.%u.%u+%hu},{%u.%u.%u.%u+%hu},",
-              NIPQUAD(local->srx.transport.sin.sin_addr),
+       _enter("{%pI4+%hu},{%pI4+%hu},",
+              &local->srx.transport.sin.sin_addr,
               ntohs(local->srx.transport.sin.sin_port),
-              NIPQUAD(peer->srx.transport.sin.sin_addr),
+              &peer->srx.transport.sin.sin_addr,
               ntohs(peer->srx.transport.sin.sin_port));
 
        /* search the transport list first */
@@ -149,10 +149,10 @@ struct rxrpc_transport *rxrpc_find_transport(struct rxrpc_local *local,
 {
        struct rxrpc_transport *trans;
 
-       _enter("{%u.%u.%u.%u+%hu},{%u.%u.%u.%u+%hu},",
-              NIPQUAD(local->srx.transport.sin.sin_addr),
+       _enter("{%pI4+%hu},{%pI4+%hu},",
+              &local->srx.transport.sin.sin_addr,
               ntohs(local->srx.transport.sin.sin_port),
-              NIPQUAD(peer->srx.transport.sin.sin_addr),
+              &peer->srx.transport.sin.sin_addr,
               ntohs(peer->srx.transport.sin.sin_port));
 
        /* search the transport list */
index ba3f6e49fddc59164fed12773b483ee699aa1a3d..ef8f91030a150ff6cb4605c8229dd1955b3528e0 100644 (file)
@@ -897,7 +897,7 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn,
        /* get the IPv4 address of the entity that requested the ticket */
        memcpy(&addr, p, sizeof(addr));
        p += 4;
-       _debug("KIV ADDR : "NIPQUAD_FMT, NIPQUAD(addr));
+       _debug("KIV ADDR : %pI4", &addr);
 
        /* get the session key from the ticket */
        memcpy(&key, p, sizeof(key));
index 6767e54155dbac238f8ea1707272bd95253a4927..36543b6fcef31230a3a7dd64990668d09841f9cb 100644 (file)
@@ -316,6 +316,17 @@ config NET_CLS_FLOW
          To compile this code as a module, choose M here: the
          module will be called cls_flow.
 
+config NET_CLS_CGROUP
+       bool "Control Group Classifier"
+       select NET_CLS
+       depends on CGROUPS
+       ---help---
+         Say Y here if you want to classify packets based on the control
+         cgroup of their process.
+
+         To compile this code as a module, choose M here: the
+         module will be called cls_cgroup.
+
 config NET_EMATCH
        bool "Extended Matches"
        select NET_CLS
index e60c9925b269ade40c544da32e54d8572b9fa54c..70b35f8708c3a1f1522ced6000bb127b1a5d71f9 100644 (file)
@@ -38,6 +38,7 @@ obj-$(CONFIG_NET_CLS_TCINDEX) += cls_tcindex.o
 obj-$(CONFIG_NET_CLS_RSVP6)    += cls_rsvp6.o
 obj-$(CONFIG_NET_CLS_BASIC)    += cls_basic.o
 obj-$(CONFIG_NET_CLS_FLOW)     += cls_flow.o
+obj-$(CONFIG_NET_CLS_CGROUP)   += cls_cgroup.o
 obj-$(CONFIG_NET_EMATCH)       += ematch.o
 obj-$(CONFIG_NET_EMATCH_CMP)   += em_cmp.o
 obj-$(CONFIG_NET_EMATCH_NBYTE) += em_nbyte.o
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
new file mode 100644 (file)
index 0000000..53ada2c
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * net/sched/cls_cgroup.c      Control Group Classifier
+ *
+ *             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.
+ *
+ * Authors:    Thomas Graf <tgraf@suug.ch>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+#include <linux/cgroup.h>
+#include <net/rtnetlink.h>
+#include <net/pkt_cls.h>
+
+struct cgroup_cls_state
+{
+       struct cgroup_subsys_state css;
+       u32 classid;
+};
+
+static inline struct cgroup_cls_state *net_cls_state(struct cgroup *cgrp)
+{
+       return (struct cgroup_cls_state *)
+               cgroup_subsys_state(cgrp, net_cls_subsys_id);
+}
+
+static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss,
+                                                struct cgroup *cgrp)
+{
+       struct cgroup_cls_state *cs;
+
+       if (!(cs = kzalloc(sizeof(*cs), GFP_KERNEL)))
+               return ERR_PTR(-ENOMEM);
+
+       if (cgrp->parent)
+               cs->classid = net_cls_state(cgrp->parent)->classid;
+
+       return &cs->css;
+}
+
+static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp)
+{
+       kfree(ss);
+}
+
+static u64 read_classid(struct cgroup *cgrp, struct cftype *cft)
+{
+       return net_cls_state(cgrp)->classid;
+}
+
+static int write_classid(struct cgroup *cgrp, struct cftype *cft, u64 value)
+{
+       if (!cgroup_lock_live_group(cgrp))
+               return -ENODEV;
+
+       net_cls_state(cgrp)->classid = (u32) value;
+
+       cgroup_unlock();
+
+       return 0;
+}
+
+static struct cftype ss_files[] = {
+       {
+               .name = "classid",
+               .read_u64 = read_classid,
+               .write_u64 = write_classid,
+       },
+};
+
+static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp)
+{
+       return cgroup_add_files(cgrp, ss, ss_files, ARRAY_SIZE(ss_files));
+}
+
+struct cgroup_subsys net_cls_subsys = {
+       .name           = "net_cls",
+       .create         = cgrp_create,
+       .destroy        = cgrp_destroy,
+       .populate       = cgrp_populate,
+       .subsys_id      = net_cls_subsys_id,
+};
+
+struct cls_cgroup_head
+{
+       u32                     handle;
+       struct tcf_exts         exts;
+       struct tcf_ematch_tree  ematches;
+};
+
+static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp,
+                              struct tcf_result *res)
+{
+       struct cls_cgroup_head *head = tp->root;
+       struct cgroup_cls_state *cs;
+       int ret = 0;
+
+       /*
+        * Due to the nature of the classifier it is required to ignore all
+        * packets originating from softirq context as accessing `current'
+        * would lead to false results.
+        *
+        * This test assumes that all callers of dev_queue_xmit() explicitely
+        * disable bh. Knowing this, it is possible to detect softirq based
+        * calls by looking at the number of nested bh disable calls because
+        * softirqs always disables bh.
+        */
+       if (softirq_count() != SOFTIRQ_OFFSET)
+               return -1;
+
+       rcu_read_lock();
+       cs = (struct cgroup_cls_state *) task_subsys_state(current,
+                                                          net_cls_subsys_id);
+       if (cs->classid && tcf_em_tree_match(skb, &head->ematches, NULL)) {
+               res->classid = cs->classid;
+               res->class = 0;
+               ret = tcf_exts_exec(skb, &head->exts, res);
+       } else
+               ret = -1;
+
+       rcu_read_unlock();
+
+       return ret;
+}
+
+static unsigned long cls_cgroup_get(struct tcf_proto *tp, u32 handle)
+{
+       return 0UL;
+}
+
+static void cls_cgroup_put(struct tcf_proto *tp, unsigned long f)
+{
+}
+
+static int cls_cgroup_init(struct tcf_proto *tp)
+{
+       return 0;
+}
+
+static const struct tcf_ext_map cgroup_ext_map = {
+       .action = TCA_CGROUP_ACT,
+       .police = TCA_CGROUP_POLICE,
+};
+
+static const struct nla_policy cgroup_policy[TCA_CGROUP_MAX + 1] = {
+       [TCA_CGROUP_EMATCHES]   = { .type = NLA_NESTED },
+};
+
+static int cls_cgroup_change(struct tcf_proto *tp, unsigned long base,
+                            u32 handle, struct nlattr **tca,
+                            unsigned long *arg)
+{
+       struct nlattr *tb[TCA_CGROUP_MAX+1];
+       struct cls_cgroup_head *head = tp->root;
+       struct tcf_ematch_tree t;
+       struct tcf_exts e;
+       int err;
+
+       if (head == NULL) {
+               if (!handle)
+                       return -EINVAL;
+
+               head = kzalloc(sizeof(*head), GFP_KERNEL);
+               if (head == NULL)
+                       return -ENOBUFS;
+
+               head->handle = handle;
+
+               tcf_tree_lock(tp);
+               tp->root = head;
+               tcf_tree_unlock(tp);
+       }
+
+       if (handle != head->handle)
+               return -ENOENT;
+
+       err = nla_parse_nested(tb, TCA_CGROUP_MAX, tca[TCA_OPTIONS],
+                              cgroup_policy);
+       if (err < 0)
+               return err;
+
+       err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &cgroup_ext_map);
+       if (err < 0)
+               return err;
+
+       err = tcf_em_tree_validate(tp, tb[TCA_CGROUP_EMATCHES], &t);
+       if (err < 0)
+               return err;
+
+       tcf_exts_change(tp, &head->exts, &e);
+       tcf_em_tree_change(tp, &head->ematches, &t);
+
+       return 0;
+}
+
+static void cls_cgroup_destroy(struct tcf_proto *tp)
+{
+       struct cls_cgroup_head *head;
+
+       head = (struct cls_cgroup_head *)xchg(&tp->root, NULL);
+
+       if (head) {
+               tcf_exts_destroy(tp, &head->exts);
+               tcf_em_tree_destroy(tp, &head->ematches);
+               kfree(head);
+       }
+}
+
+static int cls_cgroup_delete(struct tcf_proto *tp, unsigned long arg)
+{
+       return -EOPNOTSUPP;
+}
+
+static void cls_cgroup_walk(struct tcf_proto *tp, struct tcf_walker *arg)
+{
+       struct cls_cgroup_head *head = tp->root;
+
+       if (arg->count < arg->skip)
+               goto skip;
+
+       if (arg->fn(tp, (unsigned long) head, arg) < 0) {
+               arg->stop = 1;
+               return;
+       }
+skip:
+       arg->count++;
+}
+
+static int cls_cgroup_dump(struct tcf_proto *tp, unsigned long fh,
+                          struct sk_buff *skb, struct tcmsg *t)
+{
+       struct cls_cgroup_head *head = tp->root;
+       unsigned char *b = skb_tail_pointer(skb);
+       struct nlattr *nest;
+
+       t->tcm_handle = head->handle;
+
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
+
+       if (tcf_exts_dump(skb, &head->exts, &cgroup_ext_map) < 0 ||
+           tcf_em_tree_dump(skb, &head->ematches, TCA_CGROUP_EMATCHES) < 0)
+               goto nla_put_failure;
+
+       nla_nest_end(skb, nest);
+
+       if (tcf_exts_dump_stats(skb, &head->exts, &cgroup_ext_map) < 0)
+               goto nla_put_failure;
+
+       return skb->len;
+
+nla_put_failure:
+       nlmsg_trim(skb, b);
+       return -1;
+}
+
+static struct tcf_proto_ops cls_cgroup_ops __read_mostly = {
+       .kind           =       "cgroup",
+       .init           =       cls_cgroup_init,
+       .change         =       cls_cgroup_change,
+       .classify       =       cls_cgroup_classify,
+       .destroy        =       cls_cgroup_destroy,
+       .get            =       cls_cgroup_get,
+       .put            =       cls_cgroup_put,
+       .delete         =       cls_cgroup_delete,
+       .walk           =       cls_cgroup_walk,
+       .dump           =       cls_cgroup_dump,
+       .owner          =       THIS_MODULE,
+};
+
+static int __init init_cgroup_cls(void)
+{
+       return register_tcf_proto_ops(&cls_cgroup_ops);
+}
+
+static void __exit exit_cgroup_cls(void)
+{
+       unregister_tcf_proto_ops(&cls_cgroup_ops);
+}
+
+module_init(init_cgroup_cls);
+module_exit(exit_cgroup_cls);
+MODULE_LICENSE("GPL");
index e82519e548d70c747f602bc179ca487f120ef5af..aab59409728b4c50c4c45bc233570c10b8844980 100644 (file)
@@ -71,7 +71,7 @@
  *
  *      static void __exit exit_my_ematch(void)
  *      {
- *             return tcf_em_unregister(&my_ops);
+ *             tcf_em_unregister(&my_ops);
  *      }
  *
  *      module_init(init_my_ematch);
@@ -154,23 +154,11 @@ EXPORT_SYMBOL(tcf_em_register);
  *
  * Returns -ENOENT if no matching ematch was found.
  */
-int tcf_em_unregister(struct tcf_ematch_ops *ops)
+void tcf_em_unregister(struct tcf_ematch_ops *ops)
 {
-       int err = 0;
-       struct tcf_ematch_ops *e;
-
        write_lock(&ematch_mod_lock);
-       list_for_each_entry(e, &ematch_ops, link) {
-               if (e == ops) {
-                       list_del(&e->link);
-                       goto out;
-               }
-       }
-
-       err = -ENOENT;
-out:
+       list_del(&ops->link);
        write_unlock(&ematch_mod_lock);
-       return err;
 }
 EXPORT_SYMBOL(tcf_em_unregister);
 
index b16ad2972c6b527dc2013a5dfb4108ad35ef8197..5bcef13408c80c435a4c22f568cf87c22453f142 100644 (file)
@@ -97,10 +97,9 @@ static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n,
 
    Auxiliary routines:
 
-   ---requeue
+   ---peek
 
-   requeues once dequeued packet. It is used for non-standard or
-   just buggy devices, which can defer output even if netif_queue_stopped()=0.
+   like dequeue but without removing a packet from the queue
 
    ---reset
 
@@ -147,8 +146,14 @@ int register_qdisc(struct Qdisc_ops *qops)
 
        if (qops->enqueue == NULL)
                qops->enqueue = noop_qdisc_ops.enqueue;
-       if (qops->requeue == NULL)
-               qops->requeue = noop_qdisc_ops.requeue;
+       if (qops->peek == NULL) {
+               if (qops->dequeue == NULL) {
+                       qops->peek = noop_qdisc_ops.peek;
+               } else {
+                       rc = -EINVAL;
+                       goto out;
+               }
+       }
        if (qops->dequeue == NULL)
                qops->dequeue = noop_qdisc_ops.dequeue;
 
index 43d37256c15e3864655364ee96822a834266b89e..ca90f6e59aeec81c85aef0ae8f121a7efbdadf79 100644 (file)
@@ -62,7 +62,7 @@ struct atm_qdisc_data {
        struct atm_flow_data    link;           /* unclassified skbs go here */
        struct atm_flow_data    *flows;         /* NB: "link" is also on this
                                                   list */
-       struct tasklet_struct   task;           /* requeue tasklet */
+       struct tasklet_struct   task;           /* dequeue tasklet */
 };
 
 /* ------------------------- Class/flow operations ------------------------- */
@@ -480,11 +480,14 @@ static void sch_atm_dequeue(unsigned long data)
                 * If traffic is properly shaped, this won't generate nasty
                 * little bursts. Otherwise, it may ... (but that's okay)
                 */
-               while ((skb = flow->q->dequeue(flow->q))) {
-                       if (!atm_may_send(flow->vcc, skb->truesize)) {
-                               (void)flow->q->ops->requeue(skb, flow->q);
+               while ((skb = flow->q->ops->peek(flow->q))) {
+                       if (!atm_may_send(flow->vcc, skb->truesize))
                                break;
-                       }
+
+                       skb = qdisc_dequeue_peeked(flow->q);
+                       if (unlikely(!skb))
+                               break;
+
                        pr_debug("atm_tc_dequeue: sending on class %p\n", flow);
                        /* remove any LL header somebody else has attached */
                        skb_pull(skb, skb_network_offset(skb));
@@ -516,27 +519,19 @@ static struct sk_buff *atm_tc_dequeue(struct Qdisc *sch)
 
        pr_debug("atm_tc_dequeue(sch %p,[qdisc %p])\n", sch, p);
        tasklet_schedule(&p->task);
-       skb = p->link.q->dequeue(p->link.q);
+       skb = qdisc_dequeue_peeked(p->link.q);
        if (skb)
                sch->q.qlen--;
        return skb;
 }
 
-static int atm_tc_requeue(struct sk_buff *skb, struct Qdisc *sch)
+static struct sk_buff *atm_tc_peek(struct Qdisc *sch)
 {
        struct atm_qdisc_data *p = qdisc_priv(sch);
-       int ret;
 
-       pr_debug("atm_tc_requeue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
-       ret = p->link.q->ops->requeue(skb, p->link.q);
-       if (!ret) {
-               sch->q.qlen++;
-               sch->qstats.requeues++;
-       } else if (net_xmit_drop_count(ret)) {
-               sch->qstats.drops++;
-               p->link.qstats.drops++;
-       }
-       return ret;
+       pr_debug("atm_tc_peek(sch %p,[qdisc %p])\n", sch, p);
+
+       return p->link.q->ops->peek(p->link.q);
 }
 
 static unsigned int atm_tc_drop(struct Qdisc *sch)
@@ -694,7 +689,7 @@ static struct Qdisc_ops atm_qdisc_ops __read_mostly = {
        .priv_size      = sizeof(struct atm_qdisc_data),
        .enqueue        = atm_tc_enqueue,
        .dequeue        = atm_tc_dequeue,
-       .requeue        = atm_tc_requeue,
+       .peek           = atm_tc_peek,
        .drop           = atm_tc_drop,
        .init           = atm_tc_init,
        .reset          = atm_tc_reset,
index 507fb488bc985a18d13e0d79d95720b704118153..094a874b48bc43ca9337887bdd7cf462ee0ea63f 100644 (file)
@@ -33,6 +33,7 @@ static struct Qdisc_ops blackhole_qdisc_ops __read_mostly = {
        .priv_size      = 0,
        .enqueue        = blackhole_enqueue,
        .dequeue        = blackhole_dequeue,
+       .peek           = blackhole_dequeue,
        .owner          = THIS_MODULE,
 };
 
index 03e389e8d945d2b93b2d31b408a2ee78c6f0c8b9..a99e37e9e6f171bc0740f9f0d729ceff9729f2df 100644 (file)
@@ -405,40 +405,6 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        return ret;
 }
 
-static int
-cbq_requeue(struct sk_buff *skb, struct Qdisc *sch)
-{
-       struct cbq_sched_data *q = qdisc_priv(sch);
-       struct cbq_class *cl;
-       int ret;
-
-       if ((cl = q->tx_class) == NULL) {
-               kfree_skb(skb);
-               sch->qstats.drops++;
-               return NET_XMIT_CN;
-       }
-       q->tx_class = NULL;
-
-       cbq_mark_toplevel(q, cl);
-
-#ifdef CONFIG_NET_CLS_ACT
-       q->rx_class = cl;
-       cl->q->__parent = sch;
-#endif
-       if ((ret = cl->q->ops->requeue(skb, cl->q)) == 0) {
-               sch->q.qlen++;
-               sch->qstats.requeues++;
-               if (!cl->next_alive)
-                       cbq_activate_class(cl);
-               return 0;
-       }
-       if (net_xmit_drop_count(ret)) {
-               sch->qstats.drops++;
-               cl->qstats.drops++;
-       }
-       return ret;
-}
-
 /* Overlimit actions */
 
 /* TC_CBQ_OVL_CLASSIC: (default) penalize leaf class by adding offtime */
@@ -2066,7 +2032,7 @@ static struct Qdisc_ops cbq_qdisc_ops __read_mostly = {
        .priv_size      =       sizeof(struct cbq_sched_data),
        .enqueue        =       cbq_enqueue,
        .dequeue        =       cbq_dequeue,
-       .requeue        =       cbq_requeue,
+       .peek           =       qdisc_peek_dequeued,
        .drop           =       cbq_drop,
        .init           =       cbq_init,
        .reset          =       cbq_reset,
index ba43aab3a8515ed3a71925254a4a531849665baa..3f9427a4b757ec8cce0090ecac4d364cb1f36a53 100644 (file)
@@ -313,24 +313,13 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
        return skb;
 }
 
-static int dsmark_requeue(struct sk_buff *skb, struct Qdisc *sch)
+static struct sk_buff *dsmark_peek(struct Qdisc *sch)
 {
        struct dsmark_qdisc_data *p = qdisc_priv(sch);
-       int err;
-
-       pr_debug("dsmark_requeue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
-
-       err = p->q->ops->requeue(skb, p->q);
-       if (err != NET_XMIT_SUCCESS) {
-               if (net_xmit_drop_count(err))
-                       sch->qstats.drops++;
-               return err;
-       }
 
-       sch->q.qlen++;
-       sch->qstats.requeues++;
+       pr_debug("dsmark_peek(sch %p,[qdisc %p])\n", sch, p);
 
-       return NET_XMIT_SUCCESS;
+       return p->q->ops->peek(p->q);
 }
 
 static unsigned int dsmark_drop(struct Qdisc *sch)
@@ -496,7 +485,7 @@ static struct Qdisc_ops dsmark_qdisc_ops __read_mostly = {
        .priv_size      =       sizeof(struct dsmark_qdisc_data),
        .enqueue        =       dsmark_enqueue,
        .dequeue        =       dsmark_dequeue,
-       .requeue        =       dsmark_requeue,
+       .peek           =       dsmark_peek,
        .drop           =       dsmark_drop,
        .init           =       dsmark_init,
        .reset          =       dsmark_reset,
index 23d258bfe8ace223e07d0c23dc62fbe7e0ae9faa..92cfc9d7e3b93486a718bea3712a983814d605f0 100644 (file)
@@ -83,7 +83,7 @@ struct Qdisc_ops pfifo_qdisc_ops __read_mostly = {
        .priv_size      =       sizeof(struct fifo_sched_data),
        .enqueue        =       pfifo_enqueue,
        .dequeue        =       qdisc_dequeue_head,
-       .requeue        =       qdisc_requeue,
+       .peek           =       qdisc_peek_head,
        .drop           =       qdisc_queue_drop,
        .init           =       fifo_init,
        .reset          =       qdisc_reset_queue,
@@ -98,7 +98,7 @@ struct Qdisc_ops bfifo_qdisc_ops __read_mostly = {
        .priv_size      =       sizeof(struct fifo_sched_data),
        .enqueue        =       bfifo_enqueue,
        .dequeue        =       qdisc_dequeue_head,
-       .requeue        =       qdisc_requeue,
+       .peek           =       qdisc_peek_head,
        .drop           =       qdisc_queue_drop,
        .init           =       fifo_init,
        .reset          =       qdisc_reset_queue,
index 93cd30ce65011d2b84541277c15664ed6287fc3d..80c8f3dbbea15cc7a620fd3b946d4e20e49e6e21 100644 (file)
@@ -306,21 +306,12 @@ static struct sk_buff *noop_dequeue(struct Qdisc * qdisc)
        return NULL;
 }
 
-static int noop_requeue(struct sk_buff *skb, struct Qdisc* qdisc)
-{
-       if (net_ratelimit())
-               printk(KERN_DEBUG "%s deferred output. It is buggy.\n",
-                      skb->dev->name);
-       kfree_skb(skb);
-       return NET_XMIT_CN;
-}
-
 struct Qdisc_ops noop_qdisc_ops __read_mostly = {
        .id             =       "noop",
        .priv_size      =       0,
        .enqueue        =       noop_enqueue,
        .dequeue        =       noop_dequeue,
-       .requeue        =       noop_requeue,
+       .peek           =       noop_dequeue,
        .owner          =       THIS_MODULE,
 };
 
@@ -335,7 +326,6 @@ 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,
 };
@@ -346,7 +336,7 @@ static struct Qdisc_ops noqueue_qdisc_ops __read_mostly = {
        .priv_size      =       0,
        .enqueue        =       noop_enqueue,
        .dequeue        =       noop_dequeue,
-       .requeue        =       noop_requeue,
+       .peek           =       noop_dequeue,
        .owner          =       THIS_MODULE,
 };
 
@@ -362,7 +352,6 @@ 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,
 };
@@ -411,10 +400,17 @@ static struct sk_buff *pfifo_fast_dequeue(struct Qdisc* qdisc)
        return NULL;
 }
 
-static int pfifo_fast_requeue(struct sk_buff *skb, struct Qdisc* qdisc)
+static struct sk_buff *pfifo_fast_peek(struct Qdisc* qdisc)
 {
-       qdisc->q.qlen++;
-       return __qdisc_requeue(skb, qdisc, prio2list(skb, qdisc));
+       int prio;
+       struct sk_buff_head *list = qdisc_priv(qdisc);
+
+       for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
+               if (!skb_queue_empty(list + prio))
+                       return skb_peek(list + prio);
+       }
+
+       return NULL;
 }
 
 static void pfifo_fast_reset(struct Qdisc* qdisc)
@@ -457,7 +453,7 @@ static struct Qdisc_ops pfifo_fast_ops __read_mostly = {
        .priv_size      =       PFIFO_FAST_BANDS * sizeof(struct sk_buff_head),
        .enqueue        =       pfifo_fast_enqueue,
        .dequeue        =       pfifo_fast_dequeue,
-       .requeue        =       pfifo_fast_requeue,
+       .peek           =       pfifo_fast_peek,
        .init           =       pfifo_fast_init,
        .reset          =       pfifo_fast_reset,
        .dump           =       pfifo_fast_dump,
@@ -483,7 +479,6 @@ 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;
@@ -526,6 +521,9 @@ void qdisc_reset(struct Qdisc *qdisc)
 
        if (ops->reset)
                ops->reset(qdisc);
+
+       kfree_skb(qdisc->gso_skb);
+       qdisc->gso_skb = NULL;
 }
 EXPORT_SYMBOL(qdisc_reset);
 
@@ -552,8 +550,6 @@ 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);
 }
 EXPORT_SYMBOL(qdisc_destroy);
index c1ad6b8de105a60bbb4427d8f49e47b7e5adc46e..40408d595c08da0163e9a2c4c358e0293d4cebce 100644 (file)
@@ -240,26 +240,6 @@ congestion_drop:
        return NET_XMIT_CN;
 }
 
-static int gred_requeue(struct sk_buff *skb, struct Qdisc* sch)
-{
-       struct gred_sched *t = qdisc_priv(sch);
-       struct gred_sched_data *q;
-       u16 dp = tc_index_to_dp(skb);
-
-       if (dp >= t->DPs || (q = t->tab[dp]) == NULL) {
-               if (net_ratelimit())
-                       printk(KERN_WARNING "GRED: Unable to relocate VQ 0x%x "
-                              "for requeue, screwing up backlog.\n",
-                              tc_index_to_dp(skb));
-       } else {
-               if (red_is_idling(&q->parms))
-                       red_end_of_idle_period(&q->parms);
-               q->backlog += qdisc_pkt_len(skb);
-       }
-
-       return qdisc_requeue(skb, sch);
-}
-
 static struct sk_buff *gred_dequeue(struct Qdisc* sch)
 {
        struct sk_buff *skb;
@@ -602,7 +582,7 @@ static struct Qdisc_ops gred_qdisc_ops __read_mostly = {
        .priv_size      =       sizeof(struct gred_sched),
        .enqueue        =       gred_enqueue,
        .dequeue        =       gred_dequeue,
-       .requeue        =       gred_requeue,
+       .peek           =       qdisc_peek_head,
        .drop           =       gred_drop,
        .init           =       gred_init,
        .reset          =       gred_reset,
index c1e77da8cd09bc7dfc0bbe5aee25da12f7f69918..071c4749a12bb78e26c243cd115bf2c935804523 100644 (file)
@@ -184,7 +184,6 @@ struct hfsc_sched
        struct rb_root eligible;                /* eligible tree */
        struct list_head droplist;              /* active leaf class list (for
                                                   dropping) */
-       struct sk_buff_head requeue;            /* requeued packet */
        struct qdisc_watchdog watchdog;         /* watchdog timer */
 };
 
@@ -880,28 +879,20 @@ set_passive(struct hfsc_class *cl)
         */
 }
 
-/*
- * hack to get length of first packet in queue.
- */
 static unsigned int
 qdisc_peek_len(struct Qdisc *sch)
 {
        struct sk_buff *skb;
        unsigned int len;
 
-       skb = sch->dequeue(sch);
+       skb = sch->ops->peek(sch);
        if (skb == NULL) {
                if (net_ratelimit())
                        printk("qdisc_peek_len: non work-conserving qdisc ?\n");
                return 0;
        }
        len = qdisc_pkt_len(skb);
-       if (unlikely(sch->ops->requeue(skb, sch) != NET_XMIT_SUCCESS)) {
-               if (net_ratelimit())
-                       printk("qdisc_peek_len: failed to requeue\n");
-               qdisc_tree_decrease_qlen(sch, 1);
-               return 0;
-       }
+
        return len;
 }
 
@@ -1440,7 +1431,6 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
                return err;
        q->eligible = RB_ROOT;
        INIT_LIST_HEAD(&q->droplist);
-       skb_queue_head_init(&q->requeue);
 
        q->root.cl_common.classid = sch->handle;
        q->root.refcnt  = 1;
@@ -1525,7 +1515,6 @@ hfsc_reset_qdisc(struct Qdisc *sch)
                hlist_for_each_entry(cl, n, &q->clhash.hash[i], cl_common.hnode)
                        hfsc_reset_class(cl);
        }
-       __skb_queue_purge(&q->requeue);
        q->eligible = RB_ROOT;
        INIT_LIST_HEAD(&q->droplist);
        qdisc_watchdog_cancel(&q->watchdog);
@@ -1550,7 +1539,6 @@ hfsc_destroy_qdisc(struct Qdisc *sch)
                        hfsc_destroy_class(sch, cl);
        }
        qdisc_class_hash_destroy(&q->clhash);
-       __skb_queue_purge(&q->requeue);
        qdisc_watchdog_cancel(&q->watchdog);
 }
 
@@ -1617,8 +1605,6 @@ hfsc_dequeue(struct Qdisc *sch)
 
        if (sch->q.qlen == 0)
                return NULL;
-       if ((skb = __skb_dequeue(&q->requeue)))
-               goto out;
 
        cur_time = psched_get_time();
 
@@ -1642,7 +1628,7 @@ hfsc_dequeue(struct Qdisc *sch)
                }
        }
 
-       skb = cl->qdisc->dequeue(cl->qdisc);
+       skb = qdisc_dequeue_peeked(cl->qdisc);
        if (skb == NULL) {
                if (net_ratelimit())
                        printk("HFSC: Non-work-conserving qdisc ?\n");
@@ -1667,24 +1653,12 @@ hfsc_dequeue(struct Qdisc *sch)
                set_passive(cl);
        }
 
- out:
        sch->flags &= ~TCQ_F_THROTTLED;
        sch->q.qlen--;
 
        return skb;
 }
 
-static int
-hfsc_requeue(struct sk_buff *skb, struct Qdisc *sch)
-{
-       struct hfsc_sched *q = qdisc_priv(sch);
-
-       __skb_queue_head(&q->requeue, skb);
-       sch->q.qlen++;
-       sch->qstats.requeues++;
-       return NET_XMIT_SUCCESS;
-}
-
 static unsigned int
 hfsc_drop(struct Qdisc *sch)
 {
@@ -1735,7 +1709,7 @@ static struct Qdisc_ops hfsc_qdisc_ops __read_mostly = {
        .dump           = hfsc_dump_qdisc,
        .enqueue        = hfsc_enqueue,
        .dequeue        = hfsc_dequeue,
-       .requeue        = hfsc_requeue,
+       .peek           = qdisc_peek_dequeued,
        .drop           = hfsc_drop,
        .cl_ops         = &hfsc_class_ops,
        .priv_size      = sizeof(struct hfsc_sched),
index d14f02056ae6dcc31dbfad8c90ba57424e4a6d45..83f5e69243c10821dea52b19e28ee791b49e9e1b 100644 (file)
@@ -551,7 +551,7 @@ static inline void htb_deactivate(struct htb_sched *q, struct htb_class *cl)
 
 static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
-       int ret;
+       int uninitialized_var(ret);
        struct htb_sched *q = qdisc_priv(sch);
        struct htb_class *cl = htb_classify(skb, sch, &ret);
 
@@ -591,47 +591,6 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        return NET_XMIT_SUCCESS;
 }
 
-/* TODO: requeuing packet charges it to policers again !! */
-static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
-{
-       int ret;
-       struct htb_sched *q = qdisc_priv(sch);
-       struct htb_class *cl = htb_classify(skb, sch, &ret);
-       struct sk_buff *tskb;
-
-       if (cl == HTB_DIRECT) {
-               /* enqueue to helper queue */
-               if (q->direct_queue.qlen < q->direct_qlen) {
-                       __skb_queue_head(&q->direct_queue, skb);
-               } else {
-                       __skb_queue_head(&q->direct_queue, skb);
-                       tskb = __skb_dequeue_tail(&q->direct_queue);
-                       kfree_skb(tskb);
-                       sch->qstats.drops++;
-                       return NET_XMIT_CN;
-               }
-#ifdef CONFIG_NET_CLS_ACT
-       } else if (!cl) {
-               if (ret & __NET_XMIT_BYPASS)
-                       sch->qstats.drops++;
-               kfree_skb(skb);
-               return ret;
-#endif
-       } else if ((ret = cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q)) !=
-                  NET_XMIT_SUCCESS) {
-               if (net_xmit_drop_count(ret)) {
-                       sch->qstats.drops++;
-                       cl->qstats.drops++;
-               }
-               return ret;
-       } else
-               htb_activate(q, cl);
-
-       sch->q.qlen++;
-       sch->qstats.requeues++;
-       return NET_XMIT_SUCCESS;
-}
-
 /**
  * htb_charge_class - charges amount "bytes" to leaf and ancestors
  *
@@ -1565,7 +1524,7 @@ static struct Qdisc_ops htb_qdisc_ops __read_mostly = {
        .priv_size      =       sizeof(struct htb_sched),
        .enqueue        =       htb_enqueue,
        .dequeue        =       htb_dequeue,
-       .requeue        =       htb_requeue,
+       .peek           =       qdisc_peek_dequeued,
        .drop           =       htb_drop,
        .init           =       htb_init,
        .reset          =       htb_reset,
index 915f3149dde23c6d5391d505ae957714961cd2d1..f645ac55a1a13524e4d926d54a4688ad72bf8eb6 100644 (file)
@@ -92,40 +92,6 @@ multiq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        return ret;
 }
 
-
-static int
-multiq_requeue(struct sk_buff *skb, struct Qdisc *sch)
-{
-       struct Qdisc *qdisc;
-       struct multiq_sched_data *q = qdisc_priv(sch);
-       int ret;
-
-       qdisc = multiq_classify(skb, sch, &ret);
-#ifdef CONFIG_NET_CLS_ACT
-       if (qdisc == NULL) {
-               if (ret & __NET_XMIT_BYPASS)
-                       sch->qstats.drops++;
-               kfree_skb(skb);
-               return ret;
-       }
-#endif
-
-       ret = qdisc->ops->requeue(skb, qdisc);
-       if (ret == NET_XMIT_SUCCESS) {
-               sch->q.qlen++;
-               sch->qstats.requeues++;
-               if (q->curband)
-                       q->curband--;
-               else
-                       q->curband = q->bands - 1;
-               return NET_XMIT_SUCCESS;
-       }
-       if (net_xmit_drop_count(ret))
-               sch->qstats.drops++;
-       return ret;
-}
-
-
 static struct sk_buff *multiq_dequeue(struct Qdisc *sch)
 {
        struct multiq_sched_data *q = qdisc_priv(sch);
@@ -140,7 +106,7 @@ static struct sk_buff *multiq_dequeue(struct Qdisc *sch)
                        q->curband = 0;
 
                /* Check that target subqueue is available before
-                * pulling an skb to avoid excessive requeues
+                * pulling an skb to avoid head-of-line blocking.
                 */
                if (!__netif_subqueue_stopped(qdisc_dev(sch), q->curband)) {
                        qdisc = q->queues[q->curband];
@@ -155,6 +121,34 @@ static struct sk_buff *multiq_dequeue(struct Qdisc *sch)
 
 }
 
+static struct sk_buff *multiq_peek(struct Qdisc *sch)
+{
+       struct multiq_sched_data *q = qdisc_priv(sch);
+       unsigned int curband = q->curband;
+       struct Qdisc *qdisc;
+       struct sk_buff *skb;
+       int band;
+
+       for (band = 0; band < q->bands; band++) {
+               /* cycle through bands to ensure fairness */
+               curband++;
+               if (curband >= q->bands)
+                       curband = 0;
+
+               /* Check that target subqueue is available before
+                * pulling an skb to avoid head-of-line blocking.
+                */
+               if (!__netif_subqueue_stopped(qdisc_dev(sch), curband)) {
+                       qdisc = q->queues[curband];
+                       skb = qdisc->ops->peek(qdisc);
+                       if (skb)
+                               return skb;
+               }
+       }
+       return NULL;
+
+}
+
 static unsigned int multiq_drop(struct Qdisc *sch)
 {
        struct multiq_sched_data *q = qdisc_priv(sch);
@@ -451,7 +445,7 @@ static struct Qdisc_ops multiq_qdisc_ops __read_mostly = {
        .priv_size      =       sizeof(struct multiq_sched_data),
        .enqueue        =       multiq_enqueue,
        .dequeue        =       multiq_dequeue,
-       .requeue        =       multiq_requeue,
+       .peek           =       multiq_peek,
        .drop           =       multiq_drop,
        .init           =       multiq_init,
        .reset          =       multiq_reset,
index a11959908d9a68c405114d56c5073c0d77647402..3cbc3ff7b5bcd2d91c45cc9954a41b8066b2a92a 100644 (file)
@@ -233,7 +233,11 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                 */
                cb->time_to_send = psched_get_time();
                q->counter = 0;
-               ret = q->qdisc->ops->requeue(skb, q->qdisc);
+
+               __skb_queue_head(&q->qdisc->q, skb);
+               q->qdisc->qstats.backlog += qdisc_pkt_len(skb);
+               q->qdisc->qstats.requeues++;
+               ret = NET_XMIT_SUCCESS;
        }
 
        if (likely(ret == NET_XMIT_SUCCESS)) {
@@ -248,20 +252,6 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        return ret;
 }
 
-/* Requeue packets but don't change time stamp */
-static int netem_requeue(struct sk_buff *skb, struct Qdisc *sch)
-{
-       struct netem_sched_data *q = qdisc_priv(sch);
-       int ret;
-
-       if ((ret = q->qdisc->ops->requeue(skb, q->qdisc)) == 0) {
-               sch->q.qlen++;
-               sch->qstats.requeues++;
-       }
-
-       return ret;
-}
-
 static unsigned int netem_drop(struct Qdisc* sch)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
@@ -283,25 +273,22 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
        if (sch->flags & TCQ_F_THROTTLED)
                return NULL;
 
-       skb = q->qdisc->dequeue(q->qdisc);
+       skb = q->qdisc->ops->peek(q->qdisc);
        if (skb) {
                const struct netem_skb_cb *cb = netem_skb_cb(skb);
                psched_time_t now = psched_get_time();
 
                /* if more time remaining? */
                if (cb->time_to_send <= now) {
+                       skb = qdisc_dequeue_peeked(q->qdisc);
+                       if (unlikely(!skb))
+                               return NULL;
+
                        pr_debug("netem_dequeue: return skb=%p\n", skb);
                        sch->q.qlen--;
                        return skb;
                }
 
-               if (unlikely(q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS)) {
-                       qdisc_tree_decrease_qlen(q->qdisc, 1);
-                       sch->qstats.drops++;
-                       printk(KERN_ERR "netem: %s could not requeue\n",
-                              q->qdisc->ops->id);
-               }
-
                qdisc_watchdog_schedule(&q->watchdog, cb->time_to_send);
        }
 
@@ -351,7 +338,7 @@ static int get_dist_table(struct Qdisc *sch, const struct nlattr *attr)
        return 0;
 }
 
-static int get_correlation(struct Qdisc *sch, const struct nlattr *attr)
+static void get_correlation(struct Qdisc *sch, const struct nlattr *attr)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
        const struct tc_netem_corr *c = nla_data(attr);
@@ -359,27 +346,24 @@ static int get_correlation(struct Qdisc *sch, const struct nlattr *attr)
        init_crandom(&q->delay_cor, c->delay_corr);
        init_crandom(&q->loss_cor, c->loss_corr);
        init_crandom(&q->dup_cor, c->dup_corr);
-       return 0;
 }
 
-static int get_reorder(struct Qdisc *sch, const struct nlattr *attr)
+static void get_reorder(struct Qdisc *sch, const struct nlattr *attr)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
        const struct tc_netem_reorder *r = nla_data(attr);
 
        q->reorder = r->probability;
        init_crandom(&q->reorder_cor, r->correlation);
-       return 0;
 }
 
-static int get_corrupt(struct Qdisc *sch, const struct nlattr *attr)
+static void get_corrupt(struct Qdisc *sch, const struct nlattr *attr)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
        const struct tc_netem_corrupt *r = nla_data(attr);
 
        q->corrupt = r->probability;
        init_crandom(&q->corrupt_cor, r->correlation);
-       return 0;
 }
 
 static const struct nla_policy netem_policy[TCA_NETEM_MAX + 1] = {
@@ -438,11 +422,8 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt)
        if (q->gap)
                q->reorder = ~0;
 
-       if (tb[TCA_NETEM_CORR]) {
-               ret = get_correlation(sch, tb[TCA_NETEM_CORR]);
-               if (ret)
-                       return ret;
-       }
+       if (tb[TCA_NETEM_CORR])
+               get_correlation(sch, tb[TCA_NETEM_CORR]);
 
        if (tb[TCA_NETEM_DELAY_DIST]) {
                ret = get_dist_table(sch, tb[TCA_NETEM_DELAY_DIST]);
@@ -450,17 +431,11 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt)
                        return ret;
        }
 
-       if (tb[TCA_NETEM_REORDER]) {
-               ret = get_reorder(sch, tb[TCA_NETEM_REORDER]);
-               if (ret)
-                       return ret;
-       }
+       if (tb[TCA_NETEM_REORDER])
+               get_reorder(sch, tb[TCA_NETEM_REORDER]);
 
-       if (tb[TCA_NETEM_CORRUPT]) {
-               ret = get_corrupt(sch, tb[TCA_NETEM_CORRUPT]);
-               if (ret)
-                       return ret;
-       }
+       if (tb[TCA_NETEM_CORRUPT])
+               get_corrupt(sch, tb[TCA_NETEM_CORRUPT]);
 
        return 0;
 }
@@ -541,7 +516,7 @@ static struct Qdisc_ops tfifo_qdisc_ops __read_mostly = {
        .priv_size      =       sizeof(struct fifo_sched_data),
        .enqueue        =       tfifo_enqueue,
        .dequeue        =       qdisc_dequeue_head,
-       .requeue        =       qdisc_requeue,
+       .peek           =       qdisc_peek_head,
        .drop           =       qdisc_queue_drop,
        .init           =       tfifo_init,
        .reset          =       qdisc_reset_queue,
@@ -624,99 +599,12 @@ nla_put_failure:
        return -1;
 }
 
-static int netem_dump_class(struct Qdisc *sch, unsigned long cl,
-                         struct sk_buff *skb, struct tcmsg *tcm)
-{
-       struct netem_sched_data *q = qdisc_priv(sch);
-
-       if (cl != 1)    /* only one class */
-               return -ENOENT;
-
-       tcm->tcm_handle |= TC_H_MIN(1);
-       tcm->tcm_info = q->qdisc->handle;
-
-       return 0;
-}
-
-static int netem_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
-                    struct Qdisc **old)
-{
-       struct netem_sched_data *q = qdisc_priv(sch);
-
-       if (new == NULL)
-               new = &noop_qdisc;
-
-       sch_tree_lock(sch);
-       *old = xchg(&q->qdisc, new);
-       qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
-       qdisc_reset(*old);
-       sch_tree_unlock(sch);
-
-       return 0;
-}
-
-static struct Qdisc *netem_leaf(struct Qdisc *sch, unsigned long arg)
-{
-       struct netem_sched_data *q = qdisc_priv(sch);
-       return q->qdisc;
-}
-
-static unsigned long netem_get(struct Qdisc *sch, u32 classid)
-{
-       return 1;
-}
-
-static void netem_put(struct Qdisc *sch, unsigned long arg)
-{
-}
-
-static int netem_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
-                           struct nlattr **tca, unsigned long *arg)
-{
-       return -ENOSYS;
-}
-
-static int netem_delete(struct Qdisc *sch, unsigned long arg)
-{
-       return -ENOSYS;
-}
-
-static void netem_walk(struct Qdisc *sch, struct qdisc_walker *walker)
-{
-       if (!walker->stop) {
-               if (walker->count >= walker->skip)
-                       if (walker->fn(sch, 1, walker) < 0) {
-                               walker->stop = 1;
-                               return;
-                       }
-               walker->count++;
-       }
-}
-
-static struct tcf_proto **netem_find_tcf(struct Qdisc *sch, unsigned long cl)
-{
-       return NULL;
-}
-
-static const struct Qdisc_class_ops netem_class_ops = {
-       .graft          =       netem_graft,
-       .leaf           =       netem_leaf,
-       .get            =       netem_get,
-       .put            =       netem_put,
-       .change         =       netem_change_class,
-       .delete         =       netem_delete,
-       .walk           =       netem_walk,
-       .tcf_chain      =       netem_find_tcf,
-       .dump           =       netem_dump_class,
-};
-
 static struct Qdisc_ops netem_qdisc_ops __read_mostly = {
        .id             =       "netem",
-       .cl_ops         =       &netem_class_ops,
        .priv_size      =       sizeof(struct netem_sched_data),
        .enqueue        =       netem_enqueue,
        .dequeue        =       netem_dequeue,
-       .requeue        =       netem_requeue,
+       .peek           =       qdisc_peek_dequeued,
        .drop           =       netem_drop,
        .init           =       netem_init,
        .reset          =       netem_reset,
index 504a78cdb718bb7dd7ba05e60feb1f5fd2e89ea3..ea65a87ec22c6c4f60fdf5115151bff7da53b875 100644 (file)
@@ -93,34 +93,20 @@ prio_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        return ret;
 }
 
-
-static int
-prio_requeue(struct sk_buff *skb, struct Qdisc* sch)
+static struct sk_buff *prio_peek(struct Qdisc *sch)
 {
-       struct Qdisc *qdisc;
-       int ret;
-
-       qdisc = prio_classify(skb, sch, &ret);
-#ifdef CONFIG_NET_CLS_ACT
-       if (qdisc == NULL) {
-               if (ret & __NET_XMIT_BYPASS)
-                       sch->qstats.drops++;
-               kfree_skb(skb);
-               return ret;
-       }
-#endif
+       struct prio_sched_data *q = qdisc_priv(sch);
+       int prio;
 
-       if ((ret = qdisc->ops->requeue(skb, qdisc)) == NET_XMIT_SUCCESS) {
-               sch->q.qlen++;
-               sch->qstats.requeues++;
-               return NET_XMIT_SUCCESS;
+       for (prio = 0; prio < q->bands; prio++) {
+               struct Qdisc *qdisc = q->queues[prio];
+               struct sk_buff *skb = qdisc->ops->peek(qdisc);
+               if (skb)
+                       return skb;
        }
-       if (net_xmit_drop_count(ret))
-               sch->qstats.drops++;
-       return ret;
+       return NULL;
 }
 
-
 static struct sk_buff *prio_dequeue(struct Qdisc* sch)
 {
        struct prio_sched_data *q = qdisc_priv(sch);
@@ -421,7 +407,7 @@ static struct Qdisc_ops prio_qdisc_ops __read_mostly = {
        .priv_size      =       sizeof(struct prio_sched_data),
        .enqueue        =       prio_enqueue,
        .dequeue        =       prio_dequeue,
-       .requeue        =       prio_requeue,
+       .peek           =       prio_peek,
        .drop           =       prio_drop,
        .init           =       prio_init,
        .reset          =       prio_reset,
index 5da05839e225001bd9afeae5e6ba975a96fc3da1..6a0371c22643f36a414df48e7889c88affbc6c21 100644 (file)
@@ -108,23 +108,6 @@ congestion_drop:
        return NET_XMIT_CN;
 }
 
-static int red_requeue(struct sk_buff *skb, struct Qdisc* sch)
-{
-       struct red_sched_data *q = qdisc_priv(sch);
-       struct Qdisc *child = q->qdisc;
-       int ret;
-
-       if (red_is_idling(&q->parms))
-               red_end_of_idle_period(&q->parms);
-
-       ret = child->ops->requeue(skb, child);
-       if (likely(ret == NET_XMIT_SUCCESS)) {
-               sch->qstats.requeues++;
-               sch->q.qlen++;
-       }
-       return ret;
-}
-
 static struct sk_buff * red_dequeue(struct Qdisc* sch)
 {
        struct sk_buff *skb;
@@ -140,6 +123,14 @@ static struct sk_buff * red_dequeue(struct Qdisc* sch)
        return skb;
 }
 
+static struct sk_buff * red_peek(struct Qdisc* sch)
+{
+       struct red_sched_data *q = qdisc_priv(sch);
+       struct Qdisc *child = q->qdisc;
+
+       return child->ops->peek(child);
+}
+
 static unsigned int red_drop(struct Qdisc* sch)
 {
        struct red_sched_data *q = qdisc_priv(sch);
@@ -361,7 +352,7 @@ static struct Qdisc_ops red_qdisc_ops __read_mostly = {
        .cl_ops         =       &red_class_ops,
        .enqueue        =       red_enqueue,
        .dequeue        =       red_dequeue,
-       .requeue        =       red_requeue,
+       .peek           =       red_peek,
        .drop           =       red_drop,
        .init           =       red_init,
        .reset          =       red_reset,
index fe1508ef0d3d51e7d552a88e253a1d4b0b82fec6..ab8cfee3c9ced13f5008661d2ad2044f764ada46 100644 (file)
@@ -329,71 +329,20 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        return NET_XMIT_CN;
 }
 
-static int
-sfq_requeue(struct sk_buff *skb, struct Qdisc *sch)
+static struct sk_buff *
+sfq_peek(struct Qdisc *sch)
 {
        struct sfq_sched_data *q = qdisc_priv(sch);
-       unsigned int hash;
-       sfq_index x;
-       int ret;
-
-       hash = sfq_classify(skb, sch, &ret);
-       if (hash == 0) {
-               if (ret & __NET_XMIT_BYPASS)
-                       sch->qstats.drops++;
-               kfree_skb(skb);
-               return ret;
-       }
-       hash--;
-
-       x = q->ht[hash];
-       if (x == SFQ_DEPTH) {
-               q->ht[hash] = x = q->dep[SFQ_DEPTH].next;
-               q->hash[x] = hash;
-       }
-
-       sch->qstats.backlog += qdisc_pkt_len(skb);
-       __skb_queue_head(&q->qs[x], skb);
-       /* If selected queue has length q->limit+1, this means that
-        * all another queues are empty and we do simple tail drop.
-        * This packet is still requeued at head of queue, tail packet
-        * is dropped.
-        */
-       if (q->qs[x].qlen > q->limit) {
-               skb = q->qs[x].prev;
-               __skb_unlink(skb, &q->qs[x]);
-               sch->qstats.drops++;
-               sch->qstats.backlog -= qdisc_pkt_len(skb);
-               kfree_skb(skb);
-               return NET_XMIT_CN;
-       }
-
-       sfq_inc(q, x);
-       if (q->qs[x].qlen == 1) {               /* The flow is new */
-               if (q->tail == SFQ_DEPTH) {     /* It is the first flow */
-                       q->tail = x;
-                       q->next[x] = x;
-                       q->allot[x] = q->quantum;
-               } else {
-                       q->next[x] = q->next[q->tail];
-                       q->next[q->tail] = x;
-                       q->tail = x;
-               }
-       }
+       sfq_index a;
 
-       if (++sch->q.qlen <= q->limit) {
-               sch->qstats.requeues++;
-               return 0;
-       }
+       /* No active slots */
+       if (q->tail == SFQ_DEPTH)
+               return NULL;
 
-       sch->qstats.drops++;
-       sfq_drop(sch);
-       return NET_XMIT_CN;
+       a = q->next[q->tail];
+       return skb_peek(&q->qs[a]);
 }
 
-
-
-
 static struct sk_buff *
 sfq_dequeue(struct Qdisc *sch)
 {
@@ -624,7 +573,7 @@ static struct Qdisc_ops sfq_qdisc_ops __read_mostly = {
        .priv_size      =       sizeof(struct sfq_sched_data),
        .enqueue        =       sfq_enqueue,
        .dequeue        =       sfq_dequeue,
-       .requeue        =       sfq_requeue,
+       .peek           =       sfq_peek,
        .drop           =       sfq_drop,
        .init           =       sfq_init,
        .reset          =       sfq_reset,
index 94c61598b86ae1c0f52a23817f797a216b77492f..bb7783d584bb51abaa59cf0e91185209cf4537eb 100644 (file)
@@ -139,19 +139,6 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch)
        return 0;
 }
 
-static int tbf_requeue(struct sk_buff *skb, struct Qdisc* sch)
-{
-       struct tbf_sched_data *q = qdisc_priv(sch);
-       int ret;
-
-       if ((ret = q->qdisc->ops->requeue(skb, q->qdisc)) == 0) {
-               sch->q.qlen++;
-               sch->qstats.requeues++;
-       }
-
-       return ret;
-}
-
 static unsigned int tbf_drop(struct Qdisc* sch)
 {
        struct tbf_sched_data *q = qdisc_priv(sch);
@@ -169,7 +156,7 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
        struct tbf_sched_data *q = qdisc_priv(sch);
        struct sk_buff *skb;
 
-       skb = q->qdisc->dequeue(q->qdisc);
+       skb = q->qdisc->ops->peek(q->qdisc);
 
        if (skb) {
                psched_time_t now;
@@ -192,6 +179,10 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
                toks -= L2T(q, len);
 
                if ((toks|ptoks) >= 0) {
+                       skb = qdisc_dequeue_peeked(q->qdisc);
+                       if (unlikely(!skb))
+                               return NULL;
+
                        q->t_c = now;
                        q->tokens = toks;
                        q->ptokens = ptoks;
@@ -214,12 +205,6 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
                   (cf. CSZ, HPFQ, HFSC)
                 */
 
-               if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) {
-                       /* When requeue fails skb is dropped */
-                       qdisc_tree_decrease_qlen(q->qdisc, 1);
-                       sch->qstats.drops++;
-               }
-
                sch->qstats.overlimits++;
        }
        return NULL;
@@ -469,7 +454,7 @@ static struct Qdisc_ops tbf_qdisc_ops __read_mostly = {
        .priv_size      =       sizeof(struct tbf_sched_data),
        .enqueue        =       tbf_enqueue,
        .dequeue        =       tbf_dequeue,
-       .requeue        =       tbf_requeue,
+       .peek           =       qdisc_peek_dequeued,
        .drop           =       tbf_drop,
        .init           =       tbf_init,
        .reset          =       tbf_reset,
index d35ef059abb1781e41becb98e6b1a15e3596001b..cfc8e7caba6223f62cbe998c24491aed533a306d 100644 (file)
@@ -93,16 +93,6 @@ teql_enqueue(struct sk_buff *skb, struct Qdisc* sch)
        return NET_XMIT_DROP;
 }
 
-static int
-teql_requeue(struct sk_buff *skb, struct Qdisc* sch)
-{
-       struct teql_sched_data *q = qdisc_priv(sch);
-
-       __skb_queue_head(&q->q, skb);
-       sch->qstats.requeues++;
-       return 0;
-}
-
 static struct sk_buff *
 teql_dequeue(struct Qdisc* sch)
 {
@@ -123,6 +113,13 @@ teql_dequeue(struct Qdisc* sch)
        return skb;
 }
 
+static struct sk_buff *
+teql_peek(struct Qdisc* sch)
+{
+       /* teql is meant to be used as root qdisc */
+       return NULL;
+}
+
 static __inline__ void
 teql_neigh_release(struct neighbour *n)
 {
@@ -433,7 +430,7 @@ static __init void teql_master_setup(struct net_device *dev)
 
        ops->enqueue    =       teql_enqueue;
        ops->dequeue    =       teql_dequeue;
-       ops->requeue    =       teql_requeue;
+       ops->peek       =       teql_peek;
        ops->init       =       teql_qdisc_init;
        ops->reset      =       teql_reset;
        ops->destroy    =       teql_destroy;
index 4124bbb9994774cc6536cd1dd8f092202ca68d6e..ceaa4aa066eaea3e00162d200f6d9bcb0c1d31f3 100644 (file)
@@ -223,10 +223,9 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
                ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
        }
 
-       SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, "
-                         "src:" NIP6_FMT " dst:" NIP6_FMT "\n",
+       SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n",
                          __func__, skb, skb->len,
-                         NIP6(fl.fl6_src), NIP6(fl.fl6_dst));
+                         &fl.fl6_src, &fl.fl6_dst);
 
        SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
 
@@ -252,23 +251,19 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
                fl.oif = daddr->v6.sin6_scope_id;
 
 
-       SCTP_DEBUG_PRINTK("%s: DST=" NIP6_FMT " ",
-                         __func__, NIP6(fl.fl6_dst));
+       SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl.fl6_dst);
 
        if (saddr) {
                ipv6_addr_copy(&fl.fl6_src, &saddr->v6.sin6_addr);
-               SCTP_DEBUG_PRINTK(
-                       "SRC=" NIP6_FMT " - ",
-                       NIP6(fl.fl6_src));
+               SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl.fl6_src);
        }
 
        dst = ip6_route_output(&init_net, NULL, &fl);
        if (!dst->error) {
                struct rt6_info *rt;
                rt = (struct rt6_info *)dst;
-               SCTP_DEBUG_PRINTK(
-                       "rt6_dst:" NIP6_FMT " rt6_src:" NIP6_FMT "\n",
-                       NIP6(rt->rt6i_dst.addr), NIP6(rt->rt6i_src.addr));
+               SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n",
+                       &rt->rt6i_dst.addr, &rt->rt6i_src.addr);
                return dst;
        }
        SCTP_DEBUG_PRINTK("NO ROUTE\n");
@@ -314,9 +309,8 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk,
        __u8 matchlen = 0;
        __u8 bmatchlen;
 
-       SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p "
-                         "daddr:" NIP6_FMT " ",
-                         __func__, asoc, dst, NIP6(daddr->v6.sin6_addr));
+       SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p daddr:%pI6 ",
+                         __func__, asoc, dst, &daddr->v6.sin6_addr);
 
        if (!asoc) {
                ipv6_dev_get_saddr(sock_net(sctp_opt2sk(sk)),
@@ -324,8 +318,8 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk,
                                   &daddr->v6.sin6_addr,
                                   inet6_sk(&sk->inet.sk)->srcprefs,
                                   &saddr->v6.sin6_addr);
-               SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: " NIP6_FMT "\n",
-                                 NIP6(saddr->v6.sin6_addr));
+               SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: %pI6\n",
+                                 &saddr->v6.sin6_addr);
                return;
        }
 
@@ -353,12 +347,11 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk,
 
        if (baddr) {
                memcpy(saddr, baddr, sizeof(union sctp_addr));
-               SCTP_DEBUG_PRINTK("saddr: " NIP6_FMT "\n",
-                                 NIP6(saddr->v6.sin6_addr));
+               SCTP_DEBUG_PRINTK("saddr: %pI6\n", &saddr->v6.sin6_addr);
        } else {
                printk(KERN_ERR "%s: asoc:%p Could not find a valid source "
-                      "address for the dest:" NIP6_FMT "\n",
-                      __func__, asoc, NIP6(daddr->v6.sin6_addr));
+                      "address for the dest:%pI6\n",
+                      __func__, asoc, &daddr->v6.sin6_addr);
        }
 
        rcu_read_unlock();
@@ -727,7 +720,7 @@ static int sctp_v6_is_ce(const struct sk_buff *skb)
 /* Dump the v6 addr to the seq file. */
 static void sctp_v6_seq_dump_addr(struct seq_file *seq, union sctp_addr *addr)
 {
-       seq_printf(seq, NIP6_FMT " ", NIP6(addr->v6.sin6_addr));
+       seq_printf(seq, "%pI6 ", &addr->v6.sin6_addr);
 }
 
 static void sctp_v6_ecn_capable(struct sock *sk)
index 0b65354aaf64978a68836f1cb9754e4101cbc35b..a8ca743241ee19379c54f3d96635e2133e4d0183 100644 (file)
@@ -482,9 +482,8 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
        if (saddr)
                fl.fl4_src = saddr->v4.sin_addr.s_addr;
 
-       SCTP_DEBUG_PRINTK("%s: DST:%u.%u.%u.%u, SRC:%u.%u.%u.%u - ",
-                         __func__, NIPQUAD(fl.fl4_dst),
-                         NIPQUAD(fl.fl4_src));
+       SCTP_DEBUG_PRINTK("%s: DST:%pI4, SRC:%pI4 - ",
+                         __func__, &fl.fl4_dst, &fl.fl4_src);
 
        if (!ip_route_output_key(&init_net, &rt, &fl)) {
                dst = &rt->u.dst;
@@ -540,8 +539,8 @@ out_unlock:
        rcu_read_unlock();
 out:
        if (dst)
-               SCTP_DEBUG_PRINTK("rt_dst:%u.%u.%u.%u, rt_src:%u.%u.%u.%u\n",
-                                 NIPQUAD(rt->rt_dst), NIPQUAD(rt->rt_src));
+               SCTP_DEBUG_PRINTK("rt_dst:%pI4, rt_src:%pI4\n",
+                                 &rt->rt_dst, &rt->rt_src);
        else
                SCTP_DEBUG_PRINTK("NO ROUTE\n");
 
@@ -646,7 +645,7 @@ static void sctp_v4_addr_v4map(struct sctp_sock *sp, union sctp_addr *addr)
 /* Dump the v4 addr to the seq file. */
 static void sctp_v4_seq_dump_addr(struct seq_file *seq, union sctp_addr *addr)
 {
-       seq_printf(seq, "%d.%d.%d.%d ", NIPQUAD(addr->v4.sin_addr));
+       seq_printf(seq, "%pI4 ", &addr->v4.sin_addr);
 }
 
 static void sctp_v4_ecn_capable(struct sock *sk)
@@ -866,11 +865,10 @@ static inline int sctp_v4_xmit(struct sk_buff *skb,
 {
        struct inet_sock *inet = inet_sk(skb->sk);
 
-       SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, "
-                         "src:%u.%u.%u.%u, dst:%u.%u.%u.%u\n",
+       SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n",
                          __func__, skb, skb->len,
-                         NIPQUAD(skb->rtable->rt_src),
-                         NIPQUAD(skb->rtable->rt_dst));
+                         &skb->rtable->rt_src,
+                         &skb->rtable->rt_dst);
 
        inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ?
                         IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
index a6a0ea71ae93147813abdec8bdd2d3f040950ce3..9f2a3eb656e56462033f6714a74d878a0b54f52f 100644 (file)
@@ -1123,19 +1123,17 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
                if (from_addr.sa.sa_family == AF_INET6) {
                        if (net_ratelimit())
                                printk(KERN_WARNING
-                                   "%s association %p could not find address "
-                                   NIP6_FMT "\n",
+                                   "%s association %p could not find address %pI6\n",
                                    __func__,
                                    asoc,
-                                   NIP6(from_addr.v6.sin6_addr));
+                                   &from_addr.v6.sin6_addr);
                } else {
                        if (net_ratelimit())
                                printk(KERN_WARNING
-                                   "%s association %p could not find address "
-                                   NIPQUAD_FMT "\n",
+                                   "%s association %p could not find address %pI4\n",
                                    __func__,
                                    asoc,
-                                   NIPQUAD(from_addr.v4.sin_addr.s_addr));
+                                   &from_addr.v4.sin_addr.s_addr);
                }
                return SCTP_DISPOSITION_DISCARD;
        }
index a1b904529d5e1c3e12ba0a6c1ff7bfbc2b5dbddb..0c70eff0b757d11365a5b91495979bd53badfd33 100644 (file)
@@ -3614,6 +3614,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
 
        SCTP_DBG_OBJCNT_INC(sock);
        atomic_inc(&sctp_sockets_allocated);
+       sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
        return 0;
 }
 
@@ -3628,6 +3629,7 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk)
        ep = sctp_sk(sk)->ep;
        sctp_endpoint_free(ep);
        atomic_dec(&sctp_sockets_allocated);
+       sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
 }
 
 /* API 4.1.7 shutdown() - TCP Style Syntax
index 52910697e104ceaadae120adcd1e5c8375b2c658..f58e994e6852f72a956c24afbc17258f49955aa0 100644 (file)
@@ -63,8 +63,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_rto_initial,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &one,
                .extra2         = &timer_max
        },
@@ -74,8 +74,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_rto_min,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &one,
                .extra2         = &timer_max
        },
@@ -85,8 +85,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_rto_max,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &one,
                .extra2         = &timer_max
        },
@@ -96,8 +96,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_valid_cookie_life,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &one,
                .extra2         = &timer_max
        },
@@ -107,8 +107,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_max_burst,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &zero,
                .extra2         = &int_max
        },
@@ -118,8 +118,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_max_retrans_association,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &one,
                .extra2         = &int_max
        },
@@ -129,8 +129,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_sndbuf_policy,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
-               .strategy       = &sysctl_intvec
+               .proc_handler   = proc_dointvec,
+               .strategy       = sysctl_intvec
        },
        {
                .ctl_name       = NET_SCTP_RCVBUF_POLICY,
@@ -138,8 +138,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_rcvbuf_policy,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
-               .strategy       = &sysctl_intvec
+               .proc_handler   = proc_dointvec,
+               .strategy       = sysctl_intvec
        },
        {
                .ctl_name       = NET_SCTP_PATH_MAX_RETRANS,
@@ -147,8 +147,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_max_retrans_path,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &one,
                .extra2         = &int_max
        },
@@ -158,8 +158,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_max_retrans_init,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &one,
                .extra2         = &int_max
        },
@@ -169,8 +169,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_hb_interval,
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &one,
                .extra2         = &timer_max
        },
@@ -180,8 +180,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_cookie_preserve_enable,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
-               .strategy       = &sysctl_intvec
+               .proc_handler   = proc_dointvec,
+               .strategy       = sysctl_intvec
        },
        {
                .ctl_name       = NET_SCTP_RTO_ALPHA,
@@ -189,8 +189,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_rto_alpha,
                .maxlen         = sizeof(int),
                .mode           = 0444,
-               .proc_handler   = &proc_dointvec,
-               .strategy       = &sysctl_intvec
+               .proc_handler   = proc_dointvec,
+               .strategy       = sysctl_intvec
        },
        {
                .ctl_name       = NET_SCTP_RTO_BETA,
@@ -198,8 +198,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_rto_beta,
                .maxlen         = sizeof(int),
                .mode           = 0444,
-               .proc_handler   = &proc_dointvec,
-               .strategy       = &sysctl_intvec
+               .proc_handler   = proc_dointvec,
+               .strategy       = sysctl_intvec
        },
        {
                .ctl_name       = NET_SCTP_ADDIP_ENABLE,
@@ -207,8 +207,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_addip_enable,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
-               .strategy       = &sysctl_intvec
+               .proc_handler   = proc_dointvec,
+               .strategy       = sysctl_intvec
        },
        {
                .ctl_name       = NET_SCTP_PRSCTP_ENABLE,
@@ -216,8 +216,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_prsctp_enable,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
-               .strategy       = &sysctl_intvec
+               .proc_handler   = proc_dointvec,
+               .strategy       = sysctl_intvec
        },
        {
                .ctl_name       = NET_SCTP_SACK_TIMEOUT,
@@ -225,8 +225,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_sack_timeout,
                .maxlen         = sizeof(long),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .strategy       = &sysctl_intvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .strategy       = sysctl_intvec,
                .extra1         = &sack_timer_min,
                .extra2         = &sack_timer_max,
        },
@@ -236,7 +236,7 @@ static ctl_table sctp_table[] = {
                .data           = &sysctl_sctp_mem,
                .maxlen         = sizeof(sysctl_sctp_mem),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = CTL_UNNUMBERED,
@@ -244,7 +244,7 @@ static ctl_table sctp_table[] = {
                .data           = &sysctl_sctp_rmem,
                .maxlen         = sizeof(sysctl_sctp_rmem),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = CTL_UNNUMBERED,
@@ -252,7 +252,7 @@ static ctl_table sctp_table[] = {
                .data           = &sysctl_sctp_wmem,
                .maxlen         = sizeof(sysctl_sctp_wmem),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = proc_dointvec,
        },
        {
                .ctl_name       = CTL_UNNUMBERED,
@@ -260,8 +260,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_auth_enable,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
-               .strategy       = &sysctl_intvec
+               .proc_handler   = proc_dointvec,
+               .strategy       = sysctl_intvec
        },
        {
                .ctl_name       = CTL_UNNUMBERED,
@@ -269,8 +269,8 @@ static ctl_table sctp_table[] = {
                .data           = &sctp_addip_noauth,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
-               .strategy       = &sysctl_intvec
+               .proc_handler   = proc_dointvec,
+               .strategy       = sysctl_intvec
        },
        { .ctl_name = 0 }
 };
index 57550c3bcabec28ab7ee82030e6d1d4cb36192a0..d7128b761c8c90eb7d7dfe5b9ade45876bc08309 100644 (file)
@@ -69,7 +69,6 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/mutex.h>
-#include <linux/thread_info.h>
 #include <linux/wanrouter.h>
 #include <linux/if_bridge.h>
 #include <linux/if_frad.h>
index 4895c341e46d03b2ad31b23c229e58876dce1c68..3ca518386d15d33959ea12a0fc1315d1e8499b98 100644 (file)
@@ -271,15 +271,15 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
                case AF_INET: {
                        struct sockaddr_in *sin =
                                        (struct sockaddr_in *)args->address;
-                       snprintf(servername, sizeof(servername), NIPQUAD_FMT,
-                                NIPQUAD(sin->sin_addr.s_addr));
+                       snprintf(servername, sizeof(servername), "%pI4",
+                                &sin->sin_addr.s_addr);
                        break;
                }
                case AF_INET6: {
                        struct sockaddr_in6 *sin =
                                        (struct sockaddr_in6 *)args->address;
-                       snprintf(servername, sizeof(servername), NIP6_FMT,
-                                NIP6(sin->sin6_addr));
+                       snprintf(servername, sizeof(servername), "%pI6",
+                                &sin->sin6_addr);
                        break;
                }
                default:
index 41013dd66ac3f3e61e4823ef853911e179efc46b..03ae007641e48523ee22cbd4aa4d5cef825b84c5 100644 (file)
@@ -270,10 +270,9 @@ static int rpcb_register_netid4(struct sockaddr_in *address_to_register,
        char buf[32];
 
        /* Construct AF_INET universal address */
-       snprintf(buf, sizeof(buf),
-                       NIPQUAD_FMT".%u.%u",
-                       NIPQUAD(address_to_register->sin_addr.s_addr),
-                       port >> 8, port & 0xff);
+       snprintf(buf, sizeof(buf), "%pI4.%u.%u",
+                &address_to_register->sin_addr.s_addr,
+                port >> 8, port & 0xff);
        map->r_addr = buf;
 
        dprintk("RPC:       %sregistering [%u, %u, %s, '%s'] with "
@@ -305,9 +304,9 @@ static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register,
                snprintf(buf, sizeof(buf), "::.%u.%u",
                                port >> 8, port & 0xff);
        else
-               snprintf(buf, sizeof(buf), NIP6_FMT".%u.%u",
-                               NIP6(address_to_register->sin6_addr),
-                               port >> 8, port & 0xff);
+               snprintf(buf, sizeof(buf), "%pI6.%u.%u",
+                        &address_to_register->sin6_addr,
+                        port >> 8, port & 0xff);
        map->r_addr = buf;
 
        dprintk("RPC:       %sregistering [%u, %u, %s, '%s'] with "
@@ -422,8 +421,8 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot)
        struct rpc_clnt *rpcb_clnt;
        int status;
 
-       dprintk("RPC:       %s(" NIPQUAD_FMT ", %u, %u, %d)\n",
-               __func__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
+       dprintk("RPC:       %s(%pI4, %u, %u, %d)\n",
+               __func__, &sin->sin_addr.s_addr, prog, vers, prot);
 
        rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin,
                                sizeof(*sin), prot, RPCBVERS_2);
index f24800f2c098c3b83d812881af05947b062a1ed3..82240e6127b2ce08b597f8ad2885b5eb86d5ab1d 100644 (file)
@@ -162,13 +162,9 @@ static void ip_map_request(struct cache_detail *cd,
        struct ip_map *im = container_of(h, struct ip_map, h);
 
        if (ipv6_addr_v4mapped(&(im->m_addr))) {
-               snprintf(text_addr, 20, NIPQUAD_FMT,
-                               ntohl(im->m_addr.s6_addr32[3]) >> 24 & 0xff,
-                               ntohl(im->m_addr.s6_addr32[3]) >> 16 & 0xff,
-                               ntohl(im->m_addr.s6_addr32[3]) >>  8 & 0xff,
-                               ntohl(im->m_addr.s6_addr32[3]) >>  0 & 0xff);
+               snprintf(text_addr, 20, "%pI4", &im->m_addr.s6_addr32[3]);
        } else {
-               snprintf(text_addr, 40, NIP6_FMT, NIP6(im->m_addr));
+               snprintf(text_addr, 40, "%pI6", &im->m_addr);
        }
        qword_add(bpp, blen, im->m_class);
        qword_add(bpp, blen, text_addr);
@@ -208,13 +204,13 @@ static int ip_map_parse(struct cache_detail *cd,
        len = qword_get(&mesg, buf, mlen);
        if (len <= 0) return -EINVAL;
 
-       if (sscanf(buf, NIPQUAD_FMT "%c", &b1, &b2, &b3, &b4, &c) == 4) {
+       if (sscanf(buf, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) == 4) {
                addr.s6_addr32[0] = 0;
                addr.s6_addr32[1] = 0;
                addr.s6_addr32[2] = htonl(0xffff);
                addr.s6_addr32[3] =
                        htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
-       } else if (sscanf(buf, NIP6_FMT "%c",
+       } else if (sscanf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x%c",
                        &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &c) == 8) {
                addr.s6_addr16[0] = htons(b1);
                addr.s6_addr16[1] = htons(b2);
@@ -278,16 +274,10 @@ static int ip_map_show(struct seq_file *m,
                dom = im->m_client->h.name;
 
        if (ipv6_addr_v4mapped(&addr)) {
-               seq_printf(m, "%s " NIPQUAD_FMT " %s\n",
-                       im->m_class,
-                       ntohl(addr.s6_addr32[3]) >> 24 & 0xff,
-                       ntohl(addr.s6_addr32[3]) >> 16 & 0xff,
-                       ntohl(addr.s6_addr32[3]) >>  8 & 0xff,
-                       ntohl(addr.s6_addr32[3]) >>  0 & 0xff,
-                       dom);
+               seq_printf(m, "%s %pI4 %s\n",
+                       im->m_class, &addr.s6_addr32[3], dom);
        } else {
-               seq_printf(m, "%s " NIP6_FMT " %s\n",
-                       im->m_class, NIP6(addr), dom);
+               seq_printf(m, "%s %pI6 %s\n", im->m_class, &addr, dom);
        }
        return 0;
 }
index 95293f549e9c2b371b82ce32af4ca43be00b5ada..6f7d1f2d2f36d00cec3a9e9561c016b032092bdf 100644 (file)
@@ -250,10 +250,10 @@ static int one_sock_name(char *buf, struct svc_sock *svsk)
 
        switch(svsk->sk_sk->sk_family) {
        case AF_INET:
-               len = sprintf(buf, "ipv4 %s %u.%u.%u.%u %d\n",
-                             svsk->sk_sk->sk_protocol==IPPROTO_UDP?
+               len = sprintf(buf, "ipv4 %s %pI4 %d\n",
+                             svsk->sk_sk->sk_protocol == IPPROTO_UDP ?
                              "udp" : "tcp",
-                             NIPQUAD(inet_sk(svsk->sk_sk)->rcv_saddr),
+                             &inet_sk(svsk->sk_sk)->rcv_saddr,
                              inet_sk(svsk->sk_sk)->num);
                break;
        default:
index 6fb493cbd29fcd2786479965bb526ba343e1b70f..f8500f018f8ad0d2f2e2edca55b87dd196e05b19 100644 (file)
@@ -1048,21 +1048,21 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
 
        dprintk("svcrdma: new connection %p accepted with the following "
                "attributes:\n"
-               "    local_ip        : %d.%d.%d.%d\n"
+               "    local_ip        : %pI4\n"
                "    local_port      : %d\n"
-               "    remote_ip       : %d.%d.%d.%d\n"
+               "    remote_ip       : %pI4\n"
                "    remote_port     : %d\n"
                "    max_sge         : %d\n"
                "    sq_depth        : %d\n"
                "    max_requests    : %d\n"
                "    ord             : %d\n",
                newxprt,
-               NIPQUAD(((struct sockaddr_in *)&newxprt->sc_cm_id->
-                        route.addr.src_addr)->sin_addr.s_addr),
+               &((struct sockaddr_in *)&newxprt->sc_cm_id->
+                        route.addr.src_addr)->sin_addr.s_addr,
                ntohs(((struct sockaddr_in *)&newxprt->sc_cm_id->
                       route.addr.src_addr)->sin_port),
-               NIPQUAD(((struct sockaddr_in *)&newxprt->sc_cm_id->
-                        route.addr.dst_addr)->sin_addr.s_addr),
+               &((struct sockaddr_in *)&newxprt->sc_cm_id->
+                        route.addr.dst_addr)->sin_addr.s_addr,
                ntohs(((struct sockaddr_in *)&newxprt->sc_cm_id->
                       route.addr.dst_addr)->sin_port),
                newxprt->sc_max_sge,
index 9839c3d94145d4b154c71ac754f65f9a52239f63..1dd6123070e94b52023a2f6596462edb3928e860 100644 (file)
@@ -174,7 +174,7 @@ xprt_rdma_format_addresses(struct rpc_xprt *xprt)
 
        buf = kzalloc(20, GFP_KERNEL);
        if (buf)
-               snprintf(buf, 20, NIPQUAD_FMT, NIPQUAD(addr->sin_addr.s_addr));
+               snprintf(buf, 20, "%pI4", &addr->sin_addr.s_addr);
        xprt->address_strings[RPC_DISPLAY_ADDR] = buf;
 
        buf = kzalloc(8, GFP_KERNEL);
@@ -186,8 +186,8 @@ xprt_rdma_format_addresses(struct rpc_xprt *xprt)
 
        buf = kzalloc(48, GFP_KERNEL);
        if (buf)
-               snprintf(buf, 48, "addr="NIPQUAD_FMT" port=%u proto=%s",
-                       NIPQUAD(addr->sin_addr.s_addr),
+               snprintf(buf, 48, "addr=%pI4 port=%u proto=%s",
+                       &addr->sin_addr.s_addr,
                        ntohs(addr->sin_port), "rdma");
        xprt->address_strings[RPC_DISPLAY_ALL] = buf;
 
@@ -204,8 +204,8 @@ xprt_rdma_format_addresses(struct rpc_xprt *xprt)
 
        buf = kzalloc(30, GFP_KERNEL);
        if (buf)
-               snprintf(buf, 30, NIPQUAD_FMT".%u.%u",
-                       NIPQUAD(addr->sin_addr.s_addr),
+               snprintf(buf, 30, "%pI4.%u.%u",
+                       &addr->sin_addr.s_addr,
                        ntohs(addr->sin_port) >> 8,
                        ntohs(addr->sin_port) & 0xff);
        xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf;
@@ -369,8 +369,8 @@ xprt_setup_rdma(struct xprt_create *args)
        if (ntohs(sin->sin_port) != 0)
                xprt_set_bound(xprt);
 
-       dprintk("RPC:       %s: %u.%u.%u.%u:%u\n", __func__,
-                       NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+       dprintk("RPC:       %s: %pI4:%u\n",
+               __func__, &sin->sin_addr.s_addr, ntohs(sin->sin_port));
 
        /* Set max requests */
        cdata.max_requests = xprt->max_reqs;
index a5fef5e6c32314b7098fe59756ddb5280681e5df..78f7f728ef10733706326ce297a7335588295a23 100644 (file)
@@ -323,12 +323,11 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
        case RDMA_CM_EVENT_DEVICE_REMOVAL:
                connstate = -ENODEV;
 connected:
-               dprintk("RPC:       %s: %s: %u.%u.%u.%u:%u"
-                       " (ep 0x%p event 0x%x)\n",
+               dprintk("RPC:       %s: %s: %pI4:%u (ep 0x%p event 0x%x)\n",
                        __func__,
                        (event->event <= 11) ? conn[event->event] :
                                                "unknown connection error",
-                       NIPQUAD(addr->sin_addr.s_addr),
+                       &addr->sin_addr.s_addr,
                        ntohs(addr->sin_port),
                        ep, event->event);
                atomic_set(&rpcx_to_rdmax(ep->rep_xprt)->rx_buf.rb_credits, 1);
@@ -348,18 +347,17 @@ connected:
        if (connstate == 1) {
                int ird = attr.max_dest_rd_atomic;
                int tird = ep->rep_remote_cma.responder_resources;
-               printk(KERN_INFO "rpcrdma: connection to %u.%u.%u.%u:%u "
+               printk(KERN_INFO "rpcrdma: connection to %pI4:%u "
                        "on %s, memreg %d slots %d ird %d%s\n",
-                       NIPQUAD(addr->sin_addr.s_addr),
+                       &addr->sin_addr.s_addr,
                        ntohs(addr->sin_port),
                        ia->ri_id->device->name,
                        ia->ri_memreg_strategy,
                        xprt->rx_buf.rb_max_requests,
                        ird, ird < 4 && ird < tird / 2 ? " (low!)" : "");
        } else if (connstate < 0) {
-               printk(KERN_INFO "rpcrdma: connection to %u.%u.%u.%u:%u "
-                       "closed (%d)\n",
-                       NIPQUAD(addr->sin_addr.s_addr),
+               printk(KERN_INFO "rpcrdma: connection to %pI4:%u closed (%d)\n",
+                       &addr->sin_addr.s_addr,
                        ntohs(addr->sin_port),
                        connstate);
        }
index 0a50361e3d83535492160f7f08a36a5a5c34d4be..5cbb404c4cdf89da7a6dd328ec5d7137d2d54dbc 100644 (file)
@@ -284,8 +284,7 @@ static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt,
 
        buf = kzalloc(20, GFP_KERNEL);
        if (buf) {
-               snprintf(buf, 20, NIPQUAD_FMT,
-                               NIPQUAD(addr->sin_addr.s_addr));
+               snprintf(buf, 20, "%pI4", &addr->sin_addr.s_addr);
        }
        xprt->address_strings[RPC_DISPLAY_ADDR] = buf;
 
@@ -300,8 +299,8 @@ static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt,
 
        buf = kzalloc(48, GFP_KERNEL);
        if (buf) {
-               snprintf(buf, 48, "addr="NIPQUAD_FMT" port=%u proto=%s",
-                       NIPQUAD(addr->sin_addr.s_addr),
+               snprintf(buf, 48, "addr=%pI4 port=%u proto=%s",
+                       &addr->sin_addr.s_addr,
                        ntohs(addr->sin_port),
                        protocol);
        }
@@ -323,8 +322,8 @@ static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt,
 
        buf = kzalloc(30, GFP_KERNEL);
        if (buf) {
-               snprintf(buf, 30, NIPQUAD_FMT".%u.%u",
-                               NIPQUAD(addr->sin_addr.s_addr),
+               snprintf(buf, 30, "%pI4.%u.%u",
+                               &addr->sin_addr.s_addr,
                                ntohs(addr->sin_port) >> 8,
                                ntohs(addr->sin_port) & 0xff);
        }
@@ -342,8 +341,7 @@ static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt,
 
        buf = kzalloc(40, GFP_KERNEL);
        if (buf) {
-               snprintf(buf, 40, NIP6_FMT,
-                               NIP6(addr->sin6_addr));
+               snprintf(buf, 40, "%pI6",&addr->sin6_addr);
        }
        xprt->address_strings[RPC_DISPLAY_ADDR] = buf;
 
@@ -358,18 +356,17 @@ static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt,
 
        buf = kzalloc(64, GFP_KERNEL);
        if (buf) {
-               snprintf(buf, 64, "addr="NIP6_FMT" port=%u proto=%s",
-                               NIP6(addr->sin6_addr),
+               snprintf(buf, 64, "addr=%pI6 port=%u proto=%s",
+                               &addr->sin6_addr,
                                ntohs(addr->sin6_port),
                                protocol);
        }
        xprt->address_strings[RPC_DISPLAY_ALL] = buf;
 
        buf = kzalloc(36, GFP_KERNEL);
-       if (buf) {
-               snprintf(buf, 36, NIP6_SEQFMT,
-                               NIP6(addr->sin6_addr));
-       }
+       if (buf)
+               snprintf(buf, 36, "%pi6", &addr->sin6_addr);
+
        xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = buf;
 
        buf = kzalloc(8, GFP_KERNEL);
@@ -381,10 +378,10 @@ static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt,
 
        buf = kzalloc(50, GFP_KERNEL);
        if (buf) {
-               snprintf(buf, 50, NIP6_FMT".%u.%u",
-                               NIP6(addr->sin6_addr),
-                               ntohs(addr->sin6_port) >> 8,
-                               ntohs(addr->sin6_port) & 0xff);
+               snprintf(buf, 50, "%pI6.%u.%u",
+                        &addr->sin6_addr,
+                        ntohs(addr->sin6_port) >> 8,
+                        ntohs(addr->sin6_port) & 0xff);
        }
        xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf;
 
@@ -1415,8 +1412,8 @@ static int xs_bind4(struct sock_xprt *transport, struct socket *sock)
                if (port > last)
                        nloop++;
        } while (err == -EADDRINUSE && nloop != 2);
-       dprintk("RPC:       %s "NIPQUAD_FMT":%u: %s (%d)\n",
-                       __func__, NIPQUAD(myaddr.sin_addr),
+       dprintk("RPC:       %s %pI4:%u: %s (%d)\n",
+                       __func__, &myaddr.sin_addr,
                        port, err ? "failed" : "ok", err);
        return err;
 }
@@ -1448,8 +1445,8 @@ static int xs_bind6(struct sock_xprt *transport, struct socket *sock)
                if (port > last)
                        nloop++;
        } while (err == -EADDRINUSE && nloop != 2);
-       dprintk("RPC:       xs_bind6 "NIP6_FMT":%u: %s (%d)\n",
-               NIP6(myaddr.sin6_addr), port, err ? "failed" : "ok", err);
+       dprintk("RPC:       xs_bind6 %pI6:%u: %s (%d)\n",
+               &myaddr.sin6_addr, port, err ? "failed" : "ok", err);
        return err;
 }
 
index fe43ef7dd7e3ce81652d9d2572b25d2a11df3175..f72ba774c246835228405e712a64c1387c6123e3 100644 (file)
@@ -243,12 +243,11 @@ static int recv_notification(struct notifier_block *nb, unsigned long evt,
 static char *eth_addr2str(struct tipc_media_addr *a, char *str_buf, int str_size)
 {
        unchar *addr = (unchar *)&a->dev_addr;
-       DECLARE_MAC_BUF(mac);
 
        if (str_size < 18)
                *str_buf = '\0';
        else
-               sprintf(str_buf, "%s", print_mac(mac, addr));
+               sprintf(str_buf, "%pM", addr);
        return str_buf;
 }
 
index cd72e22b132b381bad5ebc6e3dbc4fcf231a91f3..acab41a48d675a3f1c3709fb1489c1b433bd5460 100644 (file)
@@ -555,7 +555,7 @@ static struct name_seq *nametbl_find_seq(u32 type)
        struct name_seq *ns;
 
        dbg("find_seq %u,(%u,0x%x) table = %p, hash[type] = %u\n",
-           type, ntohl(type), type, table.types, hash(type));
+           type, htonl(type), type, table.types, hash(type));
 
        seq_head = &table.types[hash(type)];
        hlist_for_each_entry(ns, seq_node, seq_head, ns_list) {
index eb90f77bb0e294b6358db3361740deaa0bec969e..f2cf3f583f626df8bba6cb2bf5df417530eb9ca3 100644 (file)
@@ -164,7 +164,7 @@ static inline int unix_our_peer(struct sock *sk, struct sock *osk)
 
 static inline int unix_may_send(struct sock *sk, struct sock *osk)
 {
-       return (unix_peer(osk) == NULL || unix_our_peer(sk, osk));
+       return unix_peer(osk) == NULL || unix_our_peer(sk, osk);
 }
 
 static inline int unix_recvq_full(struct sock const *sk)
@@ -197,7 +197,7 @@ static inline void unix_release_addr(struct unix_address *addr)
  *             - if started by zero, it is abstract name.
  */
 
-static int unix_mkname(struct sockaddr_un * sunaddr, int len, unsigned *hashp)
+static int unix_mkname(struct sockaddr_un *sunaddr, int len, unsigned *hashp)
 {
        if (len <= sizeof(short) || len > sizeof(*sunaddr))
                return -EINVAL;
@@ -211,12 +211,12 @@ static int unix_mkname(struct sockaddr_un * sunaddr, int len, unsigned *hashp)
                 * we are guaranteed that it is a valid memory location in our
                 * kernel address buffer.
                 */
-               ((char *)sunaddr)[len]=0;
+               ((char *)sunaddr)[len] = 0;
                len = strlen(sunaddr->sun_path)+1+sizeof(short);
                return len;
        }
 
-       *hashp = unix_hash_fold(csum_partial((char*)sunaddr, len, 0));
+       *hashp = unix_hash_fold(csum_partial((char *)sunaddr, len, 0));
        return len;
 }
 
@@ -295,8 +295,7 @@ static struct sock *unix_find_socket_byinode(struct net *net, struct inode *i)
                if (!net_eq(sock_net(s), net))
                        continue;
 
-               if(dentry && dentry->d_inode == i)
-               {
+               if (dentry && dentry->d_inode == i) {
                        sock_hold(s);
                        goto found;
                }
@@ -354,7 +353,7 @@ static void unix_sock_destructor(struct sock *sk)
        WARN_ON(!sk_unhashed(sk));
        WARN_ON(sk->sk_socket);
        if (!sock_flag(sk, SOCK_DEAD)) {
-               printk("Attempt to release alive unix socket: %p\n", sk);
+               printk(KERN_DEBUG "Attempt to release alive unix socket: %p\n", sk);
                return;
        }
 
@@ -362,12 +361,14 @@ static void unix_sock_destructor(struct sock *sk)
                unix_release_addr(u->addr);
 
        atomic_dec(&unix_nr_socks);
+       sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
 #ifdef UNIX_REFCNT_DEBUG
-       printk(KERN_DEBUG "UNIX %p is destroyed, %d are still alive.\n", sk, atomic_read(&unix_nr_socks));
+       printk(KERN_DEBUG "UNIX %p is destroyed, %d are still alive.\n", sk,
+               atomic_read(&unix_nr_socks));
 #endif
 }
 
-static int unix_release_sock (struct sock *sk, int embrion)
+static int unix_release_sock(struct sock *sk, int embrion)
 {
        struct unix_sock *u = unix_sk(sk);
        struct dentry *dentry;
@@ -392,9 +393,9 @@ static int unix_release_sock (struct sock *sk, int embrion)
 
        wake_up_interruptible_all(&u->peer_wait);
 
-       skpair=unix_peer(sk);
+       skpair = unix_peer(sk);
 
-       if (skpair!=NULL) {
+       if (skpair != NULL) {
                if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
                        unix_state_lock(skpair);
                        /* No more writes */
@@ -414,7 +415,7 @@ static int unix_release_sock (struct sock *sk, int embrion)
        /* Try to flush out this socket. Throw out buffers at least */
 
        while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
-               if (state==TCP_LISTEN)
+               if (state == TCP_LISTEN)
                        unix_release_sock(skb->sk, 1);
                /* passed fds are erased in the kfree_skb hook        */
                kfree_skb(skb);
@@ -453,11 +454,11 @@ static int unix_listen(struct socket *sock, int backlog)
        struct unix_sock *u = unix_sk(sk);
 
        err = -EOPNOTSUPP;
-       if (sock->type!=SOCK_STREAM && sock->type!=SOCK_SEQPACKET)
-               goto out;                       /* Only stream/seqpacket sockets accept */
+       if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
+               goto out;       /* Only stream/seqpacket sockets accept */
        err = -EINVAL;
        if (!u->addr)
-               goto out;                       /* No listens on an unbound socket */
+               goto out;       /* No listens on an unbound socket */
        unix_state_lock(sk);
        if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN)
                goto out_unlock;
@@ -566,9 +567,10 @@ static const struct proto_ops unix_seqpacket_ops = {
 };
 
 static struct proto unix_proto = {
-       .name     = "UNIX",
-       .owner    = THIS_MODULE,
-       .obj_size = sizeof(struct unix_sock),
+       .name                   = "UNIX",
+       .owner                  = THIS_MODULE,
+       .sockets_allocated      = &unix_nr_socks,
+       .obj_size               = sizeof(struct unix_sock),
 };
 
 /*
@@ -579,7 +581,7 @@ static struct proto unix_proto = {
  */
 static struct lock_class_key af_unix_sk_receive_queue_lock_key;
 
-static struct sock * unix_create1(struct net *net, struct socket *sock)
+static struct sock *unix_create1(struct net *net, struct socket *sock)
 {
        struct sock *sk = NULL;
        struct unix_sock *u;
@@ -592,7 +594,7 @@ static struct sock * unix_create1(struct net *net, struct socket *sock)
        if (!sk)
                goto out;
 
-       sock_init_data(sock,sk);
+       sock_init_data(sock, sk);
        lockdep_set_class(&sk->sk_receive_queue.lock,
                                &af_unix_sk_receive_queue_lock_key);
 
@@ -611,6 +613,9 @@ static struct sock * unix_create1(struct net *net, struct socket *sock)
 out:
        if (sk == NULL)
                atomic_dec(&unix_nr_socks);
+       else
+               sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
+
        return sk;
 }
 
@@ -630,7 +635,7 @@ static int unix_create(struct net *net, struct socket *sock, int protocol)
                 *      nothing uses it.
                 */
        case SOCK_RAW:
-               sock->type=SOCK_DGRAM;
+               sock->type = SOCK_DGRAM;
        case SOCK_DGRAM:
                sock->ops = &unix_dgram_ops;
                break;
@@ -653,7 +658,7 @@ static int unix_release(struct socket *sock)
 
        sock->sk = NULL;
 
-       return unix_release_sock (sk, 0);
+       return unix_release_sock(sk, 0);
 }
 
 static int unix_autobind(struct socket *sock)
@@ -662,7 +667,7 @@ static int unix_autobind(struct socket *sock)
        struct net *net = sock_net(sk);
        struct unix_sock *u = unix_sk(sk);
        static u32 ordernum = 1;
-       struct unix_address * addr;
+       struct unix_address *addr;
        int err;
 
        mutex_lock(&u->readlock);
@@ -681,7 +686,7 @@ static int unix_autobind(struct socket *sock)
 
 retry:
        addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
-       addr->hash = unix_hash_fold(csum_partial((void*)addr->name, addr->len, 0));
+       addr->hash = unix_hash_fold(csum_partial((void *)addr->name, addr->len, 0));
 
        spin_lock(&unix_table_lock);
        ordernum = (ordernum+1)&0xFFFFF;
@@ -736,14 +741,14 @@ static struct sock *unix_find_other(struct net *net,
 
                path_put(&path);
 
-               err=-EPROTOTYPE;
+               err = -EPROTOTYPE;
                if (u->sk_type != type) {
                        sock_put(u);
                        goto fail;
                }
        } else {
                err = -ECONNREFUSED;
-               u=unix_find_socket_byname(net, sunname, len, type, hash);
+               u = unix_find_socket_byname(net, sunname, len, type, hash);
                if (u) {
                        struct dentry *dentry;
                        dentry = unix_sk(u)->dentry;
@@ -757,7 +762,7 @@ static struct sock *unix_find_other(struct net *net,
 put_fail:
        path_put(&path);
 fail:
-       *error=err;
+       *error = err;
        return NULL;
 }
 
@@ -767,8 +772,8 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        struct sock *sk = sock->sk;
        struct net *net = sock_net(sk);
        struct unix_sock *u = unix_sk(sk);
-       struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
-       struct dentry * dentry = NULL;
+       struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
+       struct dentry *dentry = NULL;
        struct nameidata nd;
        int err;
        unsigned hash;
@@ -779,7 +784,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        if (sunaddr->sun_family != AF_UNIX)
                goto out;
 
-       if (addr_len==sizeof(short)) {
+       if (addr_len == sizeof(short)) {
                err = unix_autobind(sock);
                goto out;
        }
@@ -875,8 +880,8 @@ out_mknod_unlock:
        mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
        path_put(&nd.path);
 out_mknod_parent:
-       if (err==-EEXIST)
-               err=-EADDRINUSE;
+       if (err == -EEXIST)
+               err = -EADDRINUSE;
        unix_release_addr(addr);
        goto out_up;
 }
@@ -911,7 +916,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
 {
        struct sock *sk = sock->sk;
        struct net *net = sock_net(sk);
-       struct sockaddr_un *sunaddr=(struct sockaddr_un*)addr;
+       struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr;
        struct sock *other;
        unsigned hash;
        int err;
@@ -927,7 +932,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
                        goto out;
 
 restart:
-               other=unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
+               other = unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
                if (!other)
                        goto out;
 
@@ -961,14 +966,14 @@ restart:
         */
        if (unix_peer(sk)) {
                struct sock *old_peer = unix_peer(sk);
-               unix_peer(sk)=other;
+               unix_peer(sk) = other;
                unix_state_double_unlock(sk, other);
 
                if (other != old_peer)
                        unix_dgram_disconnected(sk, old_peer);
                sock_put(old_peer);
        } else {
-               unix_peer(sk)=other;
+               unix_peer(sk) = other;
                unix_state_double_unlock(sk, other);
        }
        return 0;
@@ -1004,7 +1009,7 @@ static long unix_wait_for_peer(struct sock *other, long timeo)
 static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
                               int addr_len, int flags)
 {
-       struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
+       struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
        struct sock *sk = sock->sk;
        struct net *net = sock_net(sk);
        struct unix_sock *u = unix_sk(sk), *newu, *otheru;
@@ -1179,13 +1184,13 @@ out:
 
 static int unix_socketpair(struct socket *socka, struct socket *sockb)
 {
-       struct sock *ska=socka->sk, *skb = sockb->sk;
+       struct sock *ska = socka->sk, *skb = sockb->sk;
 
        /* Join our sockets back to back */
        sock_hold(ska);
        sock_hold(skb);
-       unix_peer(ska)=skb;
-       unix_peer(skb)=ska;
+       unix_peer(ska) = skb;
+       unix_peer(skb) = ska;
        ska->sk_peercred.pid = skb->sk_peercred.pid = task_tgid_vnr(current);
        ska->sk_peercred.uid = skb->sk_peercred.uid = current->euid;
        ska->sk_peercred.gid = skb->sk_peercred.gid = current->egid;
@@ -1207,7 +1212,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags)
        int err;
 
        err = -EOPNOTSUPP;
-       if (sock->type!=SOCK_STREAM && sock->type!=SOCK_SEQPACKET)
+       if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
                goto out;
 
        err = -EINVAL;
@@ -1246,7 +1251,7 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_
 {
        struct sock *sk = sock->sk;
        struct unix_sock *u;
-       struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
+       struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
        int err = 0;
 
        if (peer) {
@@ -1286,7 +1291,7 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
        skb->destructor = sock_wfree;
        UNIXCB(skb).fp = NULL;
 
-       for (i=scm->fp->count-1; i>=0; i--)
+       for (i = scm->fp->count-1; i >= 0; i--)
                unix_notinflight(scm->fp->fp[i]);
 }
 
@@ -1315,7 +1320,7 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
        if (!UNIXCB(skb).fp)
                return -ENOMEM;
 
-       for (i=scm->fp->count-1; i>=0; i--)
+       for (i = scm->fp->count-1; i >= 0; i--)
                unix_inflight(scm->fp->fp[i]);
        skb->destructor = unix_destruct_fds;
        return 0;
@@ -1332,7 +1337,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
        struct sock *sk = sock->sk;
        struct net *net = sock_net(sk);
        struct unix_sock *u = unix_sk(sk);
-       struct sockaddr_un *sunaddr=msg->msg_name;
+       struct sockaddr_un *sunaddr = msg->msg_name;
        struct sock *other = NULL;
        int namelen = 0; /* fake GCC */
        int err;
@@ -1373,7 +1378,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
                goto out;
 
        skb = sock_alloc_send_skb(sk, len, msg->msg_flags&MSG_DONTWAIT, &err);
-       if (skb==NULL)
+       if (skb == NULL)
                goto out;
 
        memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
@@ -1385,7 +1390,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
        unix_get_secdata(siocb->scm, skb);
 
        skb_reset_transport_header(skb);
-       err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
+       err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
        if (err)
                goto out_free;
 
@@ -1399,7 +1404,7 @@ restart:
 
                other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
                                        hash, &err);
-               if (other==NULL)
+               if (other == NULL)
                        goto out_free;
        }
 
@@ -1419,7 +1424,7 @@ restart:
                err = 0;
                unix_state_lock(sk);
                if (unix_peer(sk) == other) {
-                       unix_peer(sk)=NULL;
+                       unix_peer(sk) = NULL;
                        unix_state_unlock(sk);
 
                        unix_dgram_disconnected(sk, other);
@@ -1485,10 +1490,10 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
        struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
        struct sock *sk = sock->sk;
        struct sock *other = NULL;
-       struct sockaddr_un *sunaddr=msg->msg_name;
-       int err,size;
+       struct sockaddr_un *sunaddr = msg->msg_name;
+       int err, size;
        struct sk_buff *skb;
-       int sent=0;
+       int sent = 0;
        struct scm_cookie tmp_scm;
 
        if (NULL == siocb->scm)
@@ -1515,8 +1520,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
        if (sk->sk_shutdown & SEND_SHUTDOWN)
                goto pipe_err;
 
-       while(sent < len)
-       {
+       while (sent < len) {
                /*
                 *      Optimisation for the fact that under 0.01% of X
                 *      messages typically need breaking up.
@@ -1535,9 +1539,10 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
                 *      Grab a buffer
                 */
 
-               skb=sock_alloc_send_skb(sk,size,msg->msg_flags&MSG_DONTWAIT, &err);
+               skb = sock_alloc_send_skb(sk, size, msg->msg_flags&MSG_DONTWAIT,
+                                         &err);
 
-               if (skb==NULL)
+               if (skb == NULL)
                        goto out_err;
 
                /*
@@ -1558,7 +1563,8 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
                        }
                }
 
-               if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) {
+               err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
+               if (err) {
                        kfree_skb(skb);
                        goto out_err;
                }
@@ -1572,7 +1578,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
                skb_queue_tail(&other->sk_receive_queue, skb);
                unix_state_unlock(other);
                other->sk_data_ready(other, size);
-               sent+=size;
+               sent += size;
        }
 
        scm_destroy(siocb->scm);
@@ -1584,8 +1590,8 @@ pipe_err_free:
        unix_state_unlock(other);
        kfree_skb(skb);
 pipe_err:
-       if (sent==0 && !(msg->msg_flags&MSG_NOSIGNAL))
-               send_sig(SIGPIPE,current,0);
+       if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL))
+               send_sig(SIGPIPE, current, 0);
        err = -EPIPE;
 out_err:
        scm_destroy(siocb->scm);
@@ -1675,13 +1681,10 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
        siocb->scm->creds = *UNIXCREDS(skb);
        unix_set_secdata(siocb->scm, skb);
 
-       if (!(flags & MSG_PEEK))
-       {
+       if (!(flags & MSG_PEEK)) {
                if (UNIXCB(skb).fp)
                        unix_detach_fds(siocb->scm, skb);
-       }
-       else
-       {
+       } else {
                /* It is questionable: on PEEK we could:
                   - do not return fds - good, but too simple 8)
                   - return fds, and do not return them on read (old strategy,
@@ -1702,7 +1705,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
        scm_recv(sock, msg, siocb->scm, flags);
 
 out_free:
-       skb_free_datagram(sk,skb);
+       skb_free_datagram(sk, skb);
 out_unlock:
        mutex_unlock(&u->readlock);
 out:
@@ -1713,7 +1716,7 @@ out:
  *     Sleep until data has arrive. But check for races..
  */
 
-static long unix_stream_data_wait(struct sock * sk, long timeo)
+static long unix_stream_data_wait(struct sock *sk, long timeo)
 {
        DEFINE_WAIT(wait);
 
@@ -1751,7 +1754,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
        struct scm_cookie tmp_scm;
        struct sock *sk = sock->sk;
        struct unix_sock *u = unix_sk(sk);
-       struct sockaddr_un *sunaddr=msg->msg_name;
+       struct sockaddr_un *sunaddr = msg->msg_name;
        int copied = 0;
        int check_creds = 0;
        int target;
@@ -1782,15 +1785,13 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 
        mutex_lock(&u->readlock);
 
-       do
-       {
+       do {
                int chunk;
                struct sk_buff *skb;
 
                unix_state_lock(sk);
                skb = skb_dequeue(&sk->sk_receive_queue);
-               if (skb==NULL)
-               {
+               if (skb == NULL) {
                        if (copied >= target)
                                goto unlock;
 
@@ -1798,7 +1799,8 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                         *      POSIX 1003.1g mandates this order.
                         */
 
-                       if ((err = sock_error(sk)) != 0)
+                       err = sock_error(sk);
+                       if (err)
                                goto unlock;
                        if (sk->sk_shutdown & RCV_SHUTDOWN)
                                goto unlock;
@@ -1825,7 +1827,8 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 
                if (check_creds) {
                        /* Never glue messages from different writers */
-                       if (memcmp(UNIXCREDS(skb), &siocb->scm->creds, sizeof(siocb->scm->creds)) != 0) {
+                       if (memcmp(UNIXCREDS(skb), &siocb->scm->creds,
+                                  sizeof(siocb->scm->creds)) != 0) {
                                skb_queue_head(&sk->sk_receive_queue, skb);
                                break;
                        }
@@ -1836,8 +1839,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                }
 
                /* Copy address just once */
-               if (sunaddr)
-               {
+               if (sunaddr) {
                        unix_copy_addr(msg, skb->sk);
                        sunaddr = NULL;
                }
@@ -1853,16 +1855,14 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                size -= chunk;
 
                /* Mark read part of skb as used */
-               if (!(flags & MSG_PEEK))
-               {
+               if (!(flags & MSG_PEEK)) {
                        skb_pull(skb, chunk);
 
                        if (UNIXCB(skb).fp)
                                unix_detach_fds(siocb->scm, skb);
 
                        /* put the skb back if we didn't use it up.. */
-                       if (skb->len)
-                       {
+                       if (skb->len) {
                                skb_queue_head(&sk->sk_receive_queue, skb);
                                break;
                        }
@@ -1871,9 +1871,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 
                        if (siocb->scm->fp)
                                break;
-               }
-               else
-               {
+               } else {
                        /* It is questionable, see note in unix_dgram_recvmsg.
                         */
                        if (UNIXCB(skb).fp)
@@ -1901,7 +1899,7 @@ static int unix_shutdown(struct socket *sock, int mode)
        if (mode) {
                unix_state_lock(sk);
                sk->sk_shutdown |= mode;
-               other=unix_peer(sk);
+               other = unix_peer(sk);
                if (other)
                        sock_hold(other);
                unix_state_unlock(sk);
@@ -1936,16 +1934,15 @@ static int unix_shutdown(struct socket *sock, int mode)
 static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        struct sock *sk = sock->sk;
-       long amount=0;
+       long amount = 0;
        int err;
 
-       switch(cmd)
-       {
-               case SIOCOUTQ:
-                       amount = atomic_read(&sk->sk_wmem_alloc);
-                       err = put_user(amount, (int __user *)arg);
-                       break;
-               case SIOCINQ:
+       switch (cmd) {
+       case SIOCOUTQ:
+               amount = atomic_read(&sk->sk_wmem_alloc);
+               err = put_user(amount, (int __user *)arg);
+               break;
+       case SIOCINQ:
                {
                        struct sk_buff *skb;
 
@@ -1962,21 +1959,21 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        } else {
                                skb = skb_peek(&sk->sk_receive_queue);
                                if (skb)
-                                       amount=skb->len;
+                                       amount = skb->len;
                        }
                        spin_unlock(&sk->sk_receive_queue.lock);
                        err = put_user(amount, (int __user *)arg);
                        break;
                }
 
-               default:
-                       err = -ENOIOCTLCMD;
-                       break;
+       default:
+               err = -ENOIOCTLCMD;
+               break;
        }
        return err;
 }
 
-static unsigned int unix_poll(struct file * file, struct socket *sock, poll_table *wait)
+static unsigned int unix_poll(struct file *file, struct socket *sock, poll_table *wait)
 {
        struct sock *sk = sock->sk;
        unsigned int mask;
@@ -1998,7 +1995,8 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl
                mask |= POLLIN | POLLRDNORM;
 
        /* Connection-based need to check for termination and startup */
-       if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) && sk->sk_state == TCP_CLOSE)
+       if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
+           sk->sk_state == TCP_CLOSE)
                mask |= POLLHUP;
 
        /*
@@ -2094,6 +2092,7 @@ struct unix_iter_state {
        struct seq_net_private p;
        int i;
 };
+
 static struct sock *unix_seq_idx(struct seq_file *seq, loff_t pos)
 {
        struct unix_iter_state *iter = seq->private;
@@ -2110,7 +2109,6 @@ static struct sock *unix_seq_idx(struct seq_file *seq, loff_t pos)
        return NULL;
 }
 
-
 static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
        __acquires(unix_table_lock)
 {
@@ -2190,7 +2188,6 @@ static const struct seq_operations unix_seq_ops = {
        .show   = unix_seq_show,
 };
 
-
 static int unix_seq_open(struct inode *inode, struct file *file)
 {
        return seq_open_net(inode, file, &unix_seq_ops,
index 6d4a9a8de5ef1d8974a4f8fe17956dfd31b63fe6..5a0061d6b9bc903bd5f74c789555588634b3da8d 100644 (file)
@@ -104,8 +104,8 @@ static struct sock *unix_get_socket(struct file *filp)
         *      Socket ?
         */
        if (S_ISSOCK(inode->i_mode)) {
-               struct socket * sock = SOCKET_I(inode);
-               struct sock * s = sock->sk;
+               struct socket *sock = SOCKET_I(inode);
+               struct sock *s = sock->sk;
 
                /*
                 *      PF_UNIX ?
@@ -124,7 +124,7 @@ static struct sock *unix_get_socket(struct file *filp)
 void unix_inflight(struct file *fp)
 {
        struct sock *s = unix_get_socket(fp);
-       if(s) {
+       if (s) {
                struct unix_sock *u = unix_sk(s);
                spin_lock(&unix_gc_lock);
                if (atomic_long_inc_return(&u->inflight) == 1) {
@@ -141,7 +141,7 @@ void unix_inflight(struct file *fp)
 void unix_notinflight(struct file *fp)
 {
        struct sock *s = unix_get_socket(fp);
-       if(s) {
+       if (s) {
                struct unix_sock *u = unix_sk(s);
                spin_lock(&unix_gc_lock);
                BUG_ON(list_empty(&u->link));
@@ -154,7 +154,7 @@ void unix_notinflight(struct file *fp)
 
 static inline struct sk_buff *sock_queue_head(struct sock *sk)
 {
-       return (struct sk_buff *) &sk->sk_receive_queue;
+       return (struct sk_buff *)&sk->sk_receive_queue;
 }
 
 #define receive_queue_for_each_skb(sk, next, skb) \
@@ -364,7 +364,7 @@ void unix_gc(void)
         */
        skb_queue_head_init(&hitlist);
        list_for_each_entry(u, &gc_candidates, link)
-               scan_children(&u->sk, inc_inflight, &hitlist);
+       scan_children(&u->sk, inc_inflight, &hitlist);
 
        spin_unlock(&unix_gc_lock);
 
index 77513d7e35f2522251452754deaa4c1b949a2ed3..83c093077ebc845ae89979ff8e0724b99a03f095 100644 (file)
@@ -21,7 +21,7 @@ static ctl_table unix_table[] = {
                .data           = &init_net.unx.sysctl_max_dgram_qlen,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = proc_dointvec
        },
        { .ctl_name = 0 }
 };
@@ -61,4 +61,3 @@ void unix_sysctl_unregister(struct net *net)
        unregister_sysctl_table(net->unx.ctl);
        kfree(table);
 }
-
index 646c7121dbc0a78ca0c3018f6e6025ff9bca5249..ae7f2262dfb5f37253f5ecc3ac705a948add04d6 100644 (file)
@@ -72,3 +72,13 @@ config WIRELESS_EXT_SYSFS
 
          Say Y if you have programs using it, like old versions of
          hal.
+
+config LIB80211
+       tristate "Common routines for IEEE802.11 drivers"
+       default n
+       help
+         This options enables a library of common routines used
+         by IEEE802.11 wireless LAN drivers.
+
+         Drivers should select this themselves if needed.  Say Y if
+         you want this built into your kernel.
index b9f943c45f3b2584e3462d61af9cd1d799cc6579..d2d848d445f211001a919875fc4265e5ebfac4f7 100644 (file)
@@ -1,5 +1,6 @@
 obj-$(CONFIG_WIRELESS_EXT) += wext.o
 obj-$(CONFIG_CFG80211) += cfg80211.o
+obj-$(CONFIG_LIB80211) += lib80211.o
 
 cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o
 cfg80211-$(CONFIG_NL80211) += nl80211.o
index 5031db7b275b734b46870089765420c75c136d10..39e3d10fccdef5cf49761227e71868a88b997e79 100644 (file)
@@ -236,8 +236,7 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
        mutex_unlock(&cfg80211_drv_mutex);
 
        /* give it a proper name */
-       snprintf(drv->wiphy.dev.bus_id, BUS_ID_SIZE,
-                PHY_NAME "%d", drv->idx);
+       dev_set_name(&drv->wiphy.dev, PHY_NAME "%d", drv->idx);
 
        mutex_init(&drv->mtx);
        mutex_init(&drv->devlist_mtx);
@@ -301,12 +300,10 @@ int wiphy_register(struct wiphy *wiphy)
        /* check and set up bitrates */
        ieee80211_set_bitrate_flags(wiphy);
 
+       mutex_lock(&cfg80211_drv_mutex);
+
        /* set up regulatory info */
-       mutex_lock(&cfg80211_reg_mutex);
        wiphy_update_regulatory(wiphy, REGDOM_SET_BY_CORE);
-       mutex_unlock(&cfg80211_reg_mutex);
-
-       mutex_lock(&cfg80211_drv_mutex);
 
        res = device_add(&drv->wiphy.dev);
        if (res)
diff --git a/net/wireless/lib80211.c b/net/wireless/lib80211.c
new file mode 100644 (file)
index 0000000..e71f7d0
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * lib80211 -- common bits for IEEE802.11 drivers
+ *
+ * Copyright(c) 2008 John W. Linville <linville@tuxdriver.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/ctype.h>
+#include <linux/ieee80211.h>
+
+#include <net/lib80211.h>
+
+#define DRV_NAME        "lib80211"
+
+#define DRV_DESCRIPTION        "common routines for IEEE802.11 drivers"
+
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_AUTHOR("John W. Linville <linville@tuxdriver.com>");
+MODULE_LICENSE("GPL");
+
+const char *print_ssid(char *buf, const char *ssid, u8 ssid_len)
+{
+       const char *s = ssid;
+       char *d = buf;
+
+       ssid_len = min_t(u8, ssid_len, IEEE80211_MAX_SSID_LEN);
+       while (ssid_len--) {
+               if (isprint(*s)) {
+                       *d++ = *s++;
+                       continue;
+               }
+
+               *d++ = '\\';
+               if (*s == '\0')
+                       *d++ = '0';
+               else if (*s == '\n')
+                       *d++ = 'n';
+               else if (*s == '\r')
+                       *d++ = 'r';
+               else if (*s == '\t')
+                       *d++ = 't';
+               else if (*s == '\\')
+                       *d++ = '\\';
+               else
+                       d += snprintf(d, 3, "%03o", *s);
+               s++;
+       }
+       *d = '\0';
+       return buf;
+}
+EXPORT_SYMBOL(print_ssid);
+
+static int __init ieee80211_init(void)
+{
+       printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION "\n");
+       return 0;
+}
+
+static void __exit ieee80211_exit(void)
+{
+}
+
+module_init(ieee80211_init);
+module_exit(ieee80211_exit);
index 572793c8c7ab6b576dae03753b69503ee05f04cf..e3e1494e769a43c97c9b414665d00af15c05262f 100644 (file)
@@ -58,6 +58,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
        [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
        [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
                                      .len = BUS_ID_SIZE-1 },
+       [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
 
        [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
        [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
@@ -84,7 +85,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
                                               .len = NL80211_MAX_SUPP_RATES },
        [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 },
        [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
-       [NL80211_ATTR_MNTR_FLAGS] = { .type = NLA_NESTED },
+       [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
        [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
                                .len = IEEE80211_MAX_MESH_ID_LEN },
        [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
@@ -95,6 +96,10 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
        [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
        [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
        [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
+       [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
+                                          .len = NL80211_MAX_SUPP_RATES },
+
+       [NL80211_ATTR_MESH_PARAMS] = { .type = NLA_NESTED },
 
        [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
                                         .len = NL80211_HT_CAPABILITY_LEN },
@@ -157,6 +162,19 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
                if (!nl_band)
                        goto nla_put_failure;
 
+               /* add HT info */
+               if (dev->wiphy.bands[band]->ht_cap.ht_supported) {
+                       NLA_PUT(msg, NL80211_BAND_ATTR_HT_MCS_SET,
+                               sizeof(dev->wiphy.bands[band]->ht_cap.mcs),
+                               &dev->wiphy.bands[band]->ht_cap.mcs);
+                       NLA_PUT_U16(msg, NL80211_BAND_ATTR_HT_CAPA,
+                               dev->wiphy.bands[band]->ht_cap.cap);
+                       NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
+                               dev->wiphy.bands[band]->ht_cap.ampdu_factor);
+                       NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
+                               dev->wiphy.bands[band]->ht_cap.ampdu_density);
+               }
+
                /* add frequencies */
                nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
                if (!nl_freqs)
@@ -269,20 +287,76 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
        return -ENOBUFS;
 }
 
+static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
+       [NL80211_TXQ_ATTR_QUEUE]                = { .type = NLA_U8 },
+       [NL80211_TXQ_ATTR_TXOP]                 = { .type = NLA_U16 },
+       [NL80211_TXQ_ATTR_CWMIN]                = { .type = NLA_U16 },
+       [NL80211_TXQ_ATTR_CWMAX]                = { .type = NLA_U16 },
+       [NL80211_TXQ_ATTR_AIFS]                 = { .type = NLA_U8 },
+};
+
+static int parse_txq_params(struct nlattr *tb[],
+                           struct ieee80211_txq_params *txq_params)
+{
+       if (!tb[NL80211_TXQ_ATTR_QUEUE] || !tb[NL80211_TXQ_ATTR_TXOP] ||
+           !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
+           !tb[NL80211_TXQ_ATTR_AIFS])
+               return -EINVAL;
+
+       txq_params->queue = nla_get_u8(tb[NL80211_TXQ_ATTR_QUEUE]);
+       txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
+       txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
+       txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
+       txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
+
+       return 0;
+}
+
 static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
 {
        struct cfg80211_registered_device *rdev;
-       int result;
-
-       if (!info->attrs[NL80211_ATTR_WIPHY_NAME])
-               return -EINVAL;
+       int result = 0, rem_txq_params = 0;
+       struct nlattr *nl_txq_params;
 
        rdev = cfg80211_get_dev_from_info(info);
        if (IS_ERR(rdev))
                return PTR_ERR(rdev);
 
-       result = cfg80211_dev_rename(rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
+       if (info->attrs[NL80211_ATTR_WIPHY_NAME]) {
+               result = cfg80211_dev_rename(
+                       rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
+               if (result)
+                       goto bad_res;
+       }
+
+       if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
+               struct ieee80211_txq_params txq_params;
+               struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
+
+               if (!rdev->ops->set_txq_params) {
+                       result = -EOPNOTSUPP;
+                       goto bad_res;
+               }
 
+               nla_for_each_nested(nl_txq_params,
+                                   info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
+                                   rem_txq_params) {
+                       nla_parse(tb, NL80211_TXQ_ATTR_MAX,
+                                 nla_data(nl_txq_params),
+                                 nla_len(nl_txq_params),
+                                 txq_params_policy);
+                       result = parse_txq_params(tb, &txq_params);
+                       if (result)
+                               goto bad_res;
+
+                       result = rdev->ops->set_txq_params(&rdev->wiphy,
+                                                          &txq_params);
+                       if (result)
+                               goto bad_res;
+               }
+       }
+
+bad_res:
        cfg80211_put_dev(rdev);
        return result;
 }
@@ -1598,6 +1672,12 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
        if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
                params.use_short_slot_time =
                    nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
+       if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
+               params.basic_rates =
+                       nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
+               params.basic_rates_len =
+                       nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
+       }
 
        err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
        if (err)
@@ -1680,11 +1760,188 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
                return -EINVAL;
 #endif
        mutex_lock(&cfg80211_drv_mutex);
-       r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data, NULL);
+       r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data);
        mutex_unlock(&cfg80211_drv_mutex);
        return r;
 }
 
+static int nl80211_get_mesh_params(struct sk_buff *skb,
+       struct genl_info *info)
+{
+       struct cfg80211_registered_device *drv;
+       struct mesh_config cur_params;
+       int err;
+       struct net_device *dev;
+       void *hdr;
+       struct nlattr *pinfoattr;
+       struct sk_buff *msg;
+
+       /* Look up our device */
+       err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+       if (err)
+               return err;
+
+       /* Get the mesh params */
+       rtnl_lock();
+       err = drv->ops->get_mesh_params(&drv->wiphy, dev, &cur_params);
+       rtnl_unlock();
+       if (err)
+               goto out;
+
+       /* Draw up a netlink message to send back */
+       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       if (!msg) {
+               err = -ENOBUFS;
+               goto out;
+       }
+       hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+                            NL80211_CMD_GET_MESH_PARAMS);
+       if (!hdr)
+               goto nla_put_failure;
+       pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS);
+       if (!pinfoattr)
+               goto nla_put_failure;
+       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
+       NLA_PUT_U16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
+                       cur_params.dot11MeshRetryTimeout);
+       NLA_PUT_U16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
+                       cur_params.dot11MeshConfirmTimeout);
+       NLA_PUT_U16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
+                       cur_params.dot11MeshHoldingTimeout);
+       NLA_PUT_U16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
+                       cur_params.dot11MeshMaxPeerLinks);
+       NLA_PUT_U8(msg, NL80211_MESHCONF_MAX_RETRIES,
+                       cur_params.dot11MeshMaxRetries);
+       NLA_PUT_U8(msg, NL80211_MESHCONF_TTL,
+                       cur_params.dot11MeshTTL);
+       NLA_PUT_U8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
+                       cur_params.auto_open_plinks);
+       NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
+                       cur_params.dot11MeshHWMPmaxPREQretries);
+       NLA_PUT_U32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
+                       cur_params.path_refresh_time);
+       NLA_PUT_U16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
+                       cur_params.min_discovery_timeout);
+       NLA_PUT_U32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
+                       cur_params.dot11MeshHWMPactivePathTimeout);
+       NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
+                       cur_params.dot11MeshHWMPpreqMinInterval);
+       NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
+                       cur_params.dot11MeshHWMPnetDiameterTraversalTime);
+       nla_nest_end(msg, pinfoattr);
+       genlmsg_end(msg, hdr);
+       err = genlmsg_unicast(msg, info->snd_pid);
+       goto out;
+
+nla_put_failure:
+       genlmsg_cancel(msg, hdr);
+       err = -EMSGSIZE;
+out:
+       /* Cleanup */
+       cfg80211_put_dev(drv);
+       dev_put(dev);
+       return err;
+}
+
+#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
+do {\
+       if (table[attr_num]) {\
+               cfg.param = nla_fn(table[attr_num]); \
+               mask |= (1 << (attr_num - 1)); \
+       } \
+} while (0);\
+
+static struct nla_policy
+nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] __read_mostly = {
+       [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 },
+       [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 },
+       [NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 },
+       [NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 },
+       [NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 },
+       [NL80211_MESHCONF_TTL] = { .type = NLA_U8 },
+       [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
+
+       [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
+       [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
+       [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
+       [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
+       [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
+       [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
+};
+
+static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
+{
+       int err;
+       u32 mask;
+       struct cfg80211_registered_device *drv;
+       struct net_device *dev;
+       struct mesh_config cfg;
+       struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
+       struct nlattr *parent_attr;
+
+       parent_attr = info->attrs[NL80211_ATTR_MESH_PARAMS];
+       if (!parent_attr)
+               return -EINVAL;
+       if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
+                       parent_attr, nl80211_meshconf_params_policy))
+               return -EINVAL;
+
+       err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+       if (err)
+               return err;
+
+       /* This makes sure that there aren't more than 32 mesh config
+        * parameters (otherwise our bitfield scheme would not work.) */
+       BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
+
+       /* Fill in the params struct */
+       mask = 0;
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout,
+                       mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout,
+                       mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, nla_get_u16);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout,
+                       mask, NL80211_MESHCONF_HOLDING_TIMEOUT, nla_get_u16);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks,
+                       mask, NL80211_MESHCONF_MAX_PEER_LINKS, nla_get_u16);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries,
+                       mask, NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL,
+                       mask, NL80211_MESHCONF_TTL, nla_get_u8);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks,
+                       mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries,
+                       mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
+                       nla_get_u8);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time,
+                       mask, NL80211_MESHCONF_PATH_REFRESH_TIME, nla_get_u32);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout,
+                       mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
+                       nla_get_u16);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
+                       mask, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
+                       nla_get_u32);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
+                       mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
+                       nla_get_u16);
+       FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
+                       dot11MeshHWMPnetDiameterTraversalTime,
+                       mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
+                       nla_get_u16);
+
+       /* Apply changes */
+       rtnl_lock();
+       err = drv->ops->set_mesh_params(&drv->wiphy, dev, &cfg, mask);
+       rtnl_unlock();
+
+       /* cleanup */
+       cfg80211_put_dev(drv);
+       dev_put(dev);
+       return err;
+}
+
+#undef FILL_IN_MESH_PARAM_IF_SET
+
 static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
 {
        struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
@@ -1743,12 +2000,9 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
        mutex_lock(&cfg80211_drv_mutex);
        r = set_regdom(rd);
        mutex_unlock(&cfg80211_drv_mutex);
-       if (r)
-               goto bad_reg;
-
        return r;
 
-bad_reg:
+ bad_reg:
        kfree(rd);
        return -EINVAL;
 }
@@ -1902,6 +2156,18 @@ static struct genl_ops nl80211_ops[] = {
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
        },
+       {
+               .cmd = NL80211_CMD_GET_MESH_PARAMS,
+               .doit = nl80211_get_mesh_params,
+               .policy = nl80211_policy,
+               /* can be retrieved by unprivileged users */
+       },
+       {
+               .cmd = NL80211_CMD_SET_MESH_PARAMS,
+               .doit = nl80211_set_mesh_params,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
 };
 
 /* multicast groups */
index 626dbb688499bd9dafa0b963305df65d3ac0c04a..4c7e39d466c430e34d4f2ec5bad649f1f6111ca7 100644 (file)
 #include "core.h"
 #include "reg.h"
 
-/* wiphy is set if this request's initiator is REGDOM_SET_BY_DRIVER */
+/**
+ * struct regulatory_request - receipt of last regulatory request
+ *
+ * @wiphy: this is set if this request's initiator is
+ *     %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This
+ *     can be used by the wireless core to deal with conflicts
+ *     and potentially inform users of which devices specifically
+ *     cased the conflicts.
+ * @initiator: indicates who sent this request, could be any of
+ *     of those set in reg_set_by, %REGDOM_SET_BY_*
+ * @alpha2: the ISO / IEC 3166 alpha2 country code of the requested
+ *     regulatory domain. We have a few special codes:
+ *     00 - World regulatory domain
+ *     99 - built by driver but a specific alpha2 cannot be determined
+ *     98 - result of an intersection between two regulatory domains
+ * @intersect: indicates whether the wireless core should intersect
+ *     the requested regulatory domain with the presently set regulatory
+ *     domain.
+ */
 struct regulatory_request {
-       struct list_head list;
        struct wiphy *wiphy;
-       int granted;
        enum reg_set_by initiator;
        char alpha2[2];
+       bool intersect;
 };
 
-static LIST_HEAD(regulatory_requests);
-DEFINE_MUTEX(cfg80211_reg_mutex);
+/* Receipt of information from last regulatory request */
+static struct regulatory_request *last_request;
 
 /* To trigger userspace events */
 static struct platform_device *reg_pdev;
@@ -63,8 +80,6 @@ static u32 supported_bandwidths[] = {
        MHZ_TO_KHZ(20),
 };
 
-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 */
@@ -204,7 +219,7 @@ static void reset_regdomains(void)
  * core upon initialization */
 static void update_world_regdomain(const struct ieee80211_regdomain *rd)
 {
-       BUG_ON(list_empty(&regulatory_requests));
+       BUG_ON(!last_request);
 
        reset_regdomains();
 
@@ -300,121 +315,13 @@ static int call_crda(const char *alpha2)
        return kobject_uevent_env(&reg_pdev->dev.kobj, KOBJ_CHANGE, envp);
 }
 
-/* This has the logic which determines when a new request
- * should be ignored. */
-static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
-       char *alpha2, struct ieee80211_regdomain *rd)
-{
-       struct regulatory_request *last_request = NULL;
-
-       /* All initial requests are respected */
-       if (list_empty(&regulatory_requests))
-               return 0;
-
-       last_request = list_first_entry(&regulatory_requests,
-               struct regulatory_request, list);
-
-       switch (set_by) {
-       case REGDOM_SET_BY_INIT:
-               return -EINVAL;
-       case REGDOM_SET_BY_CORE:
-               /* Always respect new wireless core hints, should only
-                * come in for updating the world regulatory domain at init
-                * anyway */
-               return 0;
-       case REGDOM_SET_BY_COUNTRY_IE:
-               if (last_request->initiator == set_by) {
-                       if (last_request->wiphy != wiphy) {
-                               /* Two cards with two APs claiming different
-                                * different Country IE alpha2s!
-                                * You're special!! */
-                               if (!alpha2_equal(last_request->alpha2,
-                                               cfg80211_regdomain->alpha2)) {
-                                       /* XXX: Deal with conflict, consider
-                                        * building a new one out of the
-                                        * intersection */
-                                       WARN_ON(1);
-                                       return -EOPNOTSUPP;
-                               }
-                               return -EALREADY;
-                       }
-                       /* Two consecutive Country IE hints on the same wiphy */
-                       if (!alpha2_equal(cfg80211_regdomain->alpha2, alpha2))
-                               return 0;
-                       return -EALREADY;
-               }
-               if (WARN_ON(!is_alpha2_set(alpha2) || !is_an_alpha2(alpha2)),
-                               "Invalid Country IE regulatory hint passed "
-                               "to the wireless core\n")
-                       return -EINVAL;
-               /* We ignore Country IE hints for now, as we haven't yet
-                * added the dot11MultiDomainCapabilityEnabled flag
-                * for wiphys */
-               return 1;
-       case REGDOM_SET_BY_DRIVER:
-               BUG_ON(!wiphy);
-               if (last_request->initiator == set_by) {
-                       /* Two separate drivers hinting different things,
-                        * this is possible if you have two devices present
-                        * on a system with different EEPROM regulatory
-                        * readings. XXX: Do intersection, we support only
-                        * the first regulatory hint for now */
-                       if (last_request->wiphy != wiphy)
-                               return -EALREADY;
-                       if (rd)
-                               return -EALREADY;
-                       /* Driver should not be trying to hint different
-                        * regulatory domains! */
-                       BUG_ON(!alpha2_equal(alpha2,
-                                       cfg80211_regdomain->alpha2));
-                       return -EALREADY;
-               }
-               if (last_request->initiator == REGDOM_SET_BY_CORE)
-                       return 0;
-               /* XXX: Handle intersection, and add the
-                * dot11MultiDomainCapabilityEnabled flag to wiphy. For now
-                * we assume the driver has this set to false, following the
-                * 802.11d dot11MultiDomainCapabilityEnabled documentation */
-               if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
-                       return 0;
-               return 0;
-       case REGDOM_SET_BY_USER:
-               if (last_request->initiator == set_by ||
-                               last_request->initiator == REGDOM_SET_BY_CORE)
-                       return 0;
-               /* Drivers can use their wiphy's reg_notifier()
-                * to override any information */
-               if (last_request->initiator == REGDOM_SET_BY_DRIVER)
-                       return 0;
-               /* XXX: Handle intersection */
-               if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
-                       return -EOPNOTSUPP;
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
-static bool __reg_is_valid_request(const char *alpha2,
-       struct regulatory_request **request)
-{
-       struct regulatory_request *req;
-       if (list_empty(&regulatory_requests))
-               return false;
-       list_for_each_entry(req, &regulatory_requests, list) {
-               if (alpha2_equal(req->alpha2, alpha2)) {
-                       *request = req;
-                       return true;
-               }
-       }
-       return false;
-}
-
 /* Used by nl80211 before kmalloc'ing our regulatory domain */
 bool reg_is_valid_request(const char *alpha2)
 {
-       struct regulatory_request *request = NULL;
-       return  __reg_is_valid_request(alpha2, &request);
+       if (!last_request)
+               return false;
+
+       return alpha2_equal(last_request->alpha2, alpha2);
 }
 
 /* Sanity check on a regulatory rule */
@@ -431,7 +338,7 @@ static bool is_valid_reg_rule(const struct ieee80211_reg_rule *rule)
 
        freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
 
-       if (freq_range->max_bandwidth_khz > freq_diff)
+       if (freq_diff <= 0 || freq_range->max_bandwidth_khz > freq_diff)
                return false;
 
        return true;
@@ -469,6 +376,143 @@ static u32 freq_max_bandwidth(const struct ieee80211_freq_range *freq_range,
        return 0;
 }
 
+/* Helper for regdom_intersect(), this does the real
+ * mathematical intersection fun */
+static int reg_rules_intersect(
+       const struct ieee80211_reg_rule *rule1,
+       const struct ieee80211_reg_rule *rule2,
+       struct ieee80211_reg_rule *intersected_rule)
+{
+       const struct ieee80211_freq_range *freq_range1, *freq_range2;
+       struct ieee80211_freq_range *freq_range;
+       const struct ieee80211_power_rule *power_rule1, *power_rule2;
+       struct ieee80211_power_rule *power_rule;
+       u32 freq_diff;
+
+       freq_range1 = &rule1->freq_range;
+       freq_range2 = &rule2->freq_range;
+       freq_range = &intersected_rule->freq_range;
+
+       power_rule1 = &rule1->power_rule;
+       power_rule2 = &rule2->power_rule;
+       power_rule = &intersected_rule->power_rule;
+
+       freq_range->start_freq_khz = max(freq_range1->start_freq_khz,
+               freq_range2->start_freq_khz);
+       freq_range->end_freq_khz = min(freq_range1->end_freq_khz,
+               freq_range2->end_freq_khz);
+       freq_range->max_bandwidth_khz = min(freq_range1->max_bandwidth_khz,
+               freq_range2->max_bandwidth_khz);
+
+       freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
+       if (freq_range->max_bandwidth_khz > freq_diff)
+               freq_range->max_bandwidth_khz = freq_diff;
+
+       power_rule->max_eirp = min(power_rule1->max_eirp,
+               power_rule2->max_eirp);
+       power_rule->max_antenna_gain = min(power_rule1->max_antenna_gain,
+               power_rule2->max_antenna_gain);
+
+       intersected_rule->flags = (rule1->flags | rule2->flags);
+
+       if (!is_valid_reg_rule(intersected_rule))
+               return -EINVAL;
+
+       return 0;
+}
+
+/**
+ * regdom_intersect - do the intersection between two regulatory domains
+ * @rd1: first regulatory domain
+ * @rd2: second regulatory domain
+ *
+ * Use this function to get the intersection between two regulatory domains.
+ * Once completed we will mark the alpha2 for the rd as intersected, "98",
+ * as no one single alpha2 can represent this regulatory domain.
+ *
+ * Returns a pointer to the regulatory domain structure which will hold the
+ * resulting intersection of rules between rd1 and rd2. We will
+ * kzalloc() this structure for you.
+ */
+static struct ieee80211_regdomain *regdom_intersect(
+       const struct ieee80211_regdomain *rd1,
+       const struct ieee80211_regdomain *rd2)
+{
+       int r, size_of_regd;
+       unsigned int x, y;
+       unsigned int num_rules = 0, rule_idx = 0;
+       const struct ieee80211_reg_rule *rule1, *rule2;
+       struct ieee80211_reg_rule *intersected_rule;
+       struct ieee80211_regdomain *rd;
+       /* This is just a dummy holder to help us count */
+       struct ieee80211_reg_rule irule;
+
+       /* Uses the stack temporarily for counter arithmetic */
+       intersected_rule = &irule;
+
+       memset(intersected_rule, 0, sizeof(struct ieee80211_reg_rule));
+
+       if (!rd1 || !rd2)
+               return NULL;
+
+       /* First we get a count of the rules we'll need, then we actually
+        * build them. This is to so we can malloc() and free() a
+        * regdomain once. The reason we use reg_rules_intersect() here
+        * is it will return -EINVAL if the rule computed makes no sense.
+        * All rules that do check out OK are valid. */
+
+       for (x = 0; x < rd1->n_reg_rules; x++) {
+               rule1 = &rd1->reg_rules[x];
+               for (y = 0; y < rd2->n_reg_rules; y++) {
+                       rule2 = &rd2->reg_rules[y];
+                       if (!reg_rules_intersect(rule1, rule2,
+                                       intersected_rule))
+                               num_rules++;
+                       memset(intersected_rule, 0,
+                                       sizeof(struct ieee80211_reg_rule));
+               }
+       }
+
+       if (!num_rules)
+               return NULL;
+
+       size_of_regd = sizeof(struct ieee80211_regdomain) +
+               ((num_rules + 1) * sizeof(struct ieee80211_reg_rule));
+
+       rd = kzalloc(size_of_regd, GFP_KERNEL);
+       if (!rd)
+               return NULL;
+
+       for (x = 0; x < rd1->n_reg_rules; x++) {
+               rule1 = &rd1->reg_rules[x];
+               for (y = 0; y < rd2->n_reg_rules; y++) {
+                       rule2 = &rd2->reg_rules[y];
+                       /* This time around instead of using the stack lets
+                        * write to the target rule directly saving ourselves
+                        * a memcpy() */
+                       intersected_rule = &rd->reg_rules[rule_idx];
+                       r = reg_rules_intersect(rule1, rule2,
+                               intersected_rule);
+                       /* No need to memset here the intersected rule here as
+                        * we're not using the stack anymore */
+                       if (r)
+                               continue;
+                       rule_idx++;
+               }
+       }
+
+       if (rule_idx != num_rules) {
+               kfree(rd);
+               return NULL;
+       }
+
+       rd->n_reg_rules = num_rules;
+       rd->alpha2[0] = '9';
+       rd->alpha2[1] = '8';
+
+       return rd;
+}
+
 /* XXX: add support for the rest of enum nl80211_reg_rule_flags, we may
  * want to just have the channel structure use these */
 static u32 map_regdom_flags(u32 rd_flags)
@@ -578,22 +622,81 @@ void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby)
        }
 }
 
+/* Return value which can be used by ignore_request() to indicate
+ * it has been determined we should intersect two regulatory domains */
+#define REG_INTERSECT  1
+
+/* This has the logic which determines when a new request
+ * should be ignored. */
+static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
+                         const char *alpha2)
+{
+       /* All initial requests are respected */
+       if (!last_request)
+               return 0;
+
+       switch (set_by) {
+       case REGDOM_SET_BY_INIT:
+               return -EINVAL;
+       case REGDOM_SET_BY_CORE:
+               /*
+                * Always respect new wireless core hints, should only happen
+                * when updating the world regulatory domain at init.
+                */
+               return 0;
+       case REGDOM_SET_BY_COUNTRY_IE:
+               if (unlikely(!is_an_alpha2(alpha2)))
+                       return -EINVAL;
+               if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) {
+                       if (last_request->wiphy != wiphy) {
+                               /*
+                                * Two cards with two APs claiming different
+                                * different Country IE alpha2s. We could
+                                * intersect them, but that seems unlikely
+                                * to be correct. Reject second one for now.
+                                */
+                               if (!alpha2_equal(alpha2,
+                                                 cfg80211_regdomain->alpha2))
+                                       return -EOPNOTSUPP;
+                               return -EALREADY;
+                       }
+                       /* Two consecutive Country IE hints on the same wiphy */
+                       if (!alpha2_equal(cfg80211_regdomain->alpha2, alpha2))
+                               return 0;
+                       return -EALREADY;
+               }
+               /*
+                * Ignore Country IE hints for now, need to think about
+                * what we need to do to support multi-domain operation.
+                */
+               return -EOPNOTSUPP;
+       case REGDOM_SET_BY_DRIVER:
+               if (last_request->initiator == REGDOM_SET_BY_DRIVER)
+                       return -EALREADY;
+               return 0;
+       case REGDOM_SET_BY_USER:
+               if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
+                       return REG_INTERSECT;
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
 /* Caller must hold &cfg80211_drv_mutex */
 int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
-                     const char *alpha2, struct ieee80211_regdomain *rd)
+                     const char *alpha2)
 {
        struct regulatory_request *request;
-       char *rd_alpha2;
+       bool intersect = false;
        int r = 0;
 
-       r = ignore_request(wiphy, set_by, (char *) alpha2, rd);
-       if (r)
-               return r;
+       r = ignore_request(wiphy, set_by, alpha2);
 
-       if (rd)
-               rd_alpha2 = rd->alpha2;
-       else
-               rd_alpha2 = (char *) alpha2;
+       if (r == REG_INTERSECT)
+               intersect = true;
+       else if (r)
+               return r;
 
        switch (set_by) {
        case REGDOM_SET_BY_CORE:
@@ -601,18 +704,18 @@ int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
        case REGDOM_SET_BY_DRIVER:
        case REGDOM_SET_BY_USER:
                request = kzalloc(sizeof(struct regulatory_request),
-                       GFP_KERNEL);
+                                 GFP_KERNEL);
                if (!request)
                        return -ENOMEM;
 
-               request->alpha2[0] = rd_alpha2[0];
-               request->alpha2[1] = rd_alpha2[1];
+               request->alpha2[0] = alpha2[0];
+               request->alpha2[1] = alpha2[1];
                request->initiator = set_by;
                request->wiphy = wiphy;
+               request->intersect = intersect;
 
-               list_add_tail(&request->list, &regulatory_requests);
-               if (rd)
-                       break;
+               kfree(last_request);
+               last_request = request;
                r = call_crda(alpha2);
 #ifndef CONFIG_WIRELESS_OLD_REGULATORY
                if (r)
@@ -627,26 +730,13 @@ int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
        return r;
 }
 
-/* If rd is not NULL and if this call fails the caller must free it */
-int regulatory_hint(struct wiphy *wiphy, const char *alpha2,
-       struct ieee80211_regdomain *rd)
+void regulatory_hint(struct wiphy *wiphy, const char *alpha2)
 {
-       int r;
-       BUG_ON(!rd && !alpha2);
+       BUG_ON(!alpha2);
 
        mutex_lock(&cfg80211_drv_mutex);
-
-       r = __regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER, alpha2, rd);
-       if (r || !rd)
-               goto unlock_and_exit;
-
-       /* If the driver passed a regulatory domain we skipped asking
-        * userspace for one so we can now go ahead and set it */
-       r = set_regdom(rd);
-
-unlock_and_exit:
+       __regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER, alpha2);
        mutex_unlock(&cfg80211_drv_mutex);
-       return r;
 }
 EXPORT_SYMBOL(regulatory_hint);
 
@@ -705,21 +795,21 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
        print_rd_rules(rd);
 }
 
-void print_regdomain_info(const struct ieee80211_regdomain *rd)
+static 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);
 }
 
+/* Takes ownership of rd only if it doesn't fail */
 static int __set_regdom(const struct ieee80211_regdomain *rd)
 {
-       struct regulatory_request *request = NULL;
-
+       const struct ieee80211_regdomain *intersected_rd = NULL;
        /* Some basic sanity checks first */
 
        if (is_world_regdom(rd->alpha2)) {
-               if (WARN_ON(!__reg_is_valid_request(rd->alpha2, &request)))
+               if (WARN_ON(!reg_is_valid_request(rd->alpha2)))
                        return -EINVAL;
                update_world_regdomain(rd);
                return 0;
@@ -729,7 +819,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
                        !is_unknown_alpha2(rd->alpha2))
                return -EINVAL;
 
-       if (list_empty(&regulatory_requests))
+       if (!last_request)
                return -EINVAL;
 
        /* allow overriding the static definitions if CRDA is present */
@@ -742,13 +832,13 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
         * to review or adjust their own settings based on their own
         * internal EEPROM data */
 
-       if (WARN_ON(!__reg_is_valid_request(rd->alpha2, &request)))
+       if (WARN_ON(!reg_is_valid_request(rd->alpha2)))
                return -EINVAL;
 
        reset_regdomains();
 
        /* Country IE parsing coming soon */
-       switch (request->initiator) {
+       switch (last_request->initiator) {
        case REGDOM_SET_BY_CORE:
        case REGDOM_SET_BY_DRIVER:
        case REGDOM_SET_BY_USER:
@@ -765,9 +855,16 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
                return -EOPNOTSUPP;
        }
 
+       if (unlikely(last_request->intersect)) {
+               intersected_rd = regdom_intersect(rd, cfg80211_regdomain);
+               if (!intersected_rd)
+                       return -EINVAL;
+               kfree(rd);
+               rd = intersected_rd;
+       }
+
        /* Tada! */
        cfg80211_regdomain = rd;
-       request->granted = 1;
 
        return 0;
 }
@@ -775,46 +872,23 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
 
 /* Use this call to set the current regulatory domain. Conflicts with
  * 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 */
+ * kmalloc'd the rd structure. Caller must hold cfg80211_drv_mutex */
 int set_regdom(const struct ieee80211_regdomain *rd)
 {
-       struct regulatory_request *this_request = NULL, *prev_request = NULL;
        int r;
 
-       if (!list_empty(&regulatory_requests))
-               prev_request = list_first_entry(&regulatory_requests,
-                       struct regulatory_request, list);
-
        /* Note that this doesn't update the wiphys, this is done below */
        r = __set_regdom(rd);
-       if (r)
+       if (r) {
+               kfree(rd);
                return r;
-
-       BUG_ON((!__reg_is_valid_request(rd->alpha2, &this_request)));
-
-       /* The initial standard core update of the world regulatory domain, no
-        * need to keep that request info around if it didn't fail. */
-       if (is_world_regdom(rd->alpha2) &&
-                       this_request->initiator == REGDOM_SET_BY_CORE &&
-                       this_request->granted) {
-               list_del(&this_request->list);
-               kfree(this_request);
-               this_request = NULL;
-       }
-
-       /* Remove old requests, we only leave behind the last one */
-       if (prev_request) {
-               list_del(&prev_request->list);
-               kfree(prev_request);
-               prev_request = NULL;
        }
 
        /* This would make this whole thing pointless */
        BUG_ON(rd != cfg80211_regdomain);
 
        /* update all wiphys now with the new established regulatory domain */
-       update_all_wiphy_regulatory(this_request->initiator);
+       update_all_wiphy_regulatory(last_request->initiator);
 
        print_regdomain(rd);
 
@@ -838,13 +912,13 @@ int regulatory_init(void)
         * 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')
+       if (ieee80211_regdom[0] != 'E' || ieee80211_regdom[1] != 'U')
                err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE,
-                                       ieee80211_regdom, NULL);
+                                       ieee80211_regdom);
 #else
        cfg80211_regdomain = cfg80211_world_regdom;
 
-       err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE, "00", NULL);
+       err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE, "00");
        if (err)
                printk(KERN_ERR "cfg80211: calling CRDA failed - "
                       "unable to update world regulatory domain, "
@@ -856,16 +930,12 @@ int regulatory_init(void)
 
 void regulatory_exit(void)
 {
-       struct regulatory_request *req, *req_tmp;
-
        mutex_lock(&cfg80211_drv_mutex);
 
        reset_regdomains();
 
-       list_for_each_entry_safe(req, req_tmp, &regulatory_requests, list) {
-               list_del(&req->list);
-               kfree(req);
-       }
+       kfree(last_request);
+
        platform_device_unregister(reg_pdev);
 
        mutex_unlock(&cfg80211_drv_mutex);
index a33362872f3cc3820ae46c32c010400242912bc0..c9b6b6358bbebb31ff2bd219fb419abd7f806297 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef __NET_WIRELESS_REG_H
 #define __NET_WIRELESS_REG_H
 
-extern struct mutex cfg80211_reg_mutex;
 bool is_world_regdom(const char *alpha2);
 bool reg_is_valid_request(const char *alpha2);
 
@@ -10,4 +9,23 @@ void regulatory_exit(void);
 
 int set_regdom(const struct ieee80211_regdomain *rd);
 
+/**
+ * __regulatory_hint - hint to the wireless core a regulatory domain
+ * @wiphy: if the hint comes from country information from an AP, this
+ *     is required to be set to the wiphy that received the information
+ * @alpha2: the ISO/IEC 3166 alpha2 being claimed the regulatory domain
+ *     should be in.
+ *
+ * The Wireless subsystem can use this function to hint to the wireless core
+ * what it believes should be the current regulatory domain by
+ * giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory
+ * domain should be in.
+ *
+ * Returns zero if all went fine, %-EALREADY if a regulatory domain had
+ * already been set or other standard error codes.
+ *
+ */
+extern int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
+                            const char *alpha2);
+
 #endif  /* __NET_WIRELESS_REG_H */
index f54424693a38a378bd5e7cdc25326907b5fbb983..e76cc28b034557fc1dfcadbae21a09307f6fee5c 100644 (file)
@@ -7,6 +7,25 @@
 #include <asm/bitops.h>
 #include "core.h"
 
+struct ieee80211_rate *
+ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
+                           u64 basic_rates, int bitrate)
+{
+       struct ieee80211_rate *result = &sband->bitrates[0];
+       int i;
+
+       for (i = 0; i < sband->n_bitrates; i++) {
+               if (!(basic_rates & BIT(i)))
+                       continue;
+               if (sband->bitrates[i].bitrate > bitrate)
+                       continue;
+               result = &sband->bitrates[i];
+       }
+
+       return result;
+}
+EXPORT_SYMBOL(ieee80211_get_response_rate);
+
 int ieee80211_channel_to_frequency(int chan)
 {
        if (chan < 14)
index 6ebda25c24e96a4471ee7eb8aa3db69b2411075d..a5d3416522de124b7458c21641dcc2e648d03577 100644 (file)
@@ -24,8 +24,8 @@ static struct ctl_table x25_table[] = {
                .data =         &sysctl_x25_restart_request_timeout,
                .maxlen =       sizeof(int),
                .mode =         0644,
-               .proc_handler = &proc_dointvec_minmax,
-               .strategy =     &sysctl_intvec,
+               .proc_handler = proc_dointvec_minmax,
+               .strategy =     sysctl_intvec,
                .extra1 =       &min_timer,
                .extra2 =       &max_timer,
        },
@@ -35,8 +35,8 @@ static struct ctl_table x25_table[] = {
                .data =         &sysctl_x25_call_request_timeout,
                .maxlen =       sizeof(int),
                .mode =         0644,
-               .proc_handler = &proc_dointvec_minmax,
-               .strategy =     &sysctl_intvec,
+               .proc_handler = proc_dointvec_minmax,
+               .strategy =     sysctl_intvec,
                .extra1 =       &min_timer,
                .extra2 =       &max_timer,
        },
@@ -46,8 +46,8 @@ static struct ctl_table x25_table[] = {
                .data =         &sysctl_x25_reset_request_timeout,
                .maxlen =       sizeof(int),
                .mode =         0644,
-               .proc_handler = &proc_dointvec_minmax,
-               .strategy =     &sysctl_intvec,
+               .proc_handler = proc_dointvec_minmax,
+               .strategy =     sysctl_intvec,
                .extra1 =       &min_timer,
                .extra2 =       &max_timer,
        },
@@ -57,8 +57,8 @@ static struct ctl_table x25_table[] = {
                .data =         &sysctl_x25_clear_request_timeout,
                .maxlen =       sizeof(int),
                .mode =         0644,
-               .proc_handler = &proc_dointvec_minmax,
-               .strategy =     &sysctl_intvec,
+               .proc_handler = proc_dointvec_minmax,
+               .strategy =     sysctl_intvec,
                .extra1 =       &min_timer,
                .extra2 =       &max_timer,
        },
@@ -68,8 +68,8 @@ static struct ctl_table x25_table[] = {
                .data =         &sysctl_x25_ack_holdback_timeout,
                .maxlen =       sizeof(int),
                .mode =         0644,
-               .proc_handler = &proc_dointvec_minmax,
-               .strategy =     &sysctl_intvec,
+               .proc_handler = proc_dointvec_minmax,
+               .strategy =     sysctl_intvec,
                .extra1 =       &min_timer,
                .extra2 =       &max_timer,
        },
@@ -79,7 +79,7 @@ static struct ctl_table x25_table[] = {
                .data =         &sysctl_x25_forward,
                .maxlen =       sizeof(int),
                .mode =         0644,
-               .proc_handler = &proc_dointvec,
+               .proc_handler = proc_dointvec,
        },
        { 0, },
 };
index 058f04f54b9024857eb418321d6842bd448c744a..17854884f6ff7104ccbfc94daa924966ed3319bd 100644 (file)
@@ -521,7 +521,7 @@ static DECLARE_WORK(xfrm_hash_work, xfrm_hash_resize);
 
 /* Generate new index... KAME seems to generate them ordered by cost
  * of an absolute inpredictability of ordering of rules. This will not pass. */
-static u32 xfrm_gen_index(u8 type, int dir)
+static u32 xfrm_gen_index(int dir)
 {
        static u32 idx_generator;
 
@@ -608,7 +608,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
                list_del(&delpol->walk.all);
                xfrm_policy_count[dir]--;
        }
-       policy->index = delpol ? delpol->index : xfrm_gen_index(policy->type, dir);
+       policy->index = delpol ? delpol->index : xfrm_gen_index(dir);
        hlist_add_head(&policy->byidx, xfrm_policy_byidx+idx_hash(policy->index));
        policy->curlft.add_time = get_seconds();
        policy->curlft.use_time = 0;
@@ -1138,7 +1138,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
        sk->sk_policy[dir] = pol;
        if (pol) {
                pol->curlft.add_time = get_seconds();
-               pol->index = xfrm_gen_index(pol->type, XFRM_POLICY_MAX+dir);
+               pol->index = xfrm_gen_index(XFRM_POLICY_MAX+dir);
                __xfrm_policy_link(pol, XFRM_POLICY_MAX+dir);
        }
        if (old_pol)
@@ -2381,9 +2381,7 @@ static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void
 }
 
 static struct notifier_block xfrm_dev_notifier = {
-       xfrm_dev_event,
-       NULL,
-       0
+       .notifier_call  = xfrm_dev_event,
 };
 
 #ifdef CONFIG_XFRM_STATISTICS
@@ -2457,25 +2455,21 @@ static void xfrm_audit_common_policyinfo(struct xfrm_policy *xp,
 
        switch(sel->family) {
        case AF_INET:
-               audit_log_format(audit_buf, " src=" NIPQUAD_FMT,
-                                NIPQUAD(sel->saddr.a4));
+               audit_log_format(audit_buf, " src=%pI4", &sel->saddr.a4);
                if (sel->prefixlen_s != 32)
                        audit_log_format(audit_buf, " src_prefixlen=%d",
                                         sel->prefixlen_s);
-               audit_log_format(audit_buf, " dst=" NIPQUAD_FMT,
-                                NIPQUAD(sel->daddr.a4));
+               audit_log_format(audit_buf, " dst=%pI4", &sel->daddr.a4);
                if (sel->prefixlen_d != 32)
                        audit_log_format(audit_buf, " dst_prefixlen=%d",
                                         sel->prefixlen_d);
                break;
        case AF_INET6:
-               audit_log_format(audit_buf, " src=" NIP6_FMT,
-                                NIP6(*(struct in6_addr *)sel->saddr.a6));
+               audit_log_format(audit_buf, " src=%pI6", sel->saddr.a6);
                if (sel->prefixlen_s != 128)
                        audit_log_format(audit_buf, " src_prefixlen=%d",
                                         sel->prefixlen_s);
-               audit_log_format(audit_buf, " dst=" NIP6_FMT,
-                                NIP6(*(struct in6_addr *)sel->daddr.a6));
+               audit_log_format(audit_buf, " dst=%pI6", sel->daddr.a6);
                if (sel->prefixlen_d != 128)
                        audit_log_format(audit_buf, " dst_prefixlen=%d",
                                         sel->prefixlen_d);
index 508337f97249d421e524013cdd83c86b6cbbf210..cd9d9171ded75bb06d190b0d50474b75e00f9772 100644 (file)
@@ -2109,16 +2109,12 @@ static void xfrm_audit_helper_sainfo(struct xfrm_state *x,
 
        switch(x->props.family) {
        case AF_INET:
-               audit_log_format(audit_buf,
-                                " src=" NIPQUAD_FMT " dst=" NIPQUAD_FMT,
-                                NIPQUAD(x->props.saddr.a4),
-                                NIPQUAD(x->id.daddr.a4));
+               audit_log_format(audit_buf, " src=%pI4 dst=%pI4",
+                                &x->props.saddr.a4, &x->id.daddr.a4);
                break;
        case AF_INET6:
-               audit_log_format(audit_buf,
-                                " src=" NIP6_FMT " dst=" NIP6_FMT,
-                                NIP6(*(struct in6_addr *)x->props.saddr.a6),
-                                NIP6(*(struct in6_addr *)x->id.daddr.a6));
+               audit_log_format(audit_buf, " src=%pI6 dst=%pI6",
+                                x->props.saddr.a6, x->id.daddr.a6);
                break;
        }
 
@@ -2134,18 +2130,14 @@ static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family,
        switch (family) {
        case AF_INET:
                iph4 = ip_hdr(skb);
-               audit_log_format(audit_buf,
-                                " src=" NIPQUAD_FMT " dst=" NIPQUAD_FMT,
-                                NIPQUAD(iph4->saddr),
-                                NIPQUAD(iph4->daddr));
+               audit_log_format(audit_buf, " src=%pI4 dst=%pI4",
+                                &iph4->saddr, &iph4->daddr);
                break;
        case AF_INET6:
                iph6 = ipv6_hdr(skb);
                audit_log_format(audit_buf,
-                                " src=" NIP6_FMT " dst=" NIP6_FMT
-                                " flowlbl=0x%x%02x%02x",
-                                NIP6(iph6->saddr),
-                                NIP6(iph6->daddr),
+                                " src=%pI6 dst=%pI6 flowlbl=0x%x%02x%02x",
+                                &iph6->saddr,&iph6->daddr,
                                 iph6->flow_lbl[0] & 0x0f,
                                 iph6->flow_lbl[1],
                                 iph6->flow_lbl[2]);
index a278a6f3b9913eedb9d80f8e46e930520704ae3f..ee15d5dd65442fd38173447a08e08a81bdfe1c39 100644 (file)
@@ -2503,6 +2503,57 @@ static int xfrm_send_report(u8 proto, struct xfrm_selector *sel,
        return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_REPORT, GFP_ATOMIC);
 }
 
+static inline size_t xfrm_mapping_msgsize(void)
+{
+       return NLMSG_ALIGN(sizeof(struct xfrm_user_mapping));
+}
+
+static int build_mapping(struct sk_buff *skb, struct xfrm_state *x,
+                        xfrm_address_t *new_saddr, __be16 new_sport)
+{
+       struct xfrm_user_mapping *um;
+       struct nlmsghdr *nlh;
+
+       nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_MAPPING, sizeof(*um), 0);
+       if (nlh == NULL)
+               return -EMSGSIZE;
+
+       um = nlmsg_data(nlh);
+
+       memcpy(&um->id.daddr, &x->id.daddr, sizeof(um->id.daddr));
+       um->id.spi = x->id.spi;
+       um->id.family = x->props.family;
+       um->id.proto = x->id.proto;
+       memcpy(&um->new_saddr, new_saddr, sizeof(um->new_saddr));
+       memcpy(&um->old_saddr, &x->props.saddr, sizeof(um->old_saddr));
+       um->new_sport = new_sport;
+       um->old_sport = x->encap->encap_sport;
+       um->reqid = x->props.reqid;
+
+       return nlmsg_end(skb, nlh);
+}
+
+static int xfrm_send_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
+                            __be16 sport)
+{
+       struct sk_buff *skb;
+
+       if (x->id.proto != IPPROTO_ESP)
+               return -EINVAL;
+
+       if (!x->encap)
+               return -EINVAL;
+
+       skb = nlmsg_new(xfrm_mapping_msgsize(), GFP_ATOMIC);
+       if (skb == NULL)
+               return -ENOMEM;
+
+       if (build_mapping(skb, x, ipaddr, sport) < 0)
+               BUG();
+
+       return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_MAPPING, GFP_ATOMIC);
+}
+
 static struct xfrm_mgr netlink_mgr = {
        .id             = "netlink",
        .notify         = xfrm_send_state_notify,
@@ -2511,6 +2562,7 @@ static struct xfrm_mgr netlink_mgr = {
        .notify_policy  = xfrm_send_policy_notify,
        .report         = xfrm_send_report,
        .migrate        = xfrm_send_migrate,
+       .new_mapping    = xfrm_send_mapping,
 };
 
 static int __init xfrm_user_init(void)
index cb30c7e350b356c00a8d77dc5532ff20b6e5f62d..d43bd6baeeaa9e1c4526d1fd8a82eaf57c9472c8 100644 (file)
@@ -495,7 +495,7 @@ static inline void avc_print_ipv6_addr(struct audit_buffer *ab,
                                       char *name1, char *name2)
 {
        if (!ipv6_addr_any(addr))
-               audit_log_format(ab, " %s=" NIP6_FMT, name1, NIP6(*addr));
+               audit_log_format(ab, " %s=%pI6", name1, addr);
        if (port)
                audit_log_format(ab, " %s=%d", name2, ntohs(port));
 }
@@ -504,7 +504,7 @@ static inline void avc_print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
                                       __be16 port, char *name1, char *name2)
 {
        if (addr)
-               audit_log_format(ab, " %s=" NIPQUAD_FMT, name1, NIPQUAD(addr));
+               audit_log_format(ab, " %s=%pI4", name1, &addr);
        if (port)
                audit_log_format(ab, " %s=%d", name2, ntohs(port));
 }
index f85597a4d733f06d89e69987cf48f02606bb2d27..f3c4bc12fea380c0b2888bafd39caaaca7ba5148 100644 (file)
@@ -4628,7 +4628,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
         * as fast and as clean as possible. */
        if (selinux_compat_net || !selinux_policycap_netpeer)
                return selinux_ip_postroute_compat(skb, ifindex, family);
-
+#ifdef CONFIG_XFRM
        /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
         * packet transformation so allow the packet to pass without any checks
         * since we'll have another chance to perform access control checks
@@ -4637,7 +4637,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
         *       is NULL, in this case go ahead and apply access control. */
        if (skb->dst != NULL && skb->dst->xfrm != NULL)
                return NF_ACCEPT;
-
+#endif
        secmark_active = selinux_secmark_enabled();
        peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
        if (!secmark_active && !peerlbl_active)