aboutsummaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/3c501.c3
-rw-r--r--drivers/net/3c503.c3
-rw-r--r--drivers/net/3c505.c51
-rw-r--r--drivers/net/3c507.c4
-rw-r--r--drivers/net/3c509.c6
-rw-r--r--drivers/net/3c515.c5
-rw-r--r--drivers/net/3c523.c40
-rw-r--r--drivers/net/3c527.c4
-rw-r--r--drivers/net/3c59x.c13
-rw-r--r--drivers/net/7990.c1
-rw-r--r--drivers/net/8139cp.c39
-rw-r--r--drivers/net/8139too.c33
-rw-r--r--drivers/net/82596.c42
-rw-r--r--drivers/net/Kconfig32
-rw-r--r--drivers/net/Makefile2
-rw-r--r--drivers/net/a2065.c5
-rw-r--r--drivers/net/ac3200.c5
-rw-r--r--drivers/net/acenic.c26
-rw-r--r--drivers/net/amd8111e.c6
-rw-r--r--drivers/net/apne.c3
-rw-r--r--drivers/net/appletalk/cops.c1
-rw-r--r--drivers/net/appletalk/ipddp.c6
-rw-r--r--drivers/net/appletalk/ltpc.c13
-rw-r--r--drivers/net/arcnet/arc-rawmode.c5
-rw-r--r--drivers/net/arcnet/arc-rimi.c16
-rw-r--r--drivers/net/arcnet/arcnet.c32
-rw-r--r--drivers/net/arcnet/capmode.c7
-rw-r--r--drivers/net/arcnet/com20020-isa.c4
-rw-r--r--drivers/net/arcnet/com20020-pci.c2
-rw-r--r--drivers/net/arcnet/com20020.c10
-rw-r--r--drivers/net/arcnet/com90io.c4
-rw-r--r--drivers/net/arcnet/com90xx.c10
-rw-r--r--drivers/net/arcnet/rfc1051.c9
-rw-r--r--drivers/net/arcnet/rfc1201.c14
-rw-r--r--drivers/net/ariadne.c21
-rw-r--r--drivers/net/arm/am79c961a.c7
-rw-r--r--drivers/net/arm/at91_ether.c11
-rw-r--r--drivers/net/arm/ep93xx_eth.c2
-rw-r--r--drivers/net/arm/ether1.c5
-rw-r--r--drivers/net/arm/ether3.c5
-rw-r--r--drivers/net/arm/etherh.c5
-rw-r--r--drivers/net/arm/ixp4xx_eth.c1
-rw-r--r--drivers/net/at1700.c4
-rw-r--r--drivers/net/atarilance.c52
-rw-r--r--drivers/net/atl1e/atl1e_main.c39
-rw-r--r--drivers/net/atlx/atl1.c96
-rw-r--r--drivers/net/atlx/atl1.h4
-rw-r--r--drivers/net/atlx/atl2.c97
-rw-r--r--drivers/net/atlx/atl2.h1
-rw-r--r--drivers/net/atlx/atlx.c13
-rw-r--r--drivers/net/atp.c8
-rw-r--r--drivers/net/au1000_eth.c49
-rw-r--r--drivers/net/ax88796.c9
-rw-r--r--drivers/net/b44.c6
-rw-r--r--drivers/net/bfin_mac.c1
-rw-r--r--drivers/net/bmac.c7
-rw-r--r--drivers/net/bnx2.c37
-rw-r--r--drivers/net/bnx2.h35
-rw-r--r--drivers/net/bnx2x_main.c16
-rw-r--r--drivers/net/bonding/Makefile3
-rw-r--r--drivers/net/bonding/bond_3ad.c333
-rw-r--r--drivers/net/bonding/bond_3ad.h10
-rw-r--r--drivers/net/bonding/bond_alb.c25
-rw-r--r--drivers/net/bonding/bond_ipv6.c218
-rw-r--r--drivers/net/bonding/bond_main.c261
-rw-r--r--drivers/net/bonding/bond_sysfs.c150
-rw-r--r--drivers/net/bonding/bonding.h39
-rw-r--r--drivers/net/cassini.c6
-rw-r--r--drivers/net/chelsio/cxgb2.c90
-rw-r--r--drivers/net/chelsio/sge.c3
-rw-r--r--drivers/net/cpmac.c5
-rw-r--r--drivers/net/cris/eth_v10.c4
-rw-r--r--drivers/net/cs89x0.c14
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c98
-rw-r--r--drivers/net/cxgb3/sge.c1
-rw-r--r--drivers/net/de600.c4
-rw-r--r--drivers/net/de620.c9
-rw-r--r--drivers/net/declance.c7
-rw-r--r--drivers/net/defxx.c3
-rw-r--r--drivers/net/depca.c47
-rw-r--r--drivers/net/dl2k.c6
-rw-r--r--drivers/net/dm9000.c40
-rw-r--r--drivers/net/e100.c49
-rw-r--r--drivers/net/e1000/e1000_main.c56
-rw-r--r--drivers/net/e1000e/82571.c6
-rw-r--r--drivers/net/e1000e/defines.h7
-rw-r--r--drivers/net/e1000e/hw.h1
-rw-r--r--drivers/net/e1000e/netdev.c50
-rw-r--r--drivers/net/eepro.c8
-rw-r--r--drivers/net/eepro100.c2401
-rw-r--r--drivers/net/eexpress.c1
-rw-r--r--drivers/net/ehea/ehea.h2
-rw-r--r--drivers/net/ehea/ehea_main.c1
-rw-r--r--drivers/net/ehea/ehea_qmr.c10
-rw-r--r--drivers/net/enc28j60.c19
-rw-r--r--drivers/net/enic/enic_main.c30
-rw-r--r--drivers/net/enic/enic_res.c7
-rw-r--r--drivers/net/enic/vnic_dev.c10
-rw-r--r--drivers/net/epic100.c50
-rw-r--r--drivers/net/es3210.c9
-rw-r--r--drivers/net/eth16i.c3
-rw-r--r--drivers/net/ewrk3.c8
-rw-r--r--drivers/net/fealnx.c6
-rw-r--r--drivers/net/fec.c6
-rw-r--r--drivers/net/fec_mpc52xx.c3
-rw-r--r--drivers/net/forcedeth.c42
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c5
-rw-r--r--drivers/net/gianfar.c8
-rw-r--r--drivers/net/hamachi.c6
-rw-r--r--drivers/net/hamradio/6pack.c1
-rw-r--r--drivers/net/hamradio/baycom_epp.c1
-rw-r--r--drivers/net/hamradio/bpqether.c8
-rw-r--r--drivers/net/hamradio/dmascc.c13
-rw-r--r--drivers/net/hamradio/hdlcdrv.c1
-rw-r--r--drivers/net/hamradio/mkiss.c1
-rw-r--r--drivers/net/hamradio/scc.c13
-rw-r--r--drivers/net/hamradio/yam.c1
-rw-r--r--drivers/net/hp-plus.c3
-rw-r--r--drivers/net/hp.c3
-rw-r--r--drivers/net/hp100.c7
-rw-r--r--drivers/net/hydra.c5
-rw-r--r--drivers/net/ibm_newemac/core.c11
-rw-r--r--drivers/net/ibmlana.c6
-rw-r--r--drivers/net/ibmveth.c40
-rw-r--r--drivers/net/ifb.c11
-rw-r--r--drivers/net/igb/igb.h4
-rw-r--r--drivers/net/igb/igb_ethtool.c106
-rw-r--r--drivers/net/igb/igb_main.c57
-rw-r--r--drivers/net/ioc3-eth.c13
-rw-r--r--drivers/net/ipg.c9
-rw-r--r--drivers/net/irda/ali-ircc.c17
-rw-r--r--drivers/net/irda/au1k_ir.c1
-rw-r--r--drivers/net/irda/donauboe.c8
-rw-r--r--drivers/net/irda/irda-usb.c15
-rw-r--r--drivers/net/irda/kingsun-sir.c1
-rw-r--r--drivers/net/irda/ks959-sir.c1
-rw-r--r--drivers/net/irda/ksdazzle-sir.c1
-rw-r--r--drivers/net/irda/mcs7780.c1
-rw-r--r--drivers/net/irda/nsc-ircc.c17
-rw-r--r--drivers/net/irda/pxaficp_ir.c4
-rw-r--r--drivers/net/irda/sa1100_ir.c28
-rw-r--r--drivers/net/irda/sir_dev.c12
-rw-r--r--drivers/net/irda/stir4200.c1
-rw-r--r--drivers/net/irda/via-ircc.c16
-rw-r--r--drivers/net/irda/vlsi_ir.c37
-rw-r--r--drivers/net/irda/w83977af_ir.c15
-rw-r--r--drivers/net/isa-skeleton.c4
-rw-r--r--drivers/net/iseries_veth.c14
-rw-r--r--drivers/net/ixgb/ixgb_main.c35
-rw-r--r--drivers/net/ixgbe/ixgbe.h1
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c12
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c33
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c84
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.c68
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.h7
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h6
-rw-r--r--drivers/net/ixp2000/ixpdev.c2
-rw-r--r--drivers/net/jazzsonic.c4
-rw-r--r--drivers/net/jme.c13
-rw-r--r--drivers/net/korina.c1
-rw-r--r--drivers/net/lance.c30
-rw-r--r--drivers/net/lib82596.c14
-rw-r--r--drivers/net/lib8390.c1
-rw-r--r--drivers/net/lne390.c5
-rw-r--r--drivers/net/loopback.c27
-rw-r--r--drivers/net/lp486e.c29
-rw-r--r--drivers/net/mac89x0.c5
-rw-r--r--drivers/net/macb.c8
-rw-r--r--drivers/net/mace.c34
-rw-r--r--drivers/net/macmace.c6
-rw-r--r--drivers/net/macsonic.c9
-rw-r--r--drivers/net/macvlan.c45
-rw-r--r--drivers/net/meth.c4
-rw-r--r--drivers/net/mlx4/en_rx.c2
-rw-r--r--drivers/net/mlx4/mcg.c23
-rw-r--r--drivers/net/mlx4/mlx4_en.h8
-rw-r--r--drivers/net/mv643xx_eth.c525
-rw-r--r--drivers/net/mvme147.c9
-rw-r--r--drivers/net/myri10ge/myri10ge.c34
-rw-r--r--drivers/net/myri_sbus.c25
-rw-r--r--drivers/net/natsemi.c6
-rw-r--r--drivers/net/ne-h8300.c3
-rw-r--r--drivers/net/ne.c3
-rw-r--r--drivers/net/ne2.c6
-rw-r--r--drivers/net/ne2k-pci.c7
-rw-r--r--drivers/net/ne3210.c5
-rw-r--r--drivers/net/netconsole.c9
-rw-r--r--drivers/net/netx-eth.c1
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c2
-rw-r--r--drivers/net/netxen/netxen_nic_init.c2
-rw-r--r--drivers/net/netxen/netxen_nic_main.c12
-rw-r--r--drivers/net/netxen/netxen_nic_niu.c7
-rw-r--r--drivers/net/ni5010.c6
-rw-r--r--drivers/net/ni52.c37
-rw-r--r--drivers/net/ni65.c33
-rw-r--r--drivers/net/niu.c27
-rw-r--r--drivers/net/ns83820.c6
-rw-r--r--drivers/net/pasemi_mac.c8
-rw-r--r--drivers/net/pasemi_mac_ethtool.c4
-rw-r--r--drivers/net/pci-skeleton.c6
-rw-r--r--drivers/net/pcmcia/3c574_cs.c6
-rw-r--r--drivers/net/pcmcia/3c589_cs.c6
-rw-r--r--drivers/net/pcmcia/axnet_cs.c6
-rw-r--r--drivers/net/pcmcia/com20020_cs.c6
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c79
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c6
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c3
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c5
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c6
-rw-r--r--drivers/net/pcnet32.c4
-rw-r--r--drivers/net/phy/Kconfig7
-rw-r--r--drivers/net/phy/Makefile2
-rw-r--r--drivers/net/phy/broadcom.c195
-rw-r--r--drivers/net/phy/mdio-gpio.c296
-rw-r--r--drivers/net/phy/mdio-ofgpio.c204
-rw-r--r--drivers/net/phy/mdio_bus.c4
-rw-r--r--drivers/net/phy/phy.c2
-rw-r--r--drivers/net/phy/phy_device.c4
-rw-r--r--drivers/net/phy/smsc.c28
-rw-r--r--drivers/net/plip.c9
-rw-r--r--drivers/net/ppp_generic.c22
-rw-r--r--drivers/net/pppoe.c5
-rw-r--r--drivers/net/ps3_gelic_net.c6
-rw-r--r--drivers/net/ps3_gelic_wireless.c37
-rw-r--r--drivers/net/ps3_gelic_wireless.h4
-rw-r--r--drivers/net/qla3xxx.c11
-rw-r--r--drivers/net/qlge/qlge_main.c12
-rw-r--r--drivers/net/r6040.c1
-rw-r--r--drivers/net/r8169.c49
-rw-r--r--drivers/net/rionet.c31
-rw-r--r--drivers/net/rrunner.c4
-rw-r--r--drivers/net/s2io.c89
-rw-r--r--drivers/net/sb1000.c1
-rw-r--r--drivers/net/sb1250-mac.c5
-rw-r--r--drivers/net/sc92031.c1
-rw-r--r--drivers/net/seeq8005.c4
-rw-r--r--drivers/net/sfc/Kconfig8
-rw-r--r--drivers/net/sfc/Makefile1
-rw-r--r--drivers/net/sfc/boards.c136
-rw-r--r--drivers/net/sfc/efx.c47
-rw-r--r--drivers/net/sfc/efx.h10
-rw-r--r--drivers/net/sfc/enum.h4
-rw-r--r--drivers/net/sfc/ethtool.c17
-rw-r--r--drivers/net/sfc/falcon.c23
-rw-r--r--drivers/net/sfc/falcon_hwdefs.h1
-rw-r--r--drivers/net/sfc/mdio_10g.c35
-rw-r--r--drivers/net/sfc/mdio_10g.h7
-rw-r--r--drivers/net/sfc/mtd.c268
-rw-r--r--drivers/net/sfc/net_driver.h8
-rw-r--r--drivers/net/sfc/rx.c2
-rw-r--r--drivers/net/sfc/sfe4001.c116
-rw-r--r--drivers/net/sfc/spi.h34
-rw-r--r--drivers/net/sfc/tenxpress.c18
-rw-r--r--drivers/net/sfc/workarounds.h2
-rw-r--r--drivers/net/sfc/xfp_phy.c9
-rw-r--r--drivers/net/sgiseeq.c7
-rw-r--r--drivers/net/sh_eth.c3
-rw-r--r--drivers/net/sis190.c7
-rw-r--r--drivers/net/sis900.c70
-rw-r--r--drivers/net/skfp/skfddi.c2
-rw-r--r--drivers/net/skge.c95
-rw-r--r--drivers/net/sky2.c53
-rw-r--r--drivers/net/slip.c1
-rw-r--r--drivers/net/smc-mca.c5
-rw-r--r--drivers/net/smc-ultra.c5
-rw-r--r--drivers/net/smc-ultra32.c5
-rw-r--r--drivers/net/smc911x.c2
-rw-r--r--drivers/net/smc9194.c11
-rw-r--r--drivers/net/smc91x.c8
-rw-r--r--drivers/net/smc91x.h45
-rw-r--r--drivers/net/smsc911x.c2091
-rw-r--r--drivers/net/smsc911x.h394
-rw-r--r--drivers/net/sonic.c1
-rw-r--r--drivers/net/sonic.h20
-rw-r--r--drivers/net/spider_net_ethtool.c8
-rw-r--r--drivers/net/starfire.c14
-rw-r--r--drivers/net/sun3_82586.c38
-rw-r--r--drivers/net/sun3lance.c10
-rw-r--r--drivers/net/sunbmac.c20
-rw-r--r--drivers/net/sundance.c6
-rw-r--r--drivers/net/sungem.c59
-rw-r--r--drivers/net/sunhme.c31
-rw-r--r--drivers/net/sunlance.c7
-rw-r--r--drivers/net/sunqe.c15
-rw-r--r--drivers/net/sunvnet.c5
-rw-r--r--drivers/net/tc35815.c23
-rw-r--r--drivers/net/tehuti.c39
-rw-r--r--drivers/net/tg3.c403
-rw-r--r--drivers/net/tg3.h111
-rw-r--r--drivers/net/tlan.c2
-rw-r--r--drivers/net/tokenring/3c359.c2
-rw-r--r--drivers/net/tokenring/abyss.c4
-rw-r--r--drivers/net/tokenring/ibmtr.c11
-rw-r--r--drivers/net/tokenring/lanstreamer.c36
-rw-r--r--drivers/net/tokenring/madgemc.c10
-rw-r--r--drivers/net/tokenring/olympic.c52
-rw-r--r--drivers/net/tokenring/proteon.c5
-rw-r--r--drivers/net/tokenring/skisa.c5
-rw-r--r--drivers/net/tokenring/smctr.c2
-rw-r--r--drivers/net/tokenring/tms380tr.c15
-rw-r--r--drivers/net/tokenring/tmspci.c5
-rw-r--r--drivers/net/tsi108_eth.c6
-rw-r--r--drivers/net/tulip/de2104x.c50
-rw-r--r--drivers/net/tulip/de4x5.c17
-rw-r--r--drivers/net/tulip/dmfe.c7
-rw-r--r--drivers/net/tulip/eeprom.c2
-rw-r--r--drivers/net/tulip/interrupt.c2
-rw-r--r--drivers/net/tulip/tulip_core.c11
-rw-r--r--drivers/net/tulip/uli526x.c8
-rw-r--r--drivers/net/tulip/winbond-840.c16
-rw-r--r--drivers/net/tulip/xircom_cb.c4
-rw-r--r--drivers/net/tun.c31
-rw-r--r--drivers/net/typhoon.c8
-rw-r--r--drivers/net/ucc_geth.c6
-rw-r--r--drivers/net/usb/catc.c2
-rw-r--r--drivers/net/usb/mcs7830.c4
-rw-r--r--drivers/net/usb/pegasus.c41
-rw-r--r--drivers/net/usb/smsc95xx.c79
-rw-r--r--drivers/net/usb/usbnet.c5
-rw-r--r--drivers/net/veth.c28
-rw-r--r--drivers/net/via-rhine.c6
-rw-r--r--drivers/net/via-velocity.c26
-rw-r--r--drivers/net/virtio_net.c193
-rw-r--r--drivers/net/wan/cosa.c1
-rw-r--r--drivers/net/wan/cycx_x25.c91
-rw-r--r--drivers/net/wan/dlci.c37
-rw-r--r--drivers/net/wan/dscc4.c4
-rw-r--r--drivers/net/wan/farsync.c2
-rw-r--r--drivers/net/wan/hd6457x.c1
-rw-r--r--drivers/net/wan/hostess_sv11.c1
-rw-r--r--drivers/net/wan/lapbether.c3
-rw-r--r--drivers/net/wan/lmc/lmc_main.c1
-rw-r--r--drivers/net/wan/lmc/lmc_proto.c1
-rw-r--r--drivers/net/wan/pc300too.c2
-rw-r--r--drivers/net/wan/pci200syn.c2
-rw-r--r--drivers/net/wan/sbni.c2
-rw-r--r--drivers/net/wan/sdla.c48
-rw-r--r--drivers/net/wan/sealevel.c1
-rw-r--r--drivers/net/wan/syncppp.c4
-rw-r--r--drivers/net/wan/wanxl.c1
-rw-r--r--drivers/net/wan/x25_asy.c32
-rw-r--r--drivers/net/wd.c5
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile9
-rw-r--r--drivers/net/wireless/adm8211.c52
-rw-r--r--drivers/net/wireless/adm8211.h2
-rw-r--r--drivers/net/wireless/airo.c241
-rw-r--r--drivers/net/wireless/arlan-main.c27
-rw-r--r--drivers/net/wireless/ath5k/ath5k.h89
-rw-r--r--drivers/net/wireless/ath5k/base.c131
-rw-r--r--drivers/net/wireless/ath5k/dma.c190
-rw-r--r--drivers/net/wireless/ath5k/initvals.c8
-rw-r--r--drivers/net/wireless/ath5k/pcu.c184
-rw-r--r--drivers/net/wireless/ath5k/phy.c5
-rw-r--r--drivers/net/wireless/ath5k/qcu.c37
-rw-r--r--drivers/net/wireless/ath5k/reg.h15
-rw-r--r--drivers/net/wireless/ath5k/reset.c3
-rw-r--r--drivers/net/wireless/ath9k/Makefile4
-rw-r--r--drivers/net/wireless/ath9k/ani.c854
-rw-r--r--drivers/net/wireless/ath9k/ath9k.h389
-rw-r--r--drivers/net/wireless/ath9k/beacon.c42
-rw-r--r--drivers/net/wireless/ath9k/calib.c930
-rw-r--r--drivers/net/wireless/ath9k/core.c486
-rw-r--r--drivers/net/wireless/ath9k/core.h165
-rw-r--r--drivers/net/wireless/ath9k/eeprom.c1605
-rw-r--r--drivers/net/wireless/ath9k/hw.c8496
-rw-r--r--drivers/net/wireless/ath9k/hw.h2
-rw-r--r--drivers/net/wireless/ath9k/mac.c1031
-rw-r--r--drivers/net/wireless/ath9k/main.c549
-rw-r--r--drivers/net/wireless/ath9k/phy.c10
-rw-r--r--drivers/net/wireless/ath9k/rc.c145
-rw-r--r--drivers/net/wireless/ath9k/rc.h1
-rw-r--r--drivers/net/wireless/ath9k/recv.c537
-rw-r--r--drivers/net/wireless/ath9k/xmit.c1037
-rw-r--r--drivers/net/wireless/atmel.c77
-rw-r--r--drivers/net/wireless/b43/b43.h1
-rw-r--r--drivers/net/wireless/b43/dma.c4
-rw-r--r--drivers/net/wireless/b43/main.c227
-rw-r--r--drivers/net/wireless/b43/pio.c3
-rw-r--r--drivers/net/wireless/b43/xmit.c60
-rw-r--r--drivers/net/wireless/b43/xmit.h5
-rw-r--r--drivers/net/wireless/b43legacy/dma.c48
-rw-r--r--drivers/net/wireless/b43legacy/main.c100
-rw-r--r--drivers/net/wireless/b43legacy/pio.c31
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c26
-rw-r--r--drivers/net/wireless/b43legacy/xmit.h2
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c62
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_tx.c15
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c241
-rw-r--r--drivers/net/wireless/hostap/hostap_common.h13
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c10
-rw-r--r--drivers/net/wireless/hostap/hostap_info.c16
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c16
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c26
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_proc.c15
-rw-r--r--drivers/net/wireless/hostap/hostap_wlan.h2
-rw-r--r--drivers/net/wireless/ipw2100.c53
-rw-r--r--drivers/net/wireless/ipw2200.c415
-rw-r--r--drivers/net/wireless/ipw2200.h1
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-commands.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-io.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c76
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c74
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h148
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c140
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h39
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c284
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c104
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c603
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h197
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c186
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h66
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h60
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h107
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c129
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c100
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c359
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c216
-rw-r--r--drivers/net/wireless/libertas/assoc.c69
-rw-r--r--drivers/net/wireless/libertas/cmd.c14
-rw-r--r--drivers/net/wireless/libertas/debugfs.c11
-rw-r--r--drivers/net/wireless/libertas/decl.h4
-rw-r--r--drivers/net/wireless/libertas/defs.h2
-rw-r--r--drivers/net/wireless/libertas/dev.h7
-rw-r--r--drivers/net/wireless/libertas/ethtool.c12
-rw-r--r--drivers/net/wireless/libertas/main.c75
-rw-r--r--drivers/net/wireless/libertas/persistcfg.c18
-rw-r--r--drivers/net/wireless/libertas/scan.c105
-rw-r--r--drivers/net/wireless/libertas/scan.h4
-rw-r--r--drivers/net/wireless/libertas/tx.c2
-rw-r--r--drivers/net/wireless/libertas/types.h5
-rw-r--r--drivers/net/wireless/libertas/wext.c80
-rw-r--r--drivers/net/wireless/libertas_tf/cmd.c5
-rw-r--r--drivers/net/wireless/libertas_tf/main.c8
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c288
-rw-r--r--drivers/net/wireless/netwave_cs.c6
-rw-r--r--drivers/net/wireless/orinoco/Makefile12
-rw-r--r--drivers/net/wireless/orinoco/airport.c (renamed from drivers/net/wireless/airport.c)0
-rw-r--r--drivers/net/wireless/orinoco/hermes.c (renamed from drivers/net/wireless/hermes.c)0
-rw-r--r--drivers/net/wireless/orinoco/hermes.h (renamed from drivers/net/wireless/hermes.h)0
-rw-r--r--drivers/net/wireless/orinoco/hermes_dld.c (renamed from drivers/net/wireless/hermes_dld.c)0
-rw-r--r--drivers/net/wireless/orinoco/hermes_dld.h (renamed from drivers/net/wireless/hermes_dld.h)0
-rw-r--r--drivers/net/wireless/orinoco/hermes_rid.h (renamed from drivers/net/wireless/hermes_rid.h)0
-rw-r--r--drivers/net/wireless/orinoco/orinoco.c (renamed from drivers/net/wireless/orinoco.c)83
-rw-r--r--drivers/net/wireless/orinoco/orinoco.h (renamed from drivers/net/wireless/orinoco.h)5
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c (renamed from drivers/net/wireless/orinoco_cs.c)2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_nortel.c (renamed from drivers/net/wireless/orinoco_nortel.c)0
-rw-r--r--drivers/net/wireless/orinoco/orinoco_pci.c (renamed from drivers/net/wireless/orinoco_pci.c)0
-rw-r--r--drivers/net/wireless/orinoco/orinoco_pci.h (renamed from drivers/net/wireless/orinoco_pci.h)0
-rw-r--r--drivers/net/wireless/orinoco/orinoco_plx.c (renamed from drivers/net/wireless/orinoco_plx.c)0
-rw-r--r--drivers/net/wireless/orinoco/orinoco_tmd.c (renamed from drivers/net/wireless/orinoco_tmd.c)0
-rw-r--r--drivers/net/wireless/orinoco/spectrum_cs.c (renamed from drivers/net/wireless/spectrum_cs.c)2
-rw-r--r--drivers/net/wireless/p54/p54.h52
-rw-r--r--drivers/net/wireless/p54/p54common.c1160
-rw-r--r--drivers/net/wireless/p54/p54common.h316
-rw-r--r--drivers/net/wireless/p54/p54pci.c33
-rw-r--r--drivers/net/wireless/p54/p54usb.c98
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c24
-rw-r--r--drivers/net/wireless/ray_cs.c10
-rw-r--r--drivers/net/wireless/rndis_wlan.c95
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c194
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c234
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c139
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h43
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c176
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c47
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.h13
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c38
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c20
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c24
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h9
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c260
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c245
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h2
-rw-r--r--drivers/net/wireless/rtl8180_dev.c36
-rw-r--r--drivers/net/wireless/rtl8187.h1
-rw-r--r--drivers/net/wireless/rtl8187_dev.c133
-rw-r--r--drivers/net/wireless/rtl8187_rtl8225.c391
-rw-r--r--drivers/net/wireless/strip.c2
-rw-r--r--drivers/net/wireless/wavelan.c122
-rw-r--r--drivers/net/wireless/wavelan_cs.c39
-rw-r--r--drivers/net/wireless/wl3501.h4
-rw-r--r--drivers/net/wireless/wl3501_cs.c11
-rw-r--r--drivers/net/wireless/zd1201.c6
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c4
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c44
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c2
-rw-r--r--drivers/net/xen-netfront.c1
-rw-r--r--drivers/net/xtsonic.c6
-rw-r--r--drivers/net/yellowfin.c14
-rw-r--r--drivers/net/znet.c28
-rw-r--r--drivers/net/zorro8390.c7
516 files changed, 20547 insertions, 19588 deletions
diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c
index 7d15e7c6bca..3d1318a3e68 100644
--- a/drivers/net/3c501.c
+++ b/drivers/net/3c501.c
@@ -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;
}
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
index 900b0ffdcc6..95bd95f1f99 100644
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -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);
diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c
index a424869707a..6124605bef0 100644
--- a/drivers/net/3c505.c
+++ b/drivers/net/3c505.c
@@ -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
diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c
index 030c147211b..b8585ecd1d7 100644
--- a/drivers/net/3c507.c
+++ b/drivers/net/3c507.c
@@ -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;
}
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index c7a4f3bcc2b..535c234286e 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -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;
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c
index a0f8b6e2d0a..7f995008a45 100644
--- a/drivers/net/3c515.c
+++ b/drivers/net/3c515.c
@@ -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;
diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c
index e2ce41d3828..59ea2910bca 100644
--- a/drivers/net/3c523.c
+++ b/drivers/net/3c523.c
@@ -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 */
diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c
index abc84f76597..2df3af3b9b2 100644
--- a/drivers/net/3c527.c
+++ b/drivers/net/3c527.c
@@ -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);
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 9ba295d9dd9..665e7fdf27a 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -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);
diff --git a/drivers/net/7990.c b/drivers/net/7990.c
index ad6b8a5b657..7a331acc34a 100644
--- a/drivers/net/7990.c
+++ b/drivers/net/7990.c
@@ -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;
}
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 9ba1f0b4642..13f75b67872 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -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))) {
@@ -1818,6 +1817,25 @@ static void cp_set_d3_state (struct cp_private *cp)
pci_set_power_state (cp->pdev, PCI_D3hot);
}
+static const struct net_device_ops cp_netdev_ops = {
+ .ndo_open = cp_open,
+ .ndo_stop = cp_close,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = cp_set_rx_mode,
+ .ndo_get_stats = cp_get_stats,
+ .ndo_do_ioctl = cp_ioctl,
+ .ndo_tx_timeout = cp_tx_timeout,
+#if CP_VLAN_TAG_USED
+ .ndo_vlan_rx_register = cp_vlan_rx_register,
+#endif
+#ifdef BROKEN
+ .ndo_change_mtu = cp_change_mtu,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = cp_poll_controller,
+#endif
+};
+
static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct net_device *dev;
@@ -1826,7 +1844,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;
@@ -1931,26 +1948,14 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
cpu_to_le16(read_eeprom (regs, i + 7, addr_len));
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
- dev->open = cp_open;
- dev->stop = cp_close;
- dev->set_multicast_list = cp_set_rx_mode;
+ dev->netdev_ops = &cp_netdev_ops;
dev->hard_start_xmit = cp_start_xmit;
- dev->get_stats = cp_get_stats;
- dev->do_ioctl = cp_ioctl;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = cp_poll_controller;
-#endif
netif_napi_add(dev, &cp->napi, cp_rx_poll, 16);
-#ifdef BROKEN
- dev->change_mtu = cp_change_mtu;
-#endif
dev->ethtool_ops = &cp_ethtool_ops;
- dev->tx_timeout = cp_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
#if CP_VLAN_TAG_USED
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- dev->vlan_rx_register = cp_vlan_rx_register;
#endif
if (pci_using_dac)
@@ -1967,10 +1972,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);
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 63f906b0489..f8866552386 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -916,6 +916,19 @@ err_out:
return rc;
}
+static const struct net_device_ops rtl8139_netdev_ops = {
+ .ndo_open = rtl8139_open,
+ .ndo_stop = rtl8139_close,
+ .ndo_get_stats = rtl8139_get_stats,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = rtl8139_set_rx_mode,
+ .ndo_do_ioctl = netdev_ioctl,
+ .ndo_tx_timeout = rtl8139_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = rtl8139_poll_controller,
+#endif
+
+};
static int __devinit rtl8139_init_one (struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -925,7 +938,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);
@@ -977,19 +989,11 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
/* The Rtl8139-specific entries in the device structure. */
- dev->open = rtl8139_open;
- dev->hard_start_xmit = rtl8139_start_xmit;
- netif_napi_add(dev, &tp->napi, rtl8139_poll, 64);
- dev->stop = rtl8139_close;
- dev->get_stats = rtl8139_get_stats;
- dev->set_multicast_list = rtl8139_set_rx_mode;
- dev->do_ioctl = netdev_ioctl;
+ dev->netdev_ops = &rtl8139_netdev_ops;
dev->ethtool_ops = &rtl8139_ethtool_ops;
- dev->tx_timeout = rtl8139_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = rtl8139_poll_controller;
-#endif
+ dev->hard_start_xmit = rtl8139_start_xmit;
+ netif_napi_add(dev, &tp->napi, rtl8139_poll, 64);
/* note: the hardware is not capable of sg/csum/highdma, however
* through the use of skb_copy_and_csum_dev we enable these
@@ -1024,11 +1028,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 +2030,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++;
diff --git a/drivers/net/82596.c b/drivers/net/82596.c
index da292e647eb..23fe41611be 100644
--- a/drivers/net/82596.c
+++ b/drivers/net/82596.c
@@ -457,7 +457,7 @@ static inline int wait_cfg(struct net_device *dev, struct i596_cmd *cmd, int del
static void i596_display_data(struct net_device *dev)
{
- struct i596_private *lp = dev->priv;
+ struct i596_private *lp = dev->ml_priv;
struct i596_cmd *cmd;
struct i596_rfd *rfd;
struct i596_rbd *rbd;
@@ -527,7 +527,7 @@ static irqreturn_t i596_error(int irq, void *dev_id)
static inline void init_rx_bufs(struct net_device *dev)
{
- struct i596_private *lp = dev->priv;
+ struct i596_private *lp = dev->ml_priv;
int i;
struct i596_rfd *rfd;
struct i596_rbd *rbd;
@@ -578,7 +578,7 @@ static inline void init_rx_bufs(struct net_device *dev)
static inline void remove_rx_bufs(struct net_device *dev)
{
- struct i596_private *lp = dev->priv;
+ struct i596_private *lp = dev->ml_priv;
struct i596_rbd *rbd;
int i;
@@ -592,7 +592,7 @@ static inline void remove_rx_bufs(struct net_device *dev)
static void rebuild_rx_bufs(struct net_device *dev)
{
- struct i596_private *lp = dev->priv;
+ struct i596_private *lp = dev->ml_priv;
int i;
/* Ensure rx frame/buffer descriptors are tidy */
@@ -611,7 +611,7 @@ static void rebuild_rx_bufs(struct net_device *dev)
static int init_i596_mem(struct net_device *dev)
{
- struct i596_private *lp = dev->priv;
+ struct i596_private *lp = dev->ml_priv;
#if !defined(ENABLE_MVME16x_NET) && !defined(ENABLE_BVME6000_NET) || defined(ENABLE_APRICOT)
short ioaddr = dev->base_addr;
#endif
@@ -764,7 +764,7 @@ failed:
static inline int i596_rx(struct net_device *dev)
{
- struct i596_private *lp = dev->priv;
+ struct i596_private *lp = dev->ml_priv;
struct i596_rfd *rfd;
struct i596_rbd *rbd;
int frames = 0;
@@ -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;
}
@@ -959,7 +958,7 @@ static void i596_reset(struct net_device *dev, struct i596_private *lp,
static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd)
{
- struct i596_private *lp = dev->priv;
+ struct i596_private *lp = dev->ml_priv;
int ioaddr = dev->base_addr;
unsigned long flags;
@@ -1029,7 +1028,7 @@ static int i596_open(struct net_device *dev)
static void i596_tx_timeout (struct net_device *dev)
{
- struct i596_private *lp = dev->priv;
+ struct i596_private *lp = dev->ml_priv;
int ioaddr = dev->base_addr;
/* Transmitter timeout, serious problems. */
@@ -1058,7 +1057,7 @@ static void i596_tx_timeout (struct net_device *dev)
static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct i596_private *lp = dev->priv;
+ struct i596_private *lp = dev->ml_priv;
struct tx_cmd *tx_cmd;
struct i596_tbd *tbd;
short length = skb->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;
@@ -1244,9 +1239,9 @@ found:
dev->tx_timeout = i596_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
- dev->priv = (void *)(dev->mem_start);
+ dev->ml_priv = (void *)(dev->mem_start);
- lp = dev->priv;
+ lp = dev->ml_priv;
DEB(DEB_INIT,printk(KERN_DEBUG "%s: lp at 0x%08lx (%zd bytes), "
"lp->scb at 0x%08lx\n",
dev->name, (unsigned long)lp,
@@ -1307,7 +1302,7 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id)
}
ioaddr = dev->base_addr;
- lp = dev->priv;
+ lp = dev->ml_priv;
spin_lock (&lp->lock);
@@ -1450,7 +1445,7 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id)
static int i596_close(struct net_device *dev)
{
- struct i596_private *lp = dev->priv;
+ struct i596_private *lp = dev->ml_priv;
unsigned long flags;
netif_stop_queue(dev);
@@ -1500,7 +1495,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 = dev->ml_priv;
int config = 0, cnt;
DEB(DEB_MULTI,printk(KERN_DEBUG "%s: set multicast list, %d entries, promisc %s, allmulti %s\n",
@@ -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);
}
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 11f143f4adf..afa206590ad 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -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
@@ -1980,10 +1982,10 @@ config IP1000
will be called ipg. This is recommended.
config IGB
- tristate "Intel(R) 82575 PCI-Express Gigabit Ethernet support"
+ tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support"
depends on PCI
---help---
- This driver supports Intel(R) 82575 gigabit ethernet family of
+ This driver supports Intel(R) 82575/82576 gigabit ethernet family of
adapters. For more information on how to identify your adapter, go
to the Adapter & Driver ID Guide at:
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index f19acf8b922..e06829aa75b 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -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
diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c
index 9c0837435b6..7a60bdd9a24 100644
--- a/drivers/net/a2065.c
+++ b/drivers/net/a2065.c
@@ -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;
}
diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c
index b1448637107..071a851a2ea 100644
--- a/drivers/net/ac3200.c
+++ b/drivers/net/ac3200.c
@@ -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
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 66de80b64b9..309a90ea921 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -450,6 +450,17 @@ static const struct ethtool_ops ace_ethtool_ops = {
static void ace_watchdog(struct net_device *dev);
+static const struct net_device_ops ace_netdev_ops = {
+ .ndo_open = ace_open,
+ .ndo_stop = ace_close,
+ .ndo_tx_timeout = ace_watchdog,
+ .ndo_get_stats = ace_get_stats,
+ .ndo_set_multicast_list = ace_set_multicast_list,
+ .ndo_set_mac_address = ace_set_mac_addr,
+ .ndo_change_mtu = ace_change_mtu,
+ .ndo_vlan_rx_register = ace_vlan_rx_register,
+};
+
static int __devinit acenic_probe_one(struct pci_dev *pdev,
const struct pci_device_id *id)
{
@@ -466,27 +477,20 @@ 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);
dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
#if ACENIC_DO_VLAN
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- dev->vlan_rx_register = ace_vlan_rx_register;
#endif
- dev->tx_timeout = &ace_watchdog;
dev->watchdog_timeo = 5*HZ;
- dev->open = &ace_open;
- dev->stop = &ace_close;
+ dev->netdev_ops = &ace_netdev_ops;
dev->hard_start_xmit = &ace_start_xmit;
- dev->get_stats = &ace_get_stats;
- dev->set_multicast_list = &ace_set_multicast_list;
SET_ETHTOOL_OPS(dev, &ace_ethtool_ops);
- dev->set_mac_address = &ace_set_mac_addr;
- dev->change_mtu = &ace_change_mtu;
/* we only display this string ONCE */
if (!boards_found)
@@ -892,7 +896,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 +1022,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 +2037,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;
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 07a6697e363..0bc4f54d5db 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -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);
diff --git a/drivers/net/apne.c b/drivers/net/apne.c
index 867f6fff543..7426f694063 100644
--- a/drivers/net/apne.c
+++ b/drivers/net/apne.c
@@ -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);
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index 735fc947640..0c4e3c5ac49 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -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)
diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c
index 1071144edd6..9a0be9b2eaa 100644
--- a/drivers/net/appletalk/ipddp.c
+++ b/drivers/net/appletalk/ipddp.c
@@ -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);
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
index fef5560bc7a..dc4d4960560 100644
--- a/drivers/net/appletalk/ltpc.c
+++ b/drivers/net/appletalk/ltpc.c
@@ -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;
}
diff --git a/drivers/net/arcnet/arc-rawmode.c b/drivers/net/arcnet/arc-rawmode.c
index e0a18e7c73c..3ff9affb1a9 100644
--- a/drivers/net/arcnet/arc-rawmode.c
+++ b/drivers/net/arcnet/arc-rawmode.c
@@ -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;
diff --git a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c
index 8c8d6c453c4..e3082a9350f 100644
--- a/drivers/net/arcnet/arc-rimi.c
+++ b/drivers/net/arcnet/arc-rimi.c
@@ -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);
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index a5b07691e46..6b53e5ed125 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -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");
diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c
index 02cb8f1c114..e544953d8e9 100644
--- a/drivers/net/arcnet/capmode.c
+++ b/drivers/net/arcnet/capmode.c
@@ -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);
diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c
index 9289e6103de..ea53a940272 100644
--- a/drivers/net/arcnet/com20020-isa.c
+++ b/drivers/net/arcnet/com20020-isa.c
@@ -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;
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
index b8c0fa6d401..8b51f632581 100644
--- a/drivers/net/arcnet/com20020-pci.c
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -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);
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
index 70124a944e7..103688358fb 100644
--- a/drivers/net/arcnet/com20020.c
+++ b/drivers/net/arcnet/com20020.c
@@ -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 */
diff --git a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c
index 6599f1046c7..89de29b3b1d 100644
--- a/drivers/net/arcnet/com90io.c
+++ b/drivers/net/arcnet/com90io.c
@@ -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());
diff --git a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c
index 0d45553ff75..f4113d26587 100644
--- a/drivers/net/arcnet/com90xx.c
+++ b/drivers/net/arcnet/com90xx.c
@@ -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);
diff --git a/drivers/net/arcnet/rfc1051.c b/drivers/net/arcnet/rfc1051.c
index dab185bc51f..49d39a9cb69 100644
--- a/drivers/net/arcnet/rfc1051.c
+++ b/drivers/net/arcnet/rfc1051.c
@@ -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;
diff --git a/drivers/net/arcnet/rfc1201.c b/drivers/net/arcnet/rfc1201.c
index 6d6d95cc440..2303d3a1f4b 100644
--- a/drivers/net/arcnet/rfc1201.c
+++ b/drivers/net/arcnet/rfc1201.c
@@ -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;
diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c
index 29e53eb71c7..e1d72e06f3e 100644
--- a/drivers/net/ariadne.c
+++ b/drivers/net/ariadne.c
@@ -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;
}
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index aa4a5246be5..0c628a9e533 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -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;
}
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
index 6f431a887e7..442938d5038 100644
--- a/drivers/net/arm/at91_ether.c
+++ b/drivers/net/arm/at91_ether.c
@@ -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)
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index 1267444d79d..588c9739d13 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -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++;
diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c
index 3bb9e293e2e..e380de45446 100644
--- a/drivers/net/arm/ether1.c
+++ b/drivers/net/arm/ether1.c
@@ -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;
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c
index 67e96ae8503..21a7bef12d3 100644
--- a/drivers/net/arm/ether3.c
+++ b/drivers/net/arm/ether3.c
@@ -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;
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
index 5c5f1e470d3..9eb9d1bedc8 100644
--- a/drivers/net/arm/etherh.c
+++ b/drivers/net/arm/etherh.c
@@ -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);
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c
index e2d702b8b2e..14ffa2a6189 100644
--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -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);
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c
index 7e874d485d2..2d4b5c31652 100644
--- a/drivers/net/at1700.c
+++ b/drivers/net/at1700.c
@@ -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;
}
diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c
index 0860cc280b0..2d81f6afcb5 100644
--- a/drivers/net/atarilance.c
+++ b/drivers/net/atarilance.c
@@ -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;
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index 9b603528143..a815fffc2a5 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -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 +=
@@ -2254,26 +2253,32 @@ static void atl1e_shutdown(struct pci_dev *pdev)
atl1e_suspend(pdev, PMSG_SUSPEND);
}
+static const struct net_device_ops atl1e_netdev_ops = {
+ .ndo_open = atl1e_open,
+ .ndo_stop = atl1e_close,
+ .ndo_get_stats = atl1e_get_stats,
+ .ndo_set_multicast_list = atl1e_set_multi,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = atl1e_set_mac_addr,
+ .ndo_change_mtu = atl1e_change_mtu,
+ .ndo_do_ioctl = atl1e_ioctl,
+ .ndo_tx_timeout = atl1e_tx_timeout,
+ .ndo_vlan_rx_register = atl1e_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = atl1e_netpoll,
+#endif
+
+};
+
static int atl1e_init_netdev(struct net_device *netdev, struct pci_dev *pdev)
{
SET_NETDEV_DEV(netdev, &pdev->dev);
pci_set_drvdata(pdev, netdev);
netdev->irq = pdev->irq;
- netdev->open = &atl1e_open;
- netdev->stop = &atl1e_close;
- netdev->hard_start_xmit = &atl1e_xmit_frame;
- netdev->get_stats = &atl1e_get_stats;
- netdev->set_multicast_list = &atl1e_set_multi;
- netdev->set_mac_address = &atl1e_set_mac_addr;
- netdev->change_mtu = &atl1e_change_mtu;
- netdev->do_ioctl = &atl1e_ioctl;
- netdev->tx_timeout = &atl1e_tx_timeout;
+ netdev->netdev_ops = &atl1e_netdev_ops;
+ netdev->hard_start_xmit = atl1e_xmit_frame,
netdev->watchdog_timeo = AT_TX_WATCHDOG;
- netdev->vlan_rx_register = atl1e_vlan_rx_register;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = atl1e_netpoll;
-#endif
atl1e_set_ethtool_ops(netdev);
netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
@@ -2488,7 +2493,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 +2516,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 +2544,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)) {
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index aef403d299e..7a0fb04e348 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -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;
@@ -2893,6 +2880,21 @@ static void atl1_poll_controller(struct net_device *netdev)
}
#endif
+static const struct net_device_ops atl1_netdev_ops = {
+ .ndo_open = atl1_open,
+ .ndo_stop = atl1_close,
+ .ndo_set_multicast_list = atlx_set_multi,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = atl1_set_mac,
+ .ndo_change_mtu = atl1_change_mtu,
+ .ndo_do_ioctl = atlx_ioctl,
+ .ndo_tx_timeout = atlx_tx_timeout,
+ .ndo_vlan_rx_register = atlx_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = atl1_poll_controller,
+#endif
+};
+
/*
* atl1_probe - Device Initialization Routine
* @pdev: PCI device information struct
@@ -2980,20 +2982,9 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
adapter->mii.phy_id_mask = 0x1f;
adapter->mii.reg_num_mask = 0x1f;
- netdev->open = &atl1_open;
- netdev->stop = &atl1_close;
+ netdev->netdev_ops = &atl1_netdev_ops;
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;
- netdev->do_ioctl = &atlx_ioctl;
- netdev->tx_timeout = &atlx_tx_timeout;
netdev->watchdog_timeo = 5 * HZ;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = atl1_poll_controller;
-#endif
- netdev->vlan_rx_register = atlx_vlan_rx_register;
netdev->ethtool_ops = &atl1_ethtool_ops;
adapter->bd_number = cards_found;
@@ -3049,13 +3040,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 +3159,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)},
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
index ffa73fc8d95..146372fd668 100644
--- a/drivers/net/atlx/atl1.h
+++ b/drivers/net/atlx/atl1.h
@@ -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;
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
index 8571e8c0bc6..b8d585722e1 100644
--- a/drivers/net/atlx/atl2.c
+++ b/drivers/net/atlx/atl2.c
@@ -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,
@@ -900,19 +900,6 @@ static int atl2_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
/*
- * 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
* @new_mtu: new value for maximum frame size
@@ -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;
@@ -1320,6 +1311,22 @@ static void atl2_poll_controller(struct net_device *netdev)
}
#endif
+
+static const struct net_device_ops atl2_netdev_ops = {
+ .ndo_open = atl2_open,
+ .ndo_stop = atl2_close,
+ .ndo_set_multicast_list = atl2_set_multi,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = atl2_set_mac,
+ .ndo_change_mtu = atl2_change_mtu,
+ .ndo_do_ioctl = atl2_ioctl,
+ .ndo_tx_timeout = atl2_tx_timeout,
+ .ndo_vlan_rx_register = atl2_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = atl2_poll_controller,
+#endif
+};
+
/*
* atl2_probe - Device Initialization Routine
* @pdev: PCI device information struct
@@ -1393,26 +1400,10 @@ static int __devinit atl2_probe(struct pci_dev *pdev,
atl2_setup_pcicmd(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;
- netdev->do_ioctl = &atl2_ioctl;
+ netdev->netdev_ops = &atl2_netdev_ops;
atl2_set_ethtool_ops(netdev);
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = atl2_poll_controller;
-#endif
-#ifdef HAVE_TX_TIMEOUT
- netdev->tx_timeout = &atl2_tx_timeout;
netdev->watchdog_timeo = 5 * HZ;
-#endif
-#ifdef NETIF_F_HW_VLAN_TX
- netdev->vlan_rx_register = atl2_vlan_rx_register;
-#endif
strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
netdev->mem_start = mmio_start;
diff --git a/drivers/net/atlx/atl2.h b/drivers/net/atlx/atl2.h
index 09974df76b1..d918bbe621e 100644
--- a/drivers/net/atlx/atl2.h
+++ b/drivers/net/atlx/atl2.h
@@ -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
diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c
index 3cc9d1089ca..3dc01421567 100644
--- a/drivers/net/atlx/atlx.c
+++ b/drivers/net/atlx/atlx.c
@@ -182,19 +182,6 @@ static void atlx_clear_phy_int(struct atlx_adapter *adapter)
}
/*
- * 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
*/
diff --git a/drivers/net/atp.c b/drivers/net/atp.c
index c10cd8058e2..7028b276dfd 100644
--- a/drivers/net/atp.c
+++ b/drivers/net/atp.c
@@ -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);
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 019b13c08ae..ecc2573b3dc 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -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;
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index 9a314d88e7b..337488ec707 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -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)
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index c3bda5ce67c..2c7a32eb92a 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -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;
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index b458d607a9c..78e31aa861e 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -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;
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index a42bd19646d..8a546a33d58 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -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");
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index d07e3f14895..fe802215214 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -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;
}
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 617d9534016..34ca47812af 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -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
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 600210d7eff..49f8e789162 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -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:
diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index 5cdae2bc055..6f9c6faef24 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -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)
+
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 6106660a4a4..78f645d6471 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -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;
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index b5ee45f6d55..a803fe05f63 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -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);
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 87437c78847..f0dde1888c7 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -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 */
@@ -1211,11 +1218,6 @@ static int alb_set_mac_address(struct bonding *bond, void *addr)
}
bond_for_each_slave(bond, slave, i) {
- if (slave->dev->set_mac_address == NULL) {
- res = -EOPNOTSUPP;
- goto unwind;
- }
-
/* save net_device's current hw address */
memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
@@ -1224,9 +1226,8 @@ static int alb_set_mac_address(struct bonding *bond, void *addr)
/* restore net_device's hw address */
memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
- if (res) {
+ if (res)
goto unwind;
- }
}
return 0;
@@ -1285,7 +1286,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 +1707,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
index 00000000000..7c78b7bf671
--- /dev/null
+++ b/drivers/net/bonding/bond_ipv6.c
@@ -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);
+}
+
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index a3efba59eee..614656c8187 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -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;
@@ -450,10 +462,11 @@ static void bond_vlan_rx_register(struct net_device *bond_dev, struct vlan_group
bond_for_each_slave(bond, slave, i) {
struct net_device *slave_dev = slave->dev;
+ const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
- slave_dev->vlan_rx_register) {
- slave_dev->vlan_rx_register(slave_dev, grp);
+ slave_ops->ndo_vlan_rx_register) {
+ slave_ops->ndo_vlan_rx_register(slave_dev, grp);
}
}
}
@@ -465,16 +478,17 @@ 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;
bond_for_each_slave(bond, slave, i) {
struct net_device *slave_dev = slave->dev;
+ const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
if ((slave_dev->features & NETIF_F_HW_VLAN_FILTER) &&
- slave_dev->vlan_rx_add_vid) {
- slave_dev->vlan_rx_add_vid(slave_dev, vid);
+ slave_ops->ndo_vlan_rx_add_vid) {
+ slave_ops->ndo_vlan_rx_add_vid(slave_dev, vid);
}
}
@@ -493,21 +507,22 @@ 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;
bond_for_each_slave(bond, slave, i) {
struct net_device *slave_dev = slave->dev;
+ const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
if ((slave_dev->features & NETIF_F_HW_VLAN_FILTER) &&
- slave_dev->vlan_rx_kill_vid) {
+ slave_ops->ndo_vlan_rx_kill_vid) {
/* Save and then restore vlan_dev in the grp array,
* since the slave's driver might clear it.
*/
vlan_dev = vlan_group_get_device(bond->vlgrp, vid);
- slave_dev->vlan_rx_kill_vid(slave_dev, vid);
+ slave_ops->ndo_vlan_rx_kill_vid(slave_dev, vid);
vlan_group_set_device(bond->vlgrp, vid, vlan_dev);
}
}
@@ -523,26 +538,23 @@ static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid)
static void bond_add_vlans_on_slave(struct bonding *bond, struct net_device *slave_dev)
{
struct vlan_entry *vlan;
+ const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
write_lock_bh(&bond->lock);
- if (list_empty(&bond->vlan_list)) {
+ if (list_empty(&bond->vlan_list))
goto out;
- }
if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
- slave_dev->vlan_rx_register) {
- slave_dev->vlan_rx_register(slave_dev, bond->vlgrp);
- }
+ slave_ops->ndo_vlan_rx_register)
+ slave_ops->ndo_vlan_rx_register(slave_dev, bond->vlgrp);
if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) ||
- !(slave_dev->vlan_rx_add_vid)) {
+ !(slave_ops->ndo_vlan_rx_add_vid))
goto out;
- }
- list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
- slave_dev->vlan_rx_add_vid(slave_dev, vlan->vlan_id);
- }
+ list_for_each_entry(vlan, &bond->vlan_list, vlan_list)
+ slave_ops->ndo_vlan_rx_add_vid(slave_dev, vlan->vlan_id);
out:
write_unlock_bh(&bond->lock);
@@ -550,34 +562,32 @@ out:
static void bond_del_vlans_from_slave(struct bonding *bond, struct net_device *slave_dev)
{
+ const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
struct vlan_entry *vlan;
struct net_device *vlan_dev;
write_lock_bh(&bond->lock);
- if (list_empty(&bond->vlan_list)) {
+ if (list_empty(&bond->vlan_list))
goto out;
- }
if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) ||
- !(slave_dev->vlan_rx_kill_vid)) {
+ !(slave_ops->ndo_vlan_rx_kill_vid))
goto unreg;
- }
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
/* Save and then restore vlan_dev in the grp array,
* since the slave's driver might clear it.
*/
vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
- slave_dev->vlan_rx_kill_vid(slave_dev, vlan->vlan_id);
+ slave_ops->ndo_vlan_rx_kill_vid(slave_dev, vlan->vlan_id);
vlan_group_set_device(bond->vlgrp, vlan->vlan_id, vlan_dev);
}
unreg:
if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
- slave_dev->vlan_rx_register) {
- slave_dev->vlan_rx_register(slave_dev, NULL);
- }
+ slave_ops->ndo_vlan_rx_register)
+ slave_ops->ndo_vlan_rx_register(slave_dev, NULL);
out:
write_unlock_bh(&bond->lock);
@@ -686,15 +696,15 @@ static int bond_update_speed_duplex(struct slave *slave)
*/
static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_dev, int reporting)
{
+ const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
static int (* ioctl)(struct net_device *, struct ifreq *, int);
struct ifreq ifr;
struct mii_ioctl_data *mii;
- if (bond->params.use_carrier) {
+ if (bond->params.use_carrier)
return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
- }
- ioctl = slave_dev->do_ioctl;
+ ioctl = slave_ops->ndo_do_ioctl;
if (ioctl) {
/* TODO: set pointer to correct ioctl on a per team member */
/* bases to make this more efficient. that is, once */
@@ -927,7 +937,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 +1218,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 +1381,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 +1398,8 @@ 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);
+ const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
struct slave *new_slave = NULL;
struct dev_mc_list *dmi;
struct sockaddr addr;
@@ -1394,7 +1408,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
int res = 0;
if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&
- slave_dev->do_ioctl == NULL) {
+ slave_ops->ndo_do_ioctl == NULL) {
printk(KERN_WARNING DRV_NAME
": %s: Warning: no link monitoring support for %s\n",
bond_dev->name, slave_dev->name);
@@ -1476,7 +1490,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
goto err_undo_flags;
}
- if (slave_dev->set_mac_address == NULL) {
+ if (slave_ops->ndo_set_mac_address == NULL) {
if (bond->slave_cnt == 0) {
printk(KERN_WARNING DRV_NAME
": %s: Warning: The first slave device "
@@ -1787,11 +1801,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 +1833,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 +2012,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 +2029,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 +2160,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 +2209,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 +2223,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 +2477,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 +2605,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 +2642,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 +2692,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 +2716,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 +2745,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 +3178,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 +3262,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 +3315,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 +3323,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 +3344,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 +3353,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 +3360,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 +3525,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 +3543,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 +3794,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 +3835,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 +3843,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 +3856,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,8 +3897,8 @@ 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 net_device_stats *stats = &(bond->stats), *sstats;
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct net_device_stats *stats = &bond->stats;
struct net_device_stats local_stats;
struct slave *slave;
int i;
@@ -3887,7 +3908,8 @@ static struct net_device_stats *bond_get_stats(struct net_device *bond_dev)
read_lock_bh(&bond->lock);
bond_for_each_slave(bond, slave, i) {
- sstats = slave->dev->get_stats(slave->dev);
+ const struct net_device_stats *sstats = dev_get_stats(slave->dev);
+
local_stats.rx_packets += sstats->rx_packets;
local_stats.rx_bytes += sstats->rx_bytes;
local_stats.rx_errors += sstats->rx_errors;
@@ -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,12 +4201,16 @@ 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;
int i;
+ if (bond->params.mode == BOND_MODE_ALB)
+ return bond_alb_set_mac_address(bond_dev, addr);
+
+
dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None"));
/*
@@ -4214,9 +4240,10 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
*/
bond_for_each_slave(bond, slave, i) {
+ const struct net_device_ops *slave_ops = slave->dev->netdev_ops;
dprintk("slave %p %s\n", slave, slave->dev->name);
- if (slave->dev->set_mac_address == NULL) {
+ if (slave_ops->ndo_set_mac_address == NULL) {
res = -EOPNOTSUPP;
dprintk("EOPNOTSUPP %s\n", slave->dev->name);
goto unwind;
@@ -4260,7 +4287,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 +4336,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 +4368,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 +4414,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;
@@ -4494,7 +4521,6 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
/* FALLTHRU */
case BOND_MODE_TLB:
bond_dev->hard_start_xmit = bond_alb_xmit;
- bond_dev->set_mac_address = bond_alb_set_mac_address;
break;
default:
/* Should never happen, mode already checked */
@@ -4524,13 +4550,27 @@ static const struct ethtool_ops bond_ethtool_ops = {
.get_flags = ethtool_op_get_flags,
};
+static const struct net_device_ops bond_netdev_ops = {
+ .ndo_open = bond_open,
+ .ndo_stop = bond_close,
+ .ndo_get_stats = bond_get_stats,
+ .ndo_do_ioctl = bond_do_ioctl,
+ .ndo_set_multicast_list = bond_set_multicast_list,
+ .ndo_change_mtu = bond_change_mtu,
+ .ndo_validate_addr = NULL,
+ .ndo_set_mac_address = bond_set_mac_address,
+ .ndo_vlan_rx_register = bond_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid,
+};
+
/*
* Does not allocate but creates a /proc entry.
* Allowed to fail.
*/
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,20 +4591,13 @@ 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);
/* Initialize the device entry points */
- bond_dev->open = bond_open;
- bond_dev->stop = bond_close;
- bond_dev->get_stats = bond_get_stats;
- bond_dev->do_ioctl = bond_do_ioctl;
+ bond_dev->netdev_ops = &bond_netdev_ops;
bond_dev->ethtool_ops = &bond_ethtool_ops;
- bond_dev->set_multicast_list = bond_set_multicast_list;
- bond_dev->change_mtu = bond_change_mtu;
- bond_dev->set_mac_address = bond_set_mac_address;
- bond_dev->validate_addr = NULL;
-
bond_set_mode_ops(bond, bond->params.mode);
bond_dev->destructor = bond_destructor;
@@ -4573,6 +4606,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
@@ -4591,9 +4626,6 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
* when there are slaves that are not hw accel
* capable
*/
- bond_dev->vlan_rx_register = bond_vlan_rx_register;
- bond_dev->vlan_rx_add_vid = bond_vlan_rx_add_vid;
- bond_dev->vlan_rx_kill_vid = bond_vlan_rx_kill_vid;
bond_dev->features |= (NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER);
@@ -4632,7 +4664,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 +4783,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 +4847,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 +5055,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 +5156,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 +5208,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 +5231,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();
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 3bdb4738252..f6475ce347d 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -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[];
@@ -316,18 +317,12 @@ static ssize_t bonding_store_slaves(struct device *d,
/* Set the slave's MTU to match the bond */
original_mtu = dev->mtu;
- if (dev->mtu != bond->dev->mtu) {
- if (dev->change_mtu) {
- res = dev->change_mtu(dev,
- bond->dev->mtu);
- if (res) {
- ret = res;
- goto out;
- }
- } else {
- dev->mtu = bond->dev->mtu;
- }
+ res = dev_set_mtu(dev, bond->dev->mtu);
+ if (res) {
+ ret = res;
+ goto out;
}
+
res = bond_enslave(bond->dev, dev);
bond_for_each_slave(bond, slave, i)
if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0)
@@ -356,11 +351,7 @@ static ssize_t bonding_store_slaves(struct device *d,
goto out;
}
/* set the slave MTU to the default */
- if (dev->change_mtu) {
- dev->change_mtu(dev, original_mtu);
- } else {
- dev->mtu = original_mtu;
- }
+ dev_set_mtu(dev, original_mtu);
}
else {
printk(KERN_ERR DRV_NAME ": unable to remove non-existent slave %s for bond %s.\n",
@@ -620,6 +611,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 +665,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 +688,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 +697,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 +706,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 +724,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 +733,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 +935,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 +1021,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 +1120,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 +1473,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 +1497,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,
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index ffb668dd6d3..921abacc607 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -19,16 +19,19 @@
#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 */
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 86909cfb14d..bc84c4ca898 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -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;
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index 638c9a27a7a..482741797eb 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -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);
@@ -1010,6 +1010,23 @@ void t1_fatal_err(struct adapter *adapter)
adapter->name);
}
+static const struct net_device_ops cxgb_netdev_ops = {
+ .ndo_open = cxgb_open,
+ .ndo_stop = cxgb_close,
+ .ndo_get_stats = t1_get_stats,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = t1_set_rxmode,
+ .ndo_do_ioctl = t1_ioctl,
+ .ndo_change_mtu = t1_change_mtu,
+ .ndo_set_mac_address = t1_set_mac_addr,
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+ .ndo_vlan_rx_register = vlan_rx_register,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = t1_netpoll,
+#endif
+};
+
static int __devinit init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -1077,7 +1094,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 +1135,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;
@@ -1130,7 +1147,6 @@ static int __devinit init_one(struct pci_dev *pdev,
adapter->flags |= VLAN_ACCEL_CAPABLE;
netdev->features |=
NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- netdev->vlan_rx_register = vlan_rx_register;
#endif
/* T204: disable TSO */
@@ -1140,19 +1156,11 @@ static int __devinit init_one(struct pci_dev *pdev,
}
}
- netdev->open = cxgb_open;
- netdev->stop = cxgb_close;
+ netdev->netdev_ops = &cxgb_netdev_ops;
netdev->hard_start_xmit = t1_start_xmit;
netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ?
sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt);
- netdev->get_stats = t1_get_stats;
- netdev->set_multicast_list = t1_set_rxmode;
- netdev->do_ioctl = t1_ioctl;
- netdev->change_mtu = t1_change_mtu;
- netdev->set_mac_address = t1_set_mac_addr;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = t1_netpoll;
-#endif
+
netif_napi_add(netdev, &adapter->napi, t1_poll, 64);
SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops);
@@ -1382,7 +1390,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) {
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index d6c7d2aa761..ca80289fc04 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -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());
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index 017a5361b98..d39a77cba1a 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -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;
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index 7e8a63106bd..c9806c58b2f 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -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);
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index 7107620f615..b063395c4a9 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -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));
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 2c341f83d32..a9479be53ec 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -494,6 +494,36 @@ static void enable_all_napi(struct adapter *adap)
}
/**
+ * 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:{
@@ -2783,6 +2828,21 @@ static void __devinit print_port_info(struct adapter *adap,
}
}
+static const struct net_device_ops cxgb_netdev_ops = {
+ .ndo_open = cxgb_open,
+ .ndo_stop = cxgb_close,
+ .ndo_get_stats = cxgb_get_stats,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = cxgb_set_rxmode,
+ .ndo_do_ioctl = cxgb_ioctl,
+ .ndo_change_mtu = cxgb_change_mtu,
+ .ndo_set_mac_address = cxgb_set_mac_addr,
+ .ndo_vlan_rx_register = vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = cxgb_netpoll,
+#endif
+};
+
static int __devinit init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -2894,20 +2954,8 @@ static int __devinit init_one(struct pci_dev *pdev,
netdev->features |= NETIF_F_HIGHDMA;
netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- netdev->vlan_rx_register = vlan_rx_register;
-
- netdev->open = cxgb_open;
- netdev->stop = cxgb_close;
+ netdev->netdev_ops = &cxgb_netdev_ops;
netdev->hard_start_xmit = t3_eth_xmit;
- netdev->get_stats = cxgb_get_stats;
- netdev->set_multicast_list = cxgb_set_rxmode;
- netdev->do_ioctl = cxgb_ioctl;
- netdev->change_mtu = cxgb_change_mtu;
- netdev->set_mac_address = cxgb_set_mac_addr;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = cxgb_netpoll;
-#endif
-
SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
}
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index c6480be0bc1..268f15801ec 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -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) {
diff --git a/drivers/net/de600.c b/drivers/net/de600.c
index cb849b091f9..970f820ba81 100644
--- a/drivers/net/de600.c
+++ b/drivers/net/de600.c
@@ -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;
diff --git a/drivers/net/de620.c b/drivers/net/de620.c
index d454e143483..0d4b6acc11a 100644
--- a/drivers/net/de620.c
+++ b/drivers/net/de620.c
@@ -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);
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index 3e3506411ac..7ce3053530f 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -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;
diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c
index c062aacf229..6e6583b609f 100644
--- a/drivers/net/defxx.c
+++ b/drivers/net/defxx.c
@@ -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++;
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index ace39ec0a36..ec34f03cb98 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -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;
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index f8037110a52..9ec9785a9fc 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -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;
}
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 5a9083e3f44..bcf92917bbf 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -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");
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index e8bfcce6b31..5894716de19 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -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;
@@ -2610,13 +2612,26 @@ static int e100_close(struct net_device *netdev)
return 0;
}
+static const struct net_device_ops e100_netdev_ops = {
+ .ndo_open = e100_open,
+ .ndo_stop = e100_close,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = e100_set_multicast_list,
+ .ndo_set_mac_address = e100_set_mac_address,
+ .ndo_change_mtu = e100_change_mtu,
+ .ndo_do_ioctl = e100_do_ioctl,
+ .ndo_tx_timeout = e100_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = e100_netpoll,
+#endif
+};
+
static int __devinit e100_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
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)
@@ -2624,19 +2639,10 @@ static int __devinit e100_probe(struct pci_dev *pdev,
return -ENOMEM;
}
- netdev->open = e100_open;
- netdev->stop = e100_close;
+ netdev->netdev_ops = &e100_netdev_ops;
netdev->hard_start_xmit = e100_xmit_frame;
- netdev->set_multicast_list = e100_set_multicast_list;
- netdev->set_mac_address = e100_set_mac_address;
- netdev->change_mtu = e100_change_mtu;
- netdev->do_ioctl = e100_do_ioctl;
SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops);
- netdev->tx_timeout = e100_tx_timeout;
netdev->watchdog_timeo = E100_WATCHDOG_PERIOD;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = e100_netpoll;
-#endif
strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
nic = netdev_priv(netdev);
@@ -2734,8 +2740,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 +2754,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 +2802,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);
@@ -2843,7 +2850,7 @@ static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel
struct nic *nic = netdev_priv(netdev);
/* Similar to calling e100_down(), but avoids adapter I/O. */
- netdev->stop(netdev);
+ e100_close(netdev);
/* Detach; put netif into a state similar to hotplug unplug. */
napi_enable(&nic->napi);
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 872799b746f..debbba390d4 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -888,6 +888,25 @@ static int e1000_is_need_ioport(struct pci_dev *pdev)
}
}
+static const struct net_device_ops e1000_netdev_ops = {
+ .ndo_open = e1000_open,
+ .ndo_stop = e1000_close,
+ .ndo_get_stats = e1000_get_stats,
+ .ndo_set_rx_mode = e1000_set_rx_mode,
+ .ndo_set_mac_address = e1000_set_mac,
+ .ndo_tx_timeout = e1000_tx_timeout,
+ .ndo_change_mtu = e1000_change_mtu,
+ .ndo_do_ioctl = e1000_ioctl,
+ .ndo_validate_addr = eth_validate_addr,
+
+ .ndo_vlan_rx_register = e1000_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = e1000_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = e1000_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = e1000_netpoll,
+#endif
+};
+
/**
* e1000_probe - Device Initialization Routine
* @pdev: PCI device information struct
@@ -912,7 +931,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 +985,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;
@@ -983,24 +1000,12 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
}
}
- netdev->open = &e1000_open;
- netdev->stop = &e1000_close;
+ netdev->netdev_ops = &e1000_netdev_ops;
netdev->hard_start_xmit = &e1000_xmit_frame;
- netdev->get_stats = &e1000_get_stats;
- netdev->set_rx_mode = &e1000_set_rx_mode;
- netdev->set_mac_address = &e1000_set_mac;
- netdev->change_mtu = &e1000_change_mtu;
- netdev->do_ioctl = &e1000_ioctl;
e1000_set_ethtool_ops(netdev);
- netdev->tx_timeout = &e1000_tx_timeout;
netdev->watchdog_timeo = 5 * HZ;
netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
- netdev->vlan_rx_register = e1000_vlan_rx_register;
- netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid;
- netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = e1000_netpoll;
-#endif
+
strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
adapter->bd_number = cards_found;
@@ -1016,9 +1021,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 +1198,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 +3794,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 +4106,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 +4789,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 +4811,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 +4845,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);
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index b2c910c52df..3027ad53fa6 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -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);
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index 48f79ecb82a..34a68fcab5a 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -372,6 +372,13 @@
#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:
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index f66ed37a7f7..c4ffd4b7051 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -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 */
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 91795f78c3e..ced839e4cae 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -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);
@@ -4709,6 +4704,25 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter)
}
}
+static const struct net_device_ops e1000e_netdev_ops = {
+ .ndo_open = e1000_open,
+ .ndo_stop = e1000_close,
+ .ndo_get_stats = e1000_get_stats,
+ .ndo_set_multicast_list = e1000_set_multi,
+ .ndo_set_mac_address = e1000_set_mac,
+ .ndo_change_mtu = e1000_change_mtu,
+ .ndo_do_ioctl = e1000_ioctl,
+ .ndo_tx_timeout = e1000_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+
+ .ndo_vlan_rx_register = e1000_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = e1000_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = e1000_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = e1000_netpoll,
+#endif
+};
+
/**
* e1000_probe - Device Initialization Routine
* @pdev: PCI device information struct
@@ -4807,24 +4821,11 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
}
/* construct the net_device struct */
- netdev->open = &e1000_open;
- netdev->stop = &e1000_close;
+ netdev->netdev_ops = &e1000e_netdev_ops;
netdev->hard_start_xmit = &e1000_xmit_frame;
- netdev->get_stats = &e1000_get_stats;
- netdev->set_multicast_list = &e1000_set_multi;
- netdev->set_mac_address = &e1000_set_mac;
- netdev->change_mtu = &e1000_change_mtu;
- netdev->do_ioctl = &e1000_ioctl;
e1000e_set_ethtool_ops(netdev);
- netdev->tx_timeout = &e1000_tx_timeout;
netdev->watchdog_timeo = 5 * HZ;
netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
- netdev->vlan_rx_register = e1000_vlan_rx_register;
- netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid;
- netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = e1000_netpoll;
-#endif
strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
netdev->mem_start = mmio_start;
@@ -4925,10 +4926,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;
}
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index 1f11350e16c..0a984619411 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -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
index e3e26c595fa..00000000000
--- a/drivers/net/eepro100.c
+++ /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:
- */
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
index b751c1b96cf..a125e41240f 100644
--- a/drivers/net/eexpress.c
+++ b/drivers/net/eexpress.c
@@ -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;
}
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 002d918fb4c..9930d5f8b9e 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -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
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 422fcb93e2c..44c9ae18383 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -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,
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index 9d006878f04..3c0ec82f36f 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -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;
}
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c
index e1b441effbb..32c19790d01 100644
--- a/drivers/net/enc28j60.c
+++ b/drivers/net/enc28j60.c
@@ -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
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 180e968dc54..40f8c88b166 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -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) {
@@ -1591,6 +1590,22 @@ static void enic_iounmap(struct enic *enic)
iounmap(enic->bar0.vaddr);
}
+static const struct net_device_ops enic_netdev_ops = {
+ .ndo_open = enic_open,
+ .ndo_stop = enic_stop,
+ .ndo_get_stats = enic_get_stats,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = enic_set_multicast_list,
+ .ndo_change_mtu = enic_change_mtu,
+ .ndo_vlan_rx_register = enic_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = enic_vlan_rx_kill_vid,
+ .ndo_tx_timeout = enic_tx_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = enic_poll_controller,
+#endif
+};
+
static int __devinit enic_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -1814,21 +1829,10 @@ static int __devinit enic_probe(struct pci_dev *pdev,
goto err_out_free_vnic_resources;
}
- netdev->open = enic_open;
- netdev->stop = enic_stop;
+ netdev->netdev_ops = &enic_netdev_ops;
netdev->hard_start_xmit = enic_hard_start_xmit;
- netdev->get_stats = enic_get_stats;
- netdev->set_multicast_list = enic_set_multicast_list;
- netdev->change_mtu = enic_change_mtu;
- netdev->vlan_rx_register = enic_vlan_rx_register;
- netdev->vlan_rx_add_vid = enic_vlan_rx_add_vid;
- netdev->vlan_rx_kill_vid = enic_vlan_rx_kill_vid;
- netdev->tx_timeout = enic_tx_timeout;
netdev->watchdog_timeo = 2 * HZ;
netdev->ethtool_ops = &enic_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = enic_poll_controller;
-#endif
switch (vnic_dev_get_intr_mode(enic->vdev)) {
default:
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 95184b9108e..e5fc9384f8f 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -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),
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index 4d104f5c30f..9afd33c7188 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -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)
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 76118ddd104..4a951b8cb4d 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -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);
diff --git a/drivers/net/es3210.c b/drivers/net/es3210.c
index deefa51b8c3..e7df9f4a183 100644
--- a/drivers/net/es3210.c
+++ b/drivers/net/es3210.c
@@ -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) {
diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c
index bee8b3fbc56..8d9fe4dd346 100644
--- a/drivers/net/eth16i.c
+++ b/drivers/net/eth16i.c
@@ -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);
diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
index 593a120e31b..f3b664aafb8 100644
--- a/drivers/net/ewrk3.c
+++ b/drivers/net/ewrk3.c
@@ -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 {
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index b455ae931f7..31ab1ff623f 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -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;
}
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index ecd5c71a7a8..7e33c129d51 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -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;
}
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index aec3b97e794..cd8e98b45ec 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -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");
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index cc7328b1552..dd2e1f670b0 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -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 {
@@ -5410,6 +5408,21 @@ static int nv_close(struct net_device *dev)
return 0;
}
+static const struct net_device_ops nv_netdev_ops = {
+ .ndo_open = nv_open,
+ .ndo_stop = nv_close,
+ .ndo_get_stats = nv_get_stats,
+ .ndo_tx_timeout = nv_tx_timeout,
+ .ndo_change_mtu = nv_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = nv_set_mac_address,
+ .ndo_set_multicast_list = nv_set_multicast,
+ .ndo_vlan_rx_register = nv_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = nv_poll_controller,
+#endif
+};
+
static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
{
struct net_device *dev;
@@ -5420,7 +5433,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++)
@@ -5530,7 +5542,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
if (id->driver_data & DEV_HAS_VLAN) {
np->vlanctl_bits = NVREG_VLANCONTROL_ENABLE;
dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX;
- dev->vlan_rx_register = nv_vlan_rx_register;
}
np->msi_flags = 0;
@@ -5580,25 +5591,16 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
if (!np->rx_skb || !np->tx_skb)
goto out_freering;
- dev->open = nv_open;
- dev->stop = nv_close;
-
if (!nv_optimized(np))
dev->hard_start_xmit = nv_start_xmit;
else
dev->hard_start_xmit = nv_start_xmit_optimized;
- dev->get_stats = nv_get_stats;
- dev->change_mtu = nv_change_mtu;
- dev->set_mac_address = nv_set_mac_address;
- dev->set_multicast_list = nv_set_multicast;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = nv_poll_controller;
-#endif
+
+ dev->netdev_ops = &nv_netdev_ops;
#ifdef CONFIG_FORCEDETH_NAPI
netif_napi_add(dev, &np->napi, nv_napi_poll, RX_WORK_PER_LOOP);
#endif
SET_ETHTOOL_OPS(dev, &ops);
- dev->tx_timeout = nv_tx_timeout;
dev->watchdog_timeo = NV_WATCHDOG_TIMEO;
pci_set_drvdata(pci_dev, dev);
@@ -5653,8 +5655,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 +5665,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);
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index a6f49d02578..df66d620b11 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -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;
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index c4af949bf86..2635f5bed77 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -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 */
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 3199526bcec..77f2b2934e6 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -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;
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 0f501d2ca93..50f1e172ee8 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -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;
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 00bc7fbb6b3..81a65e3a1c0 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -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++;
}
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 58f4b1d7bf1..46f8f3390e7 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -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;
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index e8cfadefa4b..e67103396ed 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -572,7 +572,7 @@ static int __init setup_adapter(int card_base, int type, int n)
priv->param.persist = 256;
priv->param.dma = -1;
INIT_WORK(&priv->rx_work, rx_bh);
- dev->priv = priv;
+ dev->ml_priv = priv;
sprintf(dev->name, "dmascc%i", 2 * n + i);
dev->base_addr = card_base;
dev->irq = irq;
@@ -720,7 +720,7 @@ static int read_scc_data(struct scc_priv *priv)
static int scc_open(struct net_device *dev)
{
- struct scc_priv *priv = dev->priv;
+ struct scc_priv *priv = dev->ml_priv;
struct scc_info *info = priv->info;
int card_base = priv->card_base;
@@ -862,7 +862,7 @@ static int scc_open(struct net_device *dev)
static int scc_close(struct net_device *dev)
{
- struct scc_priv *priv = dev->priv;
+ struct scc_priv *priv = dev->ml_priv;
struct scc_info *info = priv->info;
int card_base = priv->card_base;
@@ -891,7 +891,7 @@ static int scc_close(struct net_device *dev)
static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
- struct scc_priv *priv = dev->priv;
+ struct scc_priv *priv = dev->ml_priv;
switch (cmd) {
case SIOCGSCCPARAM:
@@ -918,7 +918,7 @@ static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int scc_send_packet(struct sk_buff *skb, struct net_device *dev)
{
- struct scc_priv *priv = dev->priv;
+ struct scc_priv *priv = dev->ml_priv;
unsigned long flags;
int i;
@@ -963,7 +963,7 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev)
static struct net_device_stats *scc_get_stats(struct net_device *dev)
{
- struct scc_priv *priv = dev->priv;
+ struct scc_priv *priv = dev->ml_priv;
return &priv->stats;
}
@@ -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;
}
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index c258a0586e6..8eba61a1d4a 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -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++;
}
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index b8e25c4624d..7570c73f18c 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -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);
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index c17e39bc546..c011af7088e 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -1518,7 +1518,7 @@ static int scc_net_alloc(const char *name, struct scc_channel *scc)
if (!dev)
return -ENOMEM;
- dev->priv = scc;
+ dev->ml_priv = scc;
scc->dev = dev;
spin_lock_init(&scc->lock);
init_timer(&scc->tx_t);
@@ -1575,7 +1575,7 @@ static void scc_net_setup(struct net_device *dev)
static int scc_net_open(struct net_device *dev)
{
- struct scc_channel *scc = (struct scc_channel *) dev->priv;
+ struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
if (!scc->init)
return -EINVAL;
@@ -1593,7 +1593,7 @@ static int scc_net_open(struct net_device *dev)
static int scc_net_close(struct net_device *dev)
{
- struct scc_channel *scc = (struct scc_channel *) dev->priv;
+ struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
unsigned long flags;
netif_stop_queue(dev);
@@ -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;
}
@@ -1635,7 +1634,7 @@ static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb)
static int scc_net_tx(struct sk_buff *skb, struct net_device *dev)
{
- struct scc_channel *scc = (struct scc_channel *) dev->priv;
+ struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
unsigned long flags;
char kisscmd;
@@ -1705,7 +1704,7 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
struct scc_mem_config memcfg;
struct scc_hw_config hwcfg;
struct scc_calibrate cal;
- struct scc_channel *scc = (struct scc_channel *) dev->priv;
+ struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
int chan;
unsigned char device_name[IFNAMSIZ];
void __user *arg = ifr->ifr_data;
@@ -1952,7 +1951,7 @@ static int scc_net_set_mac_address(struct net_device *dev, void *addr)
static struct net_device_stats *scc_net_get_stats(struct net_device *dev)
{
- struct scc_channel *scc = (struct scc_channel *) dev->priv;
+ struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
scc->dev_stat.rx_errors = scc->stat.rxerrs + scc->stat.rx_over;
scc->dev_stat.tx_errors = scc->stat.txerrs + scc->stat.tx_under;
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 1c942862a3f..5407f7486c9 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -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;
}
}
diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c
index fbbd3e660c2..9026fd6ea0f 100644
--- a/drivers/net/hp-plus.c
+++ b/drivers/net/hp-plus.c
@@ -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);
diff --git a/drivers/net/hp.c b/drivers/net/hp.c
index 0a8c64930ad..3669194f106 100644
--- a/drivers/net/hp.c
+++ b/drivers/net/hp.c
@@ -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) {
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index 571dd80fb85..4dda9b043b1 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -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;
diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c
index b96cf2dcb10..b0ae0766ea4 100644
--- a/drivers/net/hydra.c
+++ b/drivers/net/hydra.c
@@ -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;
}
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 901212aa37c..87a706694fb 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -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);
diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c
index f02764725a2..5b5bf9f9861 100644
--- a/drivers/net/ibmlana.c
+++ b/drivers/net/ibmlana.c
@@ -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 */
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index c2d57f83608..02ecfdb4df6 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -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;
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index e4fbefc8c82..363a166df8f 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -137,18 +137,23 @@ resched:
}
+static const struct net_device_ops ifb_netdev_ops = {
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_open = ifb_open,
+ .ndo_stop = ifb_close,
+};
+
static void ifb_setup(struct net_device *dev)
{
/* Initialize the device structure. */
dev->hard_start_xmit = ifb_xmit;
- dev->open = &ifb_open;
- dev->stop = &ifb_close;
dev->destructor = free_netdev;
+ dev->netdev_ops = &ifb_netdev_ops;
/* Fill in device structure with ethernet-generic values. */
ether_setup(dev);
dev->tx_queue_len = TX_Q_LIMIT;
- dev->change_mtu = NULL;
+
dev->flags |= IFF_NOARP;
dev->flags &= ~IFF_MULTICAST;
random_ether_addr(dev->dev_addr);
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 4ff6f0567f3..acf2569b98f 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -294,6 +294,8 @@ struct igb_adapter {
unsigned int lro_flushed;
unsigned int lro_no_desc;
#endif
+ unsigned int tx_ring_count;
+ unsigned int rx_ring_count;
};
#define IGB_FLAG_HAS_MSI (1 << 0)
@@ -325,6 +327,8 @@ extern void igb_reset(struct igb_adapter *);
extern int igb_set_spd_dplx(struct igb_adapter *, u16);
extern int igb_setup_tx_resources(struct igb_adapter *, struct igb_ring *);
extern int igb_setup_rx_resources(struct igb_adapter *, struct igb_ring *);
+extern void igb_free_tx_resources(struct igb_ring *);
+extern void igb_free_rx_resources(struct igb_ring *);
extern void igb_update_stats(struct igb_adapter *);
extern void igb_set_ethtool_ops(struct net_device *);
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 89964fa739a..a661159a097 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -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)
@@ -714,15 +714,13 @@ static void igb_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring)
{
struct igb_adapter *adapter = netdev_priv(netdev);
- struct igb_ring *tx_ring = adapter->tx_ring;
- struct igb_ring *rx_ring = adapter->rx_ring;
ring->rx_max_pending = IGB_MAX_RXD;
ring->tx_max_pending = IGB_MAX_TXD;
ring->rx_mini_max_pending = 0;
ring->rx_jumbo_max_pending = 0;
- ring->rx_pending = rx_ring->count;
- ring->tx_pending = tx_ring->count;
+ ring->rx_pending = adapter->rx_ring_count;
+ ring->tx_pending = adapter->tx_ring_count;
ring->rx_mini_pending = 0;
ring->rx_jumbo_pending = 0;
}
@@ -731,12 +729,9 @@ static int igb_set_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring)
{
struct igb_adapter *adapter = netdev_priv(netdev);
- struct igb_buffer *old_buf;
- struct igb_buffer *old_rx_buf;
- void *old_desc;
+ struct igb_ring *temp_ring;
int i, err;
- u32 new_rx_count, new_tx_count, old_size;
- dma_addr_t old_dma;
+ u32 new_rx_count, new_tx_count;
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
return -EINVAL;
@@ -749,12 +744,19 @@ static int igb_set_ringparam(struct net_device *netdev,
new_tx_count = min(new_tx_count, (u32)IGB_MAX_TXD);
new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE);
- if ((new_tx_count == adapter->tx_ring->count) &&
- (new_rx_count == adapter->rx_ring->count)) {
+ if ((new_tx_count == adapter->tx_ring_count) &&
+ (new_rx_count == adapter->rx_ring_count)) {
/* nothing to do */
return 0;
}
+ if (adapter->num_tx_queues > adapter->num_rx_queues)
+ temp_ring = vmalloc(adapter->num_tx_queues * sizeof(struct igb_ring));
+ else
+ temp_ring = vmalloc(adapter->num_rx_queues * sizeof(struct igb_ring));
+ if (!temp_ring)
+ return -ENOMEM;
+
while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
msleep(1);
@@ -766,62 +768,55 @@ static int igb_set_ringparam(struct net_device *netdev,
* because the ISRs in MSI-X mode get passed pointers
* to the tx and rx ring structs.
*/
- if (new_tx_count != adapter->tx_ring->count) {
+ if (new_tx_count != adapter->tx_ring_count) {
+ memcpy(temp_ring, adapter->tx_ring,
+ adapter->num_tx_queues * sizeof(struct igb_ring));
+
for (i = 0; i < adapter->num_tx_queues; i++) {
- /* Save existing descriptor ring */
- old_buf = adapter->tx_ring[i].buffer_info;
- old_desc = adapter->tx_ring[i].desc;
- old_size = adapter->tx_ring[i].size;
- old_dma = adapter->tx_ring[i].dma;
- /* Try to allocate a new one */
- adapter->tx_ring[i].buffer_info = NULL;
- adapter->tx_ring[i].desc = NULL;
- adapter->tx_ring[i].count = new_tx_count;
- err = igb_setup_tx_resources(adapter,
- &adapter->tx_ring[i]);
+ temp_ring[i].count = new_tx_count;
+ err = igb_setup_tx_resources(adapter, &temp_ring[i]);
if (err) {
- /* Restore the old one so at least
- the adapter still works, even if
- we failed the request */
- adapter->tx_ring[i].buffer_info = old_buf;
- adapter->tx_ring[i].desc = old_desc;
- adapter->tx_ring[i].size = old_size;
- adapter->tx_ring[i].dma = old_dma;
+ while (i) {
+ i--;
+ igb_free_tx_resources(&temp_ring[i]);
+ }
goto err_setup;
}
- /* Free the old buffer manually */
- vfree(old_buf);
- pci_free_consistent(adapter->pdev, old_size,
- old_desc, old_dma);
}
+
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ igb_free_tx_resources(&adapter->tx_ring[i]);
+
+ memcpy(adapter->tx_ring, temp_ring,
+ adapter->num_tx_queues * sizeof(struct igb_ring));
+
+ adapter->tx_ring_count = new_tx_count;
}
if (new_rx_count != adapter->rx_ring->count) {
- for (i = 0; i < adapter->num_rx_queues; i++) {
+ memcpy(temp_ring, adapter->rx_ring,
+ adapter->num_rx_queues * sizeof(struct igb_ring));
- old_rx_buf = adapter->rx_ring[i].buffer_info;
- old_desc = adapter->rx_ring[i].desc;
- old_size = adapter->rx_ring[i].size;
- old_dma = adapter->rx_ring[i].dma;
-
- adapter->rx_ring[i].buffer_info = NULL;
- adapter->rx_ring[i].desc = NULL;
- adapter->rx_ring[i].dma = 0;
- adapter->rx_ring[i].count = new_rx_count;
- err = igb_setup_rx_resources(adapter,
- &adapter->rx_ring[i]);
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ temp_ring[i].count = new_rx_count;
+ err = igb_setup_rx_resources(adapter, &temp_ring[i]);
if (err) {
- adapter->rx_ring[i].buffer_info = old_rx_buf;
- adapter->rx_ring[i].desc = old_desc;
- adapter->rx_ring[i].size = old_size;
- adapter->rx_ring[i].dma = old_dma;
+ while (i) {
+ i--;
+ igb_free_rx_resources(&temp_ring[i]);
+ }
goto err_setup;
}
- vfree(old_rx_buf);
- pci_free_consistent(adapter->pdev, old_size, old_desc,
- old_dma);
}
+
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ igb_free_rx_resources(&adapter->rx_ring[i]);
+
+ memcpy(adapter->rx_ring, temp_ring,
+ adapter->num_rx_queues * sizeof(struct igb_ring));
+
+ adapter->rx_ring_count = new_rx_count;
}
err = 0;
@@ -830,6 +825,7 @@ err_setup:
igb_up(adapter);
clear_bit(__IGB_RESETTING, &adapter->state);
+ vfree(temp_ring);
return err;
}
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 1cbae85b142..ceb0a045879 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -76,8 +76,6 @@ static int igb_setup_all_tx_resources(struct igb_adapter *);
static int igb_setup_all_rx_resources(struct igb_adapter *);
static void igb_free_all_tx_resources(struct igb_adapter *);
static void igb_free_all_rx_resources(struct igb_adapter *);
-static void igb_free_tx_resources(struct igb_ring *);
-static void igb_free_rx_resources(struct igb_ring *);
void igb_update_stats(struct igb_adapter *);
static int igb_probe(struct pci_dev *, const struct pci_device_id *);
static void __devexit igb_remove(struct pci_dev *pdev);
@@ -259,11 +257,13 @@ static int igb_alloc_queues(struct igb_adapter *adapter)
for (i = 0; i < adapter->num_tx_queues; i++) {
struct igb_ring *ring = &(adapter->tx_ring[i]);
+ ring->count = adapter->tx_ring_count;
ring->adapter = adapter;
ring->queue_index = i;
}
for (i = 0; i < adapter->num_rx_queues; i++) {
struct igb_ring *ring = &(adapter->rx_ring[i]);
+ ring->count = adapter->rx_ring_count;
ring->adapter = adapter;
ring->queue_index = i;
ring->itr_register = E1000_ITR;
@@ -950,6 +950,24 @@ static int igb_is_need_ioport(struct pci_dev *pdev)
}
}
+static const struct net_device_ops igb_netdev_ops = {
+ .ndo_open = igb_open,
+ .ndo_stop = igb_close,
+ .ndo_get_stats = igb_get_stats,
+ .ndo_set_multicast_list = igb_set_multi,
+ .ndo_set_mac_address = igb_set_mac,
+ .ndo_change_mtu = igb_change_mtu,
+ .ndo_do_ioctl = igb_ioctl,
+ .ndo_tx_timeout = igb_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_vlan_rx_register = igb_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = igb_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = igb_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = igb_netpoll,
+#endif
+};
+
/**
* igb_probe - Device Initialization Routine
* @pdev: PCI device information struct
@@ -1059,22 +1077,9 @@ static int __devinit igb_probe(struct pci_dev *pdev,
if (!adapter->hw.hw_addr)
goto err_ioremap;
- netdev->open = &igb_open;
- netdev->stop = &igb_close;
- netdev->get_stats = &igb_get_stats;
- netdev->set_multicast_list = &igb_set_multi;
- netdev->set_mac_address = &igb_set_mac;
- netdev->change_mtu = &igb_change_mtu;
- netdev->do_ioctl = &igb_ioctl;
+ netdev->netdev_ops = &igb_netdev_ops;
igb_set_ethtool_ops(netdev);
- netdev->tx_timeout = &igb_tx_timeout;
netdev->watchdog_timeo = 5 * HZ;
- netdev->vlan_rx_register = igb_vlan_rx_register;
- netdev->vlan_rx_add_vid = igb_vlan_rx_add_vid;
- netdev->vlan_rx_kill_vid = igb_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = igb_netpoll;
-#endif
netdev->hard_start_xmit = &igb_xmit_frame_adv;
strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
@@ -1275,16 +1280,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,
@@ -1397,6 +1400,8 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word);
+ adapter->tx_ring_count = IGB_DEFAULT_TXD;
+ adapter->rx_ring_count = IGB_DEFAULT_RXD;
adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
adapter->rx_ps_hdr_size = 0; /* disable packet split */
adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
@@ -1985,7 +1990,7 @@ static void igb_configure_rx(struct igb_adapter *adapter)
*
* Free all transmit software resources
**/
-static void igb_free_tx_resources(struct igb_ring *tx_ring)
+void igb_free_tx_resources(struct igb_ring *tx_ring)
{
struct pci_dev *pdev = tx_ring->adapter->pdev;
@@ -2085,7 +2090,7 @@ static void igb_clean_all_tx_rings(struct igb_adapter *adapter)
*
* Free all receive software resources
**/
-static void igb_free_rx_resources(struct igb_ring *rx_ring)
+void igb_free_rx_resources(struct igb_ring *rx_ring)
{
struct pci_dev *pdev = rx_ring->adapter->pdev;
@@ -3923,8 +3928,10 @@ send_up:
next_buffer = &rx_ring->buffer_info[i];
if (!(staterr & E1000_RXD_STAT_EOP)) {
- buffer_info->skb = xchg(&next_buffer->skb, skb);
- buffer_info->dma = xchg(&next_buffer->dma, 0);
+ buffer_info->skb = next_buffer->skb;
+ buffer_info->dma = next_buffer->dma;
+ next_buffer->skb = skb;
+ next_buffer->dma = 0;
goto next_desc;
}
@@ -3942,8 +3949,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;
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 1f25263dc7e..170b12d1d70 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -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 {
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index 059369885be..7b6d435a846 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -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. */
diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c
index 2ff181861d2..3c58e67ef1e 100644
--- a/drivers/net/irda/ali-ircc.c
+++ b/drivers/net/irda/ali-ircc.c
@@ -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__ );
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c
index a1e4508717c..6c4b53ffbca 100644
--- a/drivers/net/irda/au1k_ir.c
+++ b/drivers/net/irda/au1k_ir.c
@@ -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;
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 69d16b30323..687c2d53d4d 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -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);
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index b5d6b9ac162..205e4e825a9 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -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);
diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c
index e1429fc6d05..c747c874d44 100644
--- a/drivers/net/irda/kingsun-sir.c
+++ b/drivers/net/irda/kingsun-sir.c
@@ -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)
diff --git a/drivers/net/irda/ks959-sir.c b/drivers/net/irda/ks959-sir.c
index 2e67ae015d9..600d96f9cdb 100644
--- a/drivers/net/irda/ks959-sir.c
+++ b/drivers/net/irda/ks959-sir.c
@@ -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;
diff --git a/drivers/net/irda/ksdazzle-sir.c b/drivers/net/irda/ksdazzle-sir.c
index 3843b5faba8..0e7f89337b2 100644
--- a/drivers/net/irda/ksdazzle-sir.c
+++ b/drivers/net/irda/ksdazzle-sir.c
@@ -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;
}
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index ad92d3ff1c4..904c9610c0d 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -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);
}
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index 8583d951a6a..2c6bf2d11bb 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -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;
}
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index c5b02b66f75..a0ee0531815 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -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;
}
}
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index a95188948de..ccde5829ba2 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -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);
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index 3f32909c24c..ceef040aa76 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -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;
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index 3575804fd7c..ca4cd9266e5 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -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);
}
diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c
index 84e609ea5fb..74c78cf7a33 100644
--- a/drivers/net/irda/via-ircc.c
+++ b/drivers/net/irda/via-ircc.c
@@ -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;
}
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index 9c926d205de..0d30f8d659a 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -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);
diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c
index 002a6d769f2..161d591aeb9 100644
--- a/drivers/net/irda/w83977af_ir.c
+++ b/drivers/net/irda/w83977af_ir.c
@@ -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;
}
diff --git a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c
index d6ff26af37b..15ebae9b98d 100644
--- a/drivers/net/isa-skeleton.c
+++ b/drivers/net/isa-skeleton.c
@@ -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;
}
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index c46864d626b..c7457f97259 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -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) {
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index be3c7dc96f6..3ca9daa70b3 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -321,6 +321,23 @@ ixgb_reset(struct ixgb_adapter *adapter)
}
}
+static const struct net_device_ops ixgb_netdev_ops = {
+ .ndo_open = ixgb_open,
+ .ndo_stop = ixgb_close,
+ .ndo_get_stats = ixgb_get_stats,
+ .ndo_set_multicast_list = ixgb_set_multi,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = ixgb_set_mac,
+ .ndo_change_mtu = ixgb_change_mtu,
+ .ndo_tx_timeout = ixgb_tx_timeout,
+ .ndo_vlan_rx_register = ixgb_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = ixgb_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = ixgb_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ixgb_netpoll,
+#endif
+};
+
/**
* ixgb_probe - Device Initialization Routine
* @pdev: PCI device information struct
@@ -381,8 +398,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;
@@ -397,23 +413,11 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
}
- netdev->open = &ixgb_open;
- netdev->stop = &ixgb_close;
+ netdev->netdev_ops = &ixgb_netdev_ops;
netdev->hard_start_xmit = &ixgb_xmit_frame;
- netdev->get_stats = &ixgb_get_stats;
- netdev->set_multicast_list = &ixgb_set_multi;
- netdev->set_mac_address = &ixgb_set_mac;
- netdev->change_mtu = &ixgb_change_mtu;
ixgb_set_ethtool_ops(netdev);
- netdev->tx_timeout = &ixgb_tx_timeout;
netdev->watchdog_timeo = 5 * HZ;
netif_napi_add(netdev, &adapter->napi, ixgb_clean, 64);
- netdev->vlan_rx_register = ixgb_vlan_rx_register;
- netdev->vlan_rx_add_vid = ixgb_vlan_rx_add_vid;
- netdev->vlan_rx_kill_vid = ixgb_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = ixgb_netpoll;
-#endif
strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
@@ -1981,7 +1985,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 */
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index e116d340dcc..132854f646b 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -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)
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 7cddcfba809..c2cdb042c48 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -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;
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 81a9c4b8672..a610016a017 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -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;
}
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 36f2bb666bf..7ad07a00680 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -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);
@@ -1312,6 +1326,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);
}
@@ -1343,6 +1359,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;
@@ -1925,6 +1943,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;
@@ -1970,6 +1995,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;
@@ -2562,6 +2590,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;
@@ -3217,7 +3248,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;
@@ -3228,7 +3258,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);
}
}
@@ -3689,9 +3718,30 @@ 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);
}
+static const struct net_device_ops ixgbe_netdev_ops = {
+ .ndo_open = ixgbe_open,
+ .ndo_stop = ixgbe_close,
+ .ndo_get_stats = ixgbe_get_stats,
+ .ndo_set_multicast_list = ixgbe_set_rx_mode,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = ixgbe_set_mac,
+ .ndo_change_mtu = ixgbe_change_mtu,
+ .ndo_tx_timeout = ixgbe_tx_timeout,
+ .ndo_vlan_rx_register = ixgbe_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ixgbe_netpoll,
+#endif
+};
+
/**
* ixgbe_probe - Device Initialization Routine
* @pdev: PCI device information struct
@@ -3773,23 +3823,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
continue;
}
- netdev->open = &ixgbe_open;
- netdev->stop = &ixgbe_close;
+ netdev->netdev_ops = &ixgbe_netdev_ops;
netdev->hard_start_xmit = &ixgbe_xmit_frame;
- netdev->get_stats = &ixgbe_get_stats;
- netdev->set_rx_mode = &ixgbe_set_rx_mode;
- netdev->set_multicast_list = &ixgbe_set_rx_mode;
- netdev->set_mac_address = &ixgbe_set_mac;
- netdev->change_mtu = &ixgbe_change_mtu;
ixgbe_set_ethtool_ops(netdev);
- netdev->tx_timeout = &ixgbe_tx_timeout;
netdev->watchdog_timeo = 5 * HZ;
- netdev->vlan_rx_register = ixgbe_vlan_rx_register;
- netdev->vlan_rx_add_vid = ixgbe_vlan_rx_add_vid;
- netdev->vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = ixgbe_netpoll;
-#endif
strcpy(netdev->name, pci_name(pdev));
adapter->bd_number = cards_found;
@@ -3875,8 +3912,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"),
@@ -3885,8 +3921,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,
@@ -3911,7 +3946,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);
@@ -4009,7 +4043,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);
@@ -4030,7 +4064,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,
@@ -4058,7 +4092,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)) {
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index 764035a8c9a..981e6d84959 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -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;
+}
+
diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h
index 9bfe3f2b1d8..5cc063d0277 100644
--- a/drivers/net/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ixgbe/ixgbe_phy.h
@@ -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_ */
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index c6f8fa1c4e5..51df39dae81 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -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
@@ -488,6 +489,8 @@
#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 *);
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
index 7b70c66504a..bd96dbc8e02 100644
--- a/drivers/net/ixp2000/ixpdev.c
+++ b/drivers/net/ixp2000/ixpdev.c
@@ -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);
}
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index 07944820f74..334ff9e12cd 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -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;
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index 665e70d620f..0430ffb6236 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -931,7 +931,6 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx)
cpu_to_le16(RXWBFLAG_DEST_MUL))
++(NET_STAT(jme).multicast);
- jme->dev->last_rx = jiffies;
NET_STAT(jme).rx_bytes += framesize;
++(NET_STAT(jme).rx_packets);
}
@@ -2861,18 +2860,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;
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index e18576316bd..63626953f07 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -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;
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index 977ed3401bb..e81b6113ed9 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -359,7 +359,7 @@ int __init init_module(void)
static void cleanup_card(struct net_device *dev)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
if (dev->dma != 4)
free_dma(dev->dma);
release_region(dev->base_addr, LANCE_TOTAL_SIZE);
@@ -418,7 +418,7 @@ static int __init do_lance_probe(struct net_device *dev)
if (card < NUM_CARDS) { /*Signature OK*/
result = lance_probe1(dev, ioaddr, 0, 0);
if (!result) {
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
int ver = lp->chip_version;
r->name = chip_table[ver].name;
@@ -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. */
@@ -538,7 +537,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
if(lp==NULL)
return -ENODEV;
if (lance_debug > 6) printk(" (#0x%05lx)", (unsigned long)lp);
- dev->priv = lp;
+ dev->ml_priv = lp;
lp->name = chipname;
lp->rx_buffs = (unsigned long)kmalloc(PKT_BUF_SZ*RX_RING_SIZE,
GFP_DMA | GFP_KERNEL);
@@ -742,7 +741,7 @@ out_lp:
static int
lance_open(struct net_device *dev)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
int ioaddr = dev->base_addr;
int i;
@@ -830,7 +829,7 @@ lance_open(struct net_device *dev)
static void
lance_purge_ring(struct net_device *dev)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
int i;
/* Free all the skbuffs in the Rx and Tx queues. */
@@ -854,7 +853,7 @@ lance_purge_ring(struct net_device *dev)
static void
lance_init_ring(struct net_device *dev, gfp_t gfp)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
int i;
lp->cur_rx = lp->cur_tx = 0;
@@ -896,7 +895,7 @@ lance_init_ring(struct net_device *dev, gfp_t gfp)
static void
lance_restart(struct net_device *dev, unsigned int csr0_bits, int must_reinit)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
if (must_reinit ||
(chip_table[lp->chip_version].flags & LANCE_MUST_REINIT_RING)) {
@@ -910,7 +909,7 @@ lance_restart(struct net_device *dev, unsigned int csr0_bits, int must_reinit)
static void lance_tx_timeout (struct net_device *dev)
{
- struct lance_private *lp = (struct lance_private *) dev->priv;
+ struct lance_private *lp = (struct lance_private *) dev->ml_priv;
int ioaddr = dev->base_addr;
outw (0, ioaddr + LANCE_ADDR);
@@ -944,7 +943,7 @@ static void lance_tx_timeout (struct net_device *dev)
static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
int ioaddr = dev->base_addr;
int entry;
unsigned long flags;
@@ -1021,7 +1020,7 @@ static irqreturn_t lance_interrupt(int irq, void *dev_id)
int must_restart;
ioaddr = dev->base_addr;
- lp = dev->priv;
+ lp = dev->ml_priv;
spin_lock (&lp->devlock);
@@ -1134,7 +1133,7 @@ static irqreturn_t lance_interrupt(int irq, void *dev_id)
static int
lance_rx(struct net_device *dev)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
int entry = lp->cur_rx & RX_RING_MOD_MASK;
int i;
@@ -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;
}
@@ -1213,7 +1211,7 @@ static int
lance_close(struct net_device *dev)
{
int ioaddr = dev->base_addr;
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
netif_stop_queue (dev);
@@ -1246,7 +1244,7 @@ lance_close(struct net_device *dev)
static struct net_device_stats *lance_get_stats(struct net_device *dev)
{
- struct lance_private *lp = dev->priv;
+ struct lance_private *lp = dev->ml_priv;
if (chip_table[lp->chip_version].flags & LANCE_HAS_MISSED_FRAME) {
short ioaddr = dev->base_addr;
diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c
index b59f442bbf3..7415f517491 100644
--- a/drivers/net/lib82596.c
+++ b/drivers/net/lib82596.c
@@ -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);
diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c
index f80dcc11fe2..9430167a3b1 100644
--- a/drivers/net/lib8390.c
+++ b/drivers/net/lib8390.c
@@ -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)
diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c
index b3698909788..bc70d5e79ab 100644
--- a/drivers/net/lne390.c
+++ b/drivers/net/lne390.c
@@ -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: ");
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index b1ac63ab8c1..958450124de 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -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());
@@ -89,7 +87,7 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
-static struct net_device_stats *get_stats(struct net_device *dev)
+static struct net_device_stats *loopback_get_stats(struct net_device *dev)
{
const struct pcpu_lstats *pcpu_lstats;
struct net_device_stats *stats = &dev->stats;
@@ -145,13 +143,17 @@ static void loopback_dev_free(struct net_device *dev)
free_netdev(dev);
}
+static const struct net_device_ops loopback_ops = {
+ .ndo_init = loopback_dev_init,
+ .ndo_get_stats = loopback_get_stats,
+};
+
/*
* The loopback device is special. There is only one instance
* per network namespace.
*/
static void loopback_setup(struct net_device *dev)
{
- dev->get_stats = &get_stats;
dev->mtu = (16 * 1024) + 20 + 20 + 12;
dev->hard_start_xmit = loopback_xmit;
dev->hard_header_len = ETH_HLEN; /* 14 */
@@ -167,8 +169,8 @@ static void loopback_setup(struct net_device *dev)
| NETIF_F_NETNS_LOCAL;
dev->ethtool_ops = &loopback_ethtool_ops;
dev->header_ops = &eth_header_ops;
- dev->init = loopback_dev_init;
- dev->destructor = loopback_dev_free;
+ dev->netdev_ops = &loopback_ops;
+ dev->destructor = loopback_dev_free;
}
/* Setup and register the loopback device. */
@@ -206,17 +208,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);
diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c
index 83fa9d82a00..4d1a059921c 100644
--- a/drivers/net/lp486e.c
+++ b/drivers/net/lp486e.c
@@ -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)
diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c
index 4ce8afd481c..2ee477c84b0 100644
--- a/drivers/net/mac89x0.c
+++ b/drivers/net/mac89x0.c
@@ -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;
}
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 01f7a31bac7..261b9507124 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -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] "
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index 451acdca2a2..feebbd92aff 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -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;
}
diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c
index 85587a6667b..274e99bb63a 100644
--- a/drivers/net/macmace.c
+++ b/drivers/net/macmace.c
@@ -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;
}
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index e64c2086d33..205bb05c25d 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -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;
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 42394505bb5..d00ea444e0a 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -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,23 +331,52 @@ 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 const struct net_device_ops macvlan_netdev_ops = {
+ .ndo_init = macvlan_init,
+ .ndo_open = macvlan_open,
+ .ndo_stop = macvlan_stop,
+ .ndo_change_mtu = macvlan_change_mtu,
+ .ndo_change_rx_flags = macvlan_change_rx_flags,
+ .ndo_set_mac_address = macvlan_set_mac_address,
+ .ndo_set_multicast_list = macvlan_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
};
static void macvlan_setup(struct net_device *dev)
{
ether_setup(dev);
- dev->init = macvlan_init;
- dev->open = macvlan_open;
- dev->stop = macvlan_stop;
- dev->change_mtu = macvlan_change_mtu;
- dev->change_rx_flags = macvlan_change_rx_flags;
- dev->set_mac_address = macvlan_set_mac_address;
- dev->set_multicast_list = macvlan_set_multicast_list;
+ dev->netdev_ops = &macvlan_netdev_ops;
dev->hard_start_xmit = macvlan_hard_start_xmit;
dev->destructor = free_netdev;
dev->header_ops = &macvlan_hard_header_ops,
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index a1e22ed1f6e..c336a1f4251 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -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);
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index 6232227f56c..944ad47c951 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -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;
diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c
index 592c01ae2c5..b1622062b12 100644
--- a/drivers/net/mlx4/mcg.c
+++ b/drivers/net/mlx4/mcg.c
@@ -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;
}
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
index 98ddc0811f9..24f6d2585a6 100644
--- a/drivers/net/mlx4/mlx4_en.h
+++ b/drivers/net/mlx4/mlx4_en.h
@@ -58,17 +58,17 @@
#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
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index e513f76f2a9..7253a499d9c 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -51,8 +51,8 @@
#include <linux/workqueue.h>
#include <linux/phy.h>
#include <linux/mv643xx_eth.h>
-#include <asm/io.h>
-#include <asm/types.h>
+#include <linux/io.h>
+#include <linux/types.h>
#include <asm/system.h>
static char mv643xx_eth_driver_name[] = "mv643xx_eth";
@@ -78,16 +78,17 @@ static char mv643xx_eth_driver_version[] = "1.4";
#define WINDOW_PROTECT(w) (0x0294 + ((w) << 4))
/*
- * Per-port registers.
+ * Main per-port registers. These live at offset 0x0400 for
+ * port #0, 0x0800 for port #1, and 0x0c00 for port #2.
*/
-#define PORT_CONFIG(p) (0x0400 + ((p) << 10))
+#define PORT_CONFIG 0x0000
#define UNICAST_PROMISCUOUS_MODE 0x00000001
-#define PORT_CONFIG_EXT(p) (0x0404 + ((p) << 10))
-#define MAC_ADDR_LOW(p) (0x0414 + ((p) << 10))
-#define MAC_ADDR_HIGH(p) (0x0418 + ((p) << 10))
-#define SDMA_CONFIG(p) (0x041c + ((p) << 10))
-#define PORT_SERIAL_CONTROL(p) (0x043c + ((p) << 10))
-#define PORT_STATUS(p) (0x0444 + ((p) << 10))
+#define PORT_CONFIG_EXT 0x0004
+#define MAC_ADDR_LOW 0x0014
+#define MAC_ADDR_HIGH 0x0018
+#define SDMA_CONFIG 0x001c
+#define PORT_SERIAL_CONTROL 0x003c
+#define PORT_STATUS 0x0044
#define TX_FIFO_EMPTY 0x00000400
#define TX_IN_PROGRESS 0x00000080
#define PORT_SPEED_MASK 0x00000030
@@ -97,31 +98,35 @@ static char mv643xx_eth_driver_version[] = "1.4";
#define FLOW_CONTROL_ENABLED 0x00000008
#define FULL_DUPLEX 0x00000004
#define LINK_UP 0x00000002
-#define TXQ_COMMAND(p) (0x0448 + ((p) << 10))
-#define TXQ_FIX_PRIO_CONF(p) (0x044c + ((p) << 10))
-#define TX_BW_RATE(p) (0x0450 + ((p) << 10))
-#define TX_BW_MTU(p) (0x0458 + ((p) << 10))
-#define TX_BW_BURST(p) (0x045c + ((p) << 10))
-#define INT_CAUSE(p) (0x0460 + ((p) << 10))
+#define TXQ_COMMAND 0x0048
+#define TXQ_FIX_PRIO_CONF 0x004c
+#define TX_BW_RATE 0x0050
+#define TX_BW_MTU 0x0058
+#define TX_BW_BURST 0x005c
+#define INT_CAUSE 0x0060
#define INT_TX_END 0x07f80000
#define INT_RX 0x000003fc
#define INT_EXT 0x00000002
-#define INT_CAUSE_EXT(p) (0x0464 + ((p) << 10))
+#define INT_CAUSE_EXT 0x0064
#define INT_EXT_LINK_PHY 0x00110000
#define INT_EXT_TX 0x000000ff
-#define INT_MASK(p) (0x0468 + ((p) << 10))
-#define INT_MASK_EXT(p) (0x046c + ((p) << 10))
-#define TX_FIFO_URGENT_THRESHOLD(p) (0x0474 + ((p) << 10))
-#define TXQ_FIX_PRIO_CONF_MOVED(p) (0x04dc + ((p) << 10))
-#define TX_BW_RATE_MOVED(p) (0x04e0 + ((p) << 10))
-#define TX_BW_MTU_MOVED(p) (0x04e8 + ((p) << 10))
-#define TX_BW_BURST_MOVED(p) (0x04ec + ((p) << 10))
-#define RXQ_CURRENT_DESC_PTR(p, q) (0x060c + ((p) << 10) + ((q) << 4))
-#define RXQ_COMMAND(p) (0x0680 + ((p) << 10))
-#define TXQ_CURRENT_DESC_PTR(p, q) (0x06c0 + ((p) << 10) + ((q) << 2))
-#define TXQ_BW_TOKENS(p, q) (0x0700 + ((p) << 10) + ((q) << 4))
-#define TXQ_BW_CONF(p, q) (0x0704 + ((p) << 10) + ((q) << 4))
-#define TXQ_BW_WRR_CONF(p, q) (0x0708 + ((p) << 10) + ((q) << 4))
+#define INT_MASK 0x0068
+#define INT_MASK_EXT 0x006c
+#define TX_FIFO_URGENT_THRESHOLD 0x0074
+#define TXQ_FIX_PRIO_CONF_MOVED 0x00dc
+#define TX_BW_RATE_MOVED 0x00e0
+#define TX_BW_MTU_MOVED 0x00e8
+#define TX_BW_BURST_MOVED 0x00ec
+#define RXQ_CURRENT_DESC_PTR(q) (0x020c + ((q) << 4))
+#define RXQ_COMMAND 0x0280
+#define TXQ_CURRENT_DESC_PTR(q) (0x02c0 + ((q) << 2))
+#define TXQ_BW_TOKENS(q) (0x0300 + ((q) << 4))
+#define TXQ_BW_CONF(q) (0x0304 + ((q) << 4))
+#define TXQ_BW_WRR_CONF(q) (0x0308 + ((q) << 4))
+
+/*
+ * Misc per-port registers.
+ */
#define MIB_COUNTERS(p) (0x1000 + ((p) << 7))
#define SPECIAL_MCAST_TABLE(p) (0x1400 + ((p) << 10))
#define OTHER_MCAST_TABLE(p) (0x1500 + ((p) << 10))
@@ -138,14 +143,14 @@ static char mv643xx_eth_driver_version[] = "1.4";
#if defined(__BIG_ENDIAN)
#define PORT_SDMA_CONFIG_DEFAULT_VALUE \
- RX_BURST_SIZE_16_64BIT | \
- TX_BURST_SIZE_16_64BIT
+ (RX_BURST_SIZE_16_64BIT | \
+ TX_BURST_SIZE_16_64BIT)
#elif defined(__LITTLE_ENDIAN)
#define PORT_SDMA_CONFIG_DEFAULT_VALUE \
- RX_BURST_SIZE_16_64BIT | \
+ (RX_BURST_SIZE_16_64BIT | \
BLM_RX_NO_SWAP | \
BLM_TX_NO_SWAP | \
- TX_BURST_SIZE_16_64BIT
+ TX_BURST_SIZE_16_64BIT)
#else
#error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
#endif
@@ -351,6 +356,7 @@ struct tx_queue {
struct mv643xx_eth_private {
struct mv643xx_eth_shared_private *shared;
+ void __iomem *base;
int port_num;
struct net_device *dev;
@@ -401,11 +407,21 @@ static inline u32 rdl(struct mv643xx_eth_private *mp, int offset)
return readl(mp->shared->base + offset);
}
+static inline u32 rdlp(struct mv643xx_eth_private *mp, int offset)
+{
+ return readl(mp->base + offset);
+}
+
static inline void wrl(struct mv643xx_eth_private *mp, int offset, u32 data)
{
writel(data, mp->shared->base + offset);
}
+static inline void wrlp(struct mv643xx_eth_private *mp, int offset, u32 data)
+{
+ writel(data, mp->base + offset);
+}
+
/* rxq/txq helper functions *************************************************/
static struct mv643xx_eth_private *rxq_to_mp(struct rx_queue *rxq)
@@ -421,7 +437,7 @@ static struct mv643xx_eth_private *txq_to_mp(struct tx_queue *txq)
static void rxq_enable(struct rx_queue *rxq)
{
struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
- wrl(mp, RXQ_COMMAND(mp->port_num), 1 << rxq->index);
+ wrlp(mp, RXQ_COMMAND, 1 << rxq->index);
}
static void rxq_disable(struct rx_queue *rxq)
@@ -429,26 +445,25 @@ static void rxq_disable(struct rx_queue *rxq)
struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
u8 mask = 1 << rxq->index;
- wrl(mp, RXQ_COMMAND(mp->port_num), mask << 8);
- while (rdl(mp, RXQ_COMMAND(mp->port_num)) & mask)
+ wrlp(mp, RXQ_COMMAND, mask << 8);
+ while (rdlp(mp, RXQ_COMMAND) & mask)
udelay(10);
}
static void txq_reset_hw_ptr(struct tx_queue *txq)
{
struct mv643xx_eth_private *mp = txq_to_mp(txq);
- int off = TXQ_CURRENT_DESC_PTR(mp->port_num, txq->index);
u32 addr;
addr = (u32)txq->tx_desc_dma;
addr += txq->tx_curr_desc * sizeof(struct tx_desc);
- wrl(mp, off, addr);
+ wrlp(mp, TXQ_CURRENT_DESC_PTR(txq->index), addr);
}
static void txq_enable(struct tx_queue *txq)
{
struct mv643xx_eth_private *mp = txq_to_mp(txq);
- wrl(mp, TXQ_COMMAND(mp->port_num), 1 << txq->index);
+ wrlp(mp, TXQ_COMMAND, 1 << txq->index);
}
static void txq_disable(struct tx_queue *txq)
@@ -456,8 +471,8 @@ static void txq_disable(struct tx_queue *txq)
struct mv643xx_eth_private *mp = txq_to_mp(txq);
u8 mask = 1 << txq->index;
- wrl(mp, TXQ_COMMAND(mp->port_num), mask << 8);
- while (rdl(mp, TXQ_COMMAND(mp->port_num)) & mask)
+ wrlp(mp, TXQ_COMMAND, mask << 8);
+ while (rdlp(mp, TXQ_COMMAND) & mask)
udelay(10);
}
@@ -528,37 +543,38 @@ static int rxq_process(struct rx_queue *rxq, int budget)
* on, or the error summary bit is set, the packet needs
* to be dropped.
*/
- if (((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
- (RX_FIRST_DESC | RX_LAST_DESC))
- || (cmd_sts & ERROR_SUMMARY)) {
- stats->rx_dropped++;
-
- if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
- (RX_FIRST_DESC | RX_LAST_DESC)) {
- if (net_ratelimit())
- dev_printk(KERN_ERR, &mp->dev->dev,
- "received packet spanning "
- "multiple descriptors\n");
- }
+ if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC | ERROR_SUMMARY))
+ != (RX_FIRST_DESC | RX_LAST_DESC))
+ goto err;
- if (cmd_sts & ERROR_SUMMARY)
- stats->rx_errors++;
+ /*
+ * The -4 is for the CRC in the trailer of the
+ * received packet
+ */
+ skb_put(skb, byte_cnt - 2 - 4);
- dev_kfree_skb(skb);
- } else {
- /*
- * The -4 is for the CRC in the trailer of the
- * received packet
- */
- skb_put(skb, byte_cnt - 2 - 4);
-
- if (cmd_sts & LAYER_4_CHECKSUM_OK)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- skb->protocol = eth_type_trans(skb, mp->dev);
- netif_receive_skb(skb);
+ if (cmd_sts & LAYER_4_CHECKSUM_OK)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ skb->protocol = eth_type_trans(skb, mp->dev);
+ netif_receive_skb(skb);
+
+ continue;
+
+err:
+ stats->rx_dropped++;
+
+ if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
+ (RX_FIRST_DESC | RX_LAST_DESC)) {
+ if (net_ratelimit())
+ dev_printk(KERN_ERR, &mp->dev->dev,
+ "received packet spanning "
+ "multiple descriptors\n");
}
- mp->dev->last_rx = jiffies;
+ if (cmd_sts & ERROR_SUMMARY)
+ stats->rx_errors++;
+
+ dev_kfree_skb(skb);
}
if (rx < budget)
@@ -577,6 +593,7 @@ static int rxq_refill(struct rx_queue *rxq, int budget)
struct sk_buff *skb;
int unaligned;
int rx;
+ struct rx_desc *rx_desc;
skb = __skb_dequeue(&mp->rx_recycle);
if (skb == NULL)
@@ -599,13 +616,14 @@ static int rxq_refill(struct rx_queue *rxq, int budget)
if (rxq->rx_used_desc == rxq->rx_ring_size)
rxq->rx_used_desc = 0;
- rxq->rx_desc_area[rx].buf_ptr = dma_map_single(NULL, skb->data,
- mp->skb_size, DMA_FROM_DEVICE);
- rxq->rx_desc_area[rx].buf_size = mp->skb_size;
+ rx_desc = rxq->rx_desc_area + rx;
+
+ rx_desc->buf_ptr = dma_map_single(NULL, skb->data,
+ mp->skb_size, DMA_FROM_DEVICE);
+ rx_desc->buf_size = mp->skb_size;
rxq->rx_skb[rx] = skb;
wmb();
- rxq->rx_desc_area[rx].cmd_sts = BUFFER_OWNED_BY_DMA |
- RX_ENABLE_INTERRUPT;
+ rx_desc->cmd_sts = BUFFER_OWNED_BY_DMA | RX_ENABLE_INTERRUPT;
wmb();
/*
@@ -638,21 +656,6 @@ static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb)
return 0;
}
-static int txq_alloc_desc_index(struct tx_queue *txq)
-{
- int tx_desc_curr;
-
- BUG_ON(txq->tx_desc_count >= txq->tx_ring_size);
-
- tx_desc_curr = txq->tx_curr_desc++;
- if (txq->tx_curr_desc == txq->tx_ring_size)
- txq->tx_curr_desc = 0;
-
- BUG_ON(txq->tx_curr_desc == txq->tx_used_desc);
-
- return tx_desc_curr;
-}
-
static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb)
{
int nr_frags = skb_shinfo(skb)->nr_frags;
@@ -664,7 +667,9 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb)
struct tx_desc *desc;
this_frag = &skb_shinfo(skb)->frags[frag];
- tx_index = txq_alloc_desc_index(txq);
+ tx_index = txq->tx_curr_desc++;
+ if (txq->tx_curr_desc == txq->tx_ring_size)
+ txq->tx_curr_desc = 0;
desc = &txq->tx_desc_area[tx_index];
/*
@@ -746,7 +751,9 @@ no_csum:
cmd_sts |= 5 << TX_IHL_SHIFT;
}
- tx_index = txq_alloc_desc_index(txq);
+ tx_index = txq->tx_curr_desc++;
+ if (txq->tx_curr_desc == txq->tx_ring_size)
+ txq->tx_curr_desc = 0;
desc = &txq->tx_desc_area[tx_index];
if (nr_frags) {
@@ -831,10 +838,10 @@ static void txq_kick(struct tx_queue *txq)
__netif_tx_lock(nq, smp_processor_id());
- if (rdl(mp, TXQ_COMMAND(mp->port_num)) & (1 << txq->index))
+ if (rdlp(mp, TXQ_COMMAND) & (1 << txq->index))
goto out;
- hw_desc_ptr = rdl(mp, TXQ_CURRENT_DESC_PTR(mp->port_num, txq->index));
+ hw_desc_ptr = rdlp(mp, TXQ_CURRENT_DESC_PTR(txq->index));
expected_ptr = (u32)txq->tx_desc_dma +
txq->tx_curr_desc * sizeof(struct tx_desc);
@@ -941,14 +948,14 @@ static void tx_set_rate(struct mv643xx_eth_private *mp, int rate, int burst)
switch (mp->shared->tx_bw_control) {
case TX_BW_CONTROL_OLD_LAYOUT:
- wrl(mp, TX_BW_RATE(mp->port_num), token_rate);
- wrl(mp, TX_BW_MTU(mp->port_num), mtu);
- wrl(mp, TX_BW_BURST(mp->port_num), bucket_size);
+ wrlp(mp, TX_BW_RATE, token_rate);
+ wrlp(mp, TX_BW_MTU, mtu);
+ wrlp(mp, TX_BW_BURST, bucket_size);
break;
case TX_BW_CONTROL_NEW_LAYOUT:
- wrl(mp, TX_BW_RATE_MOVED(mp->port_num), token_rate);
- wrl(mp, TX_BW_MTU_MOVED(mp->port_num), mtu);
- wrl(mp, TX_BW_BURST_MOVED(mp->port_num), bucket_size);
+ wrlp(mp, TX_BW_RATE_MOVED, token_rate);
+ wrlp(mp, TX_BW_MTU_MOVED, mtu);
+ wrlp(mp, TX_BW_BURST_MOVED, bucket_size);
break;
}
}
@@ -967,9 +974,8 @@ static void txq_set_rate(struct tx_queue *txq, int rate, int burst)
if (bucket_size > 65535)
bucket_size = 65535;
- wrl(mp, TXQ_BW_TOKENS(mp->port_num, txq->index), token_rate << 14);
- wrl(mp, TXQ_BW_CONF(mp->port_num, txq->index),
- (bucket_size << 10) | token_rate);
+ wrlp(mp, TXQ_BW_TOKENS(txq->index), token_rate << 14);
+ wrlp(mp, TXQ_BW_CONF(txq->index), (bucket_size << 10) | token_rate);
}
static void txq_set_fixed_prio_mode(struct tx_queue *txq)
@@ -984,17 +990,17 @@ static void txq_set_fixed_prio_mode(struct tx_queue *txq)
off = 0;
switch (mp->shared->tx_bw_control) {
case TX_BW_CONTROL_OLD_LAYOUT:
- off = TXQ_FIX_PRIO_CONF(mp->port_num);
+ off = TXQ_FIX_PRIO_CONF;
break;
case TX_BW_CONTROL_NEW_LAYOUT:
- off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num);
+ off = TXQ_FIX_PRIO_CONF_MOVED;
break;
}
if (off) {
- val = rdl(mp, off);
+ val = rdlp(mp, off);
val |= 1 << txq->index;
- wrl(mp, off, val);
+ wrlp(mp, off, val);
}
}
@@ -1010,26 +1016,25 @@ static void txq_set_wrr(struct tx_queue *txq, int weight)
off = 0;
switch (mp->shared->tx_bw_control) {
case TX_BW_CONTROL_OLD_LAYOUT:
- off = TXQ_FIX_PRIO_CONF(mp->port_num);
+ off = TXQ_FIX_PRIO_CONF;
break;
case TX_BW_CONTROL_NEW_LAYOUT:
- off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num);
+ off = TXQ_FIX_PRIO_CONF_MOVED;
break;
}
if (off) {
- val = rdl(mp, off);
+ val = rdlp(mp, off);
val &= ~(1 << txq->index);
- wrl(mp, off, val);
+ wrlp(mp, off, val);
/*
* Configure WRR weight for this queue.
*/
- off = TXQ_BW_WRR_CONF(mp->port_num, txq->index);
- val = rdl(mp, off);
+ val = rdlp(mp, off);
val = (val & ~0xff) | (weight & 0xff);
- wrl(mp, off, val);
+ wrlp(mp, TXQ_BW_WRR_CONF(txq->index), val);
}
}
@@ -1084,20 +1089,20 @@ static int smi_bus_read(struct mii_bus *bus, int addr, int reg)
int ret;
if (smi_wait_ready(msp)) {
- printk("mv643xx_eth: SMI bus busy timeout\n");
+ printk(KERN_WARNING "mv643xx_eth: SMI bus busy timeout\n");
return -ETIMEDOUT;
}
writel(SMI_OPCODE_READ | (reg << 21) | (addr << 16), smi_reg);
if (smi_wait_ready(msp)) {
- printk("mv643xx_eth: SMI bus busy timeout\n");
+ printk(KERN_WARNING "mv643xx_eth: SMI bus busy timeout\n");
return -ETIMEDOUT;
}
ret = readl(smi_reg);
if (!(ret & SMI_READ_VALID)) {
- printk("mv643xx_eth: SMI bus read not valid\n");
+ printk(KERN_WARNING "mv643xx_eth: SMI bus read not valid\n");
return -ENODEV;
}
@@ -1110,7 +1115,7 @@ static int smi_bus_write(struct mii_bus *bus, int addr, int reg, u16 val)
void __iomem *smi_reg = msp->base + SMI_REG;
if (smi_wait_ready(msp)) {
- printk("mv643xx_eth: SMI bus busy timeout\n");
+ printk(KERN_WARNING "mv643xx_eth: SMI bus busy timeout\n");
return -ETIMEDOUT;
}
@@ -1118,7 +1123,7 @@ static int smi_bus_write(struct mii_bus *bus, int addr, int reg, u16 val)
(addr << 16) | (val & 0xffff), smi_reg);
if (smi_wait_ready(msp)) {
- printk("mv643xx_eth: SMI bus busy timeout\n");
+ printk(KERN_WARNING "mv643xx_eth: SMI bus busy timeout\n");
return -ETIMEDOUT;
}
@@ -1271,7 +1276,8 @@ static const struct mv643xx_eth_stats mv643xx_eth_stats[] = {
MIBSTAT(late_collision),
};
-static int mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+static int
+mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct mv643xx_eth_private *mp = netdev_priv(dev);
int err;
@@ -1289,12 +1295,14 @@ static int mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *
return err;
}
-static int mv643xx_eth_get_settings_phyless(struct net_device *dev, struct ethtool_cmd *cmd)
+static int
+mv643xx_eth_get_settings_phyless(struct net_device *dev,
+ struct ethtool_cmd *cmd)
{
struct mv643xx_eth_private *mp = netdev_priv(dev);
u32 port_status;
- port_status = rdl(mp, PORT_STATUS(mp->port_num));
+ port_status = rdlp(mp, PORT_STATUS);
cmd->supported = SUPPORTED_MII;
cmd->advertising = ADVERTISED_MII;
@@ -1323,7 +1331,8 @@ static int mv643xx_eth_get_settings_phyless(struct net_device *dev, struct ethto
return 0;
}
-static int mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+static int
+mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct mv643xx_eth_private *mp = netdev_priv(dev);
@@ -1335,7 +1344,9 @@ static int mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *
return phy_ethtool_sset(mp->phy, cmd);
}
-static int mv643xx_eth_set_settings_phyless(struct net_device *dev, struct ethtool_cmd *cmd)
+static int
+mv643xx_eth_set_settings_phyless(struct net_device *dev,
+ struct ethtool_cmd *cmd)
{
return -EINVAL;
}
@@ -1443,11 +1454,8 @@ static const struct ethtool_ops mv643xx_eth_ethtool_ops_phyless = {
/* address handling *********************************************************/
static void uc_addr_get(struct mv643xx_eth_private *mp, unsigned char *addr)
{
- unsigned int mac_h;
- unsigned int mac_l;
-
- mac_h = rdl(mp, MAC_ADDR_HIGH(mp->port_num));
- mac_l = rdl(mp, MAC_ADDR_LOW(mp->port_num));
+ unsigned int mac_h = rdlp(mp, MAC_ADDR_HIGH);
+ unsigned int mac_l = rdlp(mp, MAC_ADDR_LOW);
addr[0] = (mac_h >> 24) & 0xff;
addr[1] = (mac_h >> 16) & 0xff;
@@ -1457,57 +1465,71 @@ static void uc_addr_get(struct mv643xx_eth_private *mp, unsigned char *addr)
addr[5] = mac_l & 0xff;
}
-static void init_mac_tables(struct mv643xx_eth_private *mp)
+static void uc_addr_set(struct mv643xx_eth_private *mp, unsigned char *addr)
{
- int i;
-
- for (i = 0; i < 0x100; i += 4) {
- wrl(mp, SPECIAL_MCAST_TABLE(mp->port_num) + i, 0);
- wrl(mp, OTHER_MCAST_TABLE(mp->port_num) + i, 0);
- }
-
- for (i = 0; i < 0x10; i += 4)
- wrl(mp, UNICAST_TABLE(mp->port_num) + i, 0);
+ wrlp(mp, MAC_ADDR_HIGH,
+ (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3]);
+ wrlp(mp, MAC_ADDR_LOW, (addr[4] << 8) | addr[5]);
}
-static void set_filter_table_entry(struct mv643xx_eth_private *mp,
- int table, unsigned char entry)
+static u32 uc_addr_filter_mask(struct net_device *dev)
{
- unsigned int table_reg;
-
- /* Set "accepts frame bit" at specified table entry */
- table_reg = rdl(mp, table + (entry & 0xfc));
- table_reg |= 0x01 << (8 * (entry & 3));
- wrl(mp, table + (entry & 0xfc), table_reg);
-}
+ struct dev_addr_list *uc_ptr;
+ u32 nibbles;
-static void uc_addr_set(struct mv643xx_eth_private *mp, unsigned char *addr)
-{
- unsigned int mac_h;
- unsigned int mac_l;
- int table;
+ if (dev->flags & IFF_PROMISC)
+ return 0;
- mac_l = (addr[4] << 8) | addr[5];
- mac_h = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
+ nibbles = 1 << (dev->dev_addr[5] & 0x0f);
+ for (uc_ptr = dev->uc_list; uc_ptr != NULL; uc_ptr = uc_ptr->next) {
+ if (memcmp(dev->dev_addr, uc_ptr->da_addr, 5))
+ return 0;
+ if ((dev->dev_addr[5] ^ uc_ptr->da_addr[5]) & 0xf0)
+ return 0;
- wrl(mp, MAC_ADDR_LOW(mp->port_num), mac_l);
- wrl(mp, MAC_ADDR_HIGH(mp->port_num), mac_h);
+ nibbles |= 1 << (uc_ptr->da_addr[5] & 0x0f);
+ }
- table = UNICAST_TABLE(mp->port_num);
- set_filter_table_entry(mp, table, addr[5] & 0x0f);
+ return nibbles;
}
-static int mv643xx_eth_set_mac_address(struct net_device *dev, void *addr)
+static void mv643xx_eth_program_unicast_filter(struct net_device *dev)
{
struct mv643xx_eth_private *mp = netdev_priv(dev);
+ u32 port_config;
+ u32 nibbles;
+ int i;
- /* +2 is for the offset of the HW addr type */
- memcpy(dev->dev_addr, addr + 2, 6);
-
- init_mac_tables(mp);
uc_addr_set(mp, dev->dev_addr);
- return 0;
+ port_config = rdlp(mp, PORT_CONFIG);
+ nibbles = uc_addr_filter_mask(dev);
+ if (!nibbles) {
+ port_config |= UNICAST_PROMISCUOUS_MODE;
+ wrlp(mp, PORT_CONFIG, port_config);
+ return;
+ }
+
+ for (i = 0; i < 16; i += 4) {
+ int off = UNICAST_TABLE(mp->port_num) + i;
+ u32 v;
+
+ v = 0;
+ if (nibbles & 1)
+ v |= 0x00000001;
+ if (nibbles & 2)
+ v |= 0x00000100;
+ if (nibbles & 4)
+ v |= 0x00010000;
+ if (nibbles & 8)
+ v |= 0x01000000;
+ nibbles >>= 4;
+
+ wrl(mp, off, v);
+ }
+
+ port_config &= ~UNICAST_PROMISCUOUS_MODE;
+ wrlp(mp, PORT_CONFIG, port_config);
}
static int addr_crc(unsigned char *addr)
@@ -1528,24 +1550,22 @@ static int addr_crc(unsigned char *addr)
return crc;
}
-static void mv643xx_eth_set_rx_mode(struct net_device *dev)
+static void mv643xx_eth_program_multicast_filter(struct net_device *dev)
{
struct mv643xx_eth_private *mp = netdev_priv(dev);
- u32 port_config;
+ u32 *mc_spec;
+ u32 *mc_other;
struct dev_addr_list *addr;
int i;
- port_config = rdl(mp, PORT_CONFIG(mp->port_num));
- if (dev->flags & IFF_PROMISC)
- port_config |= UNICAST_PROMISCUOUS_MODE;
- else
- port_config &= ~UNICAST_PROMISCUOUS_MODE;
- wrl(mp, PORT_CONFIG(mp->port_num), port_config);
-
if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
- int port_num = mp->port_num;
- u32 accept = 0x01010101;
+ int port_num;
+ u32 accept;
+ int i;
+oom:
+ port_num = mp->port_num;
+ accept = 0x01010101;
for (i = 0; i < 0x100; i += 4) {
wrl(mp, SPECIAL_MCAST_TABLE(port_num) + i, accept);
wrl(mp, OTHER_MCAST_TABLE(port_num) + i, accept);
@@ -1553,28 +1573,55 @@ static void mv643xx_eth_set_rx_mode(struct net_device *dev)
return;
}
- for (i = 0; i < 0x100; i += 4) {
- wrl(mp, SPECIAL_MCAST_TABLE(mp->port_num) + i, 0);
- wrl(mp, OTHER_MCAST_TABLE(mp->port_num) + i, 0);
- }
+ mc_spec = kmalloc(0x200, GFP_KERNEL);
+ if (mc_spec == NULL)
+ goto oom;
+ mc_other = mc_spec + (0x100 >> 2);
+
+ memset(mc_spec, 0, 0x100);
+ memset(mc_other, 0, 0x100);
for (addr = dev->mc_list; addr != NULL; addr = addr->next) {
u8 *a = addr->da_addr;
- int table;
-
- if (addr->da_addrlen != 6)
- continue;
+ u32 *table;
+ int entry;
if (memcmp(a, "\x01\x00\x5e\x00\x00", 5) == 0) {
- table = SPECIAL_MCAST_TABLE(mp->port_num);
- set_filter_table_entry(mp, table, a[5]);
+ table = mc_spec;
+ entry = a[5];
} else {
- int crc = addr_crc(a);
-
- table = OTHER_MCAST_TABLE(mp->port_num);
- set_filter_table_entry(mp, table, crc);
+ table = mc_other;
+ entry = addr_crc(a);
}
+
+ table[entry >> 2] |= 1 << (entry & 3);
}
+
+ for (i = 0; i < 0x100; i += 4) {
+ wrl(mp, SPECIAL_MCAST_TABLE(mp->port_num) + i, mc_spec[i >> 2]);
+ wrl(mp, OTHER_MCAST_TABLE(mp->port_num) + i, mc_other[i >> 2]);
+ }
+
+ kfree(mc_spec);
+}
+
+static void mv643xx_eth_set_rx_mode(struct net_device *dev)
+{
+ mv643xx_eth_program_unicast_filter(dev);
+ mv643xx_eth_program_multicast_filter(dev);
+}
+
+static int mv643xx_eth_set_mac_address(struct net_device *dev, void *addr)
+{
+ struct sockaddr *sa = addr;
+
+ memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN);
+
+ netif_addr_lock_bh(dev);
+ mv643xx_eth_program_unicast_filter(dev);
+ netif_addr_unlock_bh(dev);
+
+ return 0;
}
@@ -1758,26 +1805,25 @@ static int mv643xx_eth_collect_events(struct mv643xx_eth_private *mp)
u32 int_cause;
u32 int_cause_ext;
- int_cause = rdl(mp, INT_CAUSE(mp->port_num)) &
- (INT_TX_END | INT_RX | INT_EXT);
+ int_cause = rdlp(mp, INT_CAUSE) & (INT_TX_END | INT_RX | INT_EXT);
if (int_cause == 0)
return 0;
int_cause_ext = 0;
if (int_cause & INT_EXT)
- int_cause_ext = rdl(mp, INT_CAUSE_EXT(mp->port_num));
+ int_cause_ext = rdlp(mp, INT_CAUSE_EXT);
int_cause &= INT_TX_END | INT_RX;
if (int_cause) {
- wrl(mp, INT_CAUSE(mp->port_num), ~int_cause);
+ wrlp(mp, INT_CAUSE, ~int_cause);
mp->work_tx_end |= ((int_cause & INT_TX_END) >> 19) &
- ~(rdl(mp, TXQ_COMMAND(mp->port_num)) & 0xff);
+ ~(rdlp(mp, TXQ_COMMAND) & 0xff);
mp->work_rx |= (int_cause & INT_RX) >> 2;
}
int_cause_ext &= INT_EXT_LINK_PHY | INT_EXT_TX;
if (int_cause_ext) {
- wrl(mp, INT_CAUSE_EXT(mp->port_num), ~int_cause_ext);
+ wrlp(mp, INT_CAUSE_EXT, ~int_cause_ext);
if (int_cause_ext & INT_EXT_LINK_PHY)
mp->work_link = 1;
mp->work_tx |= int_cause_ext & INT_EXT_TX;
@@ -1794,7 +1840,7 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
if (unlikely(!mv643xx_eth_collect_events(mp)))
return IRQ_NONE;
- wrl(mp, INT_MASK(mp->port_num), 0);
+ wrlp(mp, INT_MASK, 0);
napi_schedule(&mp->napi);
return IRQ_HANDLED;
@@ -1808,7 +1854,7 @@ static void handle_link_event(struct mv643xx_eth_private *mp)
int duplex;
int fc;
- port_status = rdl(mp, PORT_STATUS(mp->port_num));
+ port_status = rdlp(mp, PORT_STATUS);
if (!(port_status & LINK_UP)) {
if (netif_carrier_ok(dev)) {
int i;
@@ -1908,7 +1954,7 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
if (mp->work_rx_oom)
mod_timer(&mp->rx_oom, jiffies + (HZ / 10));
napi_complete(napi);
- wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);
+ wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
}
return work_done;
@@ -1957,17 +2003,17 @@ static void port_start(struct mv643xx_eth_private *mp)
/*
* Configure basic link parameters.
*/
- pscr = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
+ pscr = rdlp(mp, PORT_SERIAL_CONTROL);
pscr |= SERIAL_PORT_ENABLE;
- wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
+ wrlp(mp, PORT_SERIAL_CONTROL, pscr);
pscr |= DO_NOT_FORCE_LINK_FAIL;
if (mp->phy == NULL)
pscr |= FORCE_LINK_PASS;
- wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
+ wrlp(mp, PORT_SERIAL_CONTROL, pscr);
- wrl(mp, SDMA_CONFIG(mp->port_num), PORT_SDMA_CONFIG_DEFAULT_VALUE);
+ wrlp(mp, SDMA_CONFIG, PORT_SDMA_CONFIG_DEFAULT_VALUE);
/*
* Configure TX path and queues.
@@ -1984,31 +2030,30 @@ static void port_start(struct mv643xx_eth_private *mp)
/*
* Add configured unicast address to address filter table.
*/
- uc_addr_set(mp, mp->dev->dev_addr);
+ mv643xx_eth_program_unicast_filter(mp->dev);
/*
* Receive all unmatched unicast, TCP, UDP, BPDU and broadcast
* frames to RX queue #0, and include the pseudo-header when
* calculating receive checksums.
*/
- wrl(mp, PORT_CONFIG(mp->port_num), 0x02000000);
+ wrlp(mp, PORT_CONFIG, 0x02000000);
/*
* Treat BPDUs as normal multicasts, and disable partition mode.
*/
- wrl(mp, PORT_CONFIG_EXT(mp->port_num), 0x00000000);
+ wrlp(mp, PORT_CONFIG_EXT, 0x00000000);
/*
* Enable the receive queues.
*/
for (i = 0; i < mp->rxq_count; i++) {
struct rx_queue *rxq = mp->rxq + i;
- int off = RXQ_CURRENT_DESC_PTR(mp->port_num, i);
u32 addr;
addr = (u32)rxq->rx_desc_dma;
addr += rxq->rx_curr_desc * sizeof(struct rx_desc);
- wrl(mp, off, addr);
+ wrlp(mp, RXQ_CURRENT_DESC_PTR(i), addr);
rxq_enable(rxq);
}
@@ -2019,7 +2064,7 @@ static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int delay)
unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64;
u32 val;
- val = rdl(mp, SDMA_CONFIG(mp->port_num));
+ val = rdlp(mp, SDMA_CONFIG);
if (mp->shared->extended_rx_coal_limit) {
if (coal > 0xffff)
coal = 0xffff;
@@ -2032,7 +2077,7 @@ static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int delay)
val &= ~0x003fff00;
val |= (coal & 0x3fff) << 8;
}
- wrl(mp, SDMA_CONFIG(mp->port_num), val);
+ wrlp(mp, SDMA_CONFIG, val);
}
static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int delay)
@@ -2041,7 +2086,7 @@ static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int delay)
if (coal > 0x3fff)
coal = 0x3fff;
- wrl(mp, TX_FIFO_URGENT_THRESHOLD(mp->port_num), (coal & 0x3fff) << 4);
+ wrlp(mp, TX_FIFO_URGENT_THRESHOLD, (coal & 0x3fff) << 4);
}
static void mv643xx_eth_recalc_skb_size(struct mv643xx_eth_private *mp)
@@ -2070,9 +2115,9 @@ static int mv643xx_eth_open(struct net_device *dev)
int err;
int i;
- wrl(mp, INT_CAUSE(mp->port_num), 0);
- wrl(mp, INT_CAUSE_EXT(mp->port_num), 0);
- rdl(mp, INT_CAUSE_EXT(mp->port_num));
+ wrlp(mp, INT_CAUSE, 0);
+ wrlp(mp, INT_CAUSE_EXT, 0);
+ rdlp(mp, INT_CAUSE_EXT);
err = request_irq(dev->irq, mv643xx_eth_irq,
IRQF_SHARED, dev->name, dev);
@@ -2081,8 +2126,6 @@ static int mv643xx_eth_open(struct net_device *dev)
return -EAGAIN;
}
- init_mac_tables(mp);
-
mv643xx_eth_recalc_skb_size(mp);
napi_enable(&mp->napi);
@@ -2121,8 +2164,8 @@ static int mv643xx_eth_open(struct net_device *dev)
set_rx_coal(mp, 0);
set_tx_coal(mp, 0);
- wrl(mp, INT_MASK_EXT(mp->port_num), INT_EXT_LINK_PHY | INT_EXT_TX);
- wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);
+ wrlp(mp, INT_MASK_EXT, INT_EXT_LINK_PHY | INT_EXT_TX);
+ wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
return 0;
@@ -2147,7 +2190,7 @@ static void port_reset(struct mv643xx_eth_private *mp)
txq_disable(mp->txq + i);
while (1) {
- u32 ps = rdl(mp, PORT_STATUS(mp->port_num));
+ u32 ps = rdlp(mp, PORT_STATUS);
if ((ps & (TX_IN_PROGRESS | TX_FIFO_EMPTY)) == TX_FIFO_EMPTY)
break;
@@ -2155,11 +2198,11 @@ static void port_reset(struct mv643xx_eth_private *mp)
}
/* Reset the Enable bit in the Configuration Register */
- data = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
+ data = rdlp(mp, PORT_SERIAL_CONTROL);
data &= ~(SERIAL_PORT_ENABLE |
DO_NOT_FORCE_LINK_FAIL |
FORCE_LINK_PASS);
- wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), data);
+ wrlp(mp, PORT_SERIAL_CONTROL, data);
}
static int mv643xx_eth_stop(struct net_device *dev)
@@ -2167,8 +2210,8 @@ static int mv643xx_eth_stop(struct net_device *dev)
struct mv643xx_eth_private *mp = netdev_priv(dev);
int i;
- wrl(mp, INT_MASK(mp->port_num), 0x00000000);
- rdl(mp, INT_MASK(mp->port_num));
+ wrlp(mp, INT_MASK, 0x00000000);
+ rdlp(mp, INT_MASK);
del_timer_sync(&mp->mib_counters_timer);
@@ -2261,12 +2304,12 @@ static void mv643xx_eth_netpoll(struct net_device *dev)
{
struct mv643xx_eth_private *mp = netdev_priv(dev);
- wrl(mp, INT_MASK(mp->port_num), 0x00000000);
- rdl(mp, INT_MASK(mp->port_num));
+ wrlp(mp, INT_MASK, 0x00000000);
+ rdlp(mp, INT_MASK);
mv643xx_eth_irq(dev->irq, dev);
- wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);
+ wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
}
#endif
@@ -2314,8 +2357,8 @@ static void infer_hw_params(struct mv643xx_eth_shared_private *msp)
* [21:8], or a 16-bit coal limit in bits [25,21:7] of the
* SDMA config register.
*/
- writel(0x02000000, msp->base + SDMA_CONFIG(0));
- if (readl(msp->base + SDMA_CONFIG(0)) & 0x02000000)
+ writel(0x02000000, msp->base + 0x0400 + SDMA_CONFIG);
+ if (readl(msp->base + 0x0400 + SDMA_CONFIG) & 0x02000000)
msp->extended_rx_coal_limit = 1;
else
msp->extended_rx_coal_limit = 0;
@@ -2325,12 +2368,12 @@ static void infer_hw_params(struct mv643xx_eth_shared_private *msp)
* yes, whether its associated registers are in the old or
* the new place.
*/
- writel(1, msp->base + TX_BW_MTU_MOVED(0));
- if (readl(msp->base + TX_BW_MTU_MOVED(0)) & 1) {
+ writel(1, msp->base + 0x0400 + TX_BW_MTU_MOVED);
+ if (readl(msp->base + 0x0400 + TX_BW_MTU_MOVED) & 1) {
msp->tx_bw_control = TX_BW_CONTROL_NEW_LAYOUT;
} else {
- writel(7, msp->base + TX_BW_RATE(0));
- if (readl(msp->base + TX_BW_RATE(0)) & 7)
+ writel(7, msp->base + 0x0400 + TX_BW_RATE);
+ if (readl(msp->base + 0x0400 + TX_BW_RATE) & 7)
msp->tx_bw_control = TX_BW_CONTROL_OLD_LAYOUT;
else
msp->tx_bw_control = TX_BW_CONTROL_ABSENT;
@@ -2339,7 +2382,7 @@ static void infer_hw_params(struct mv643xx_eth_shared_private *msp)
static int mv643xx_eth_shared_probe(struct platform_device *pdev)
{
- static int mv643xx_eth_version_printed = 0;
+ static int mv643xx_eth_version_printed;
struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;
struct mv643xx_eth_shared_private *msp;
struct resource *res;
@@ -2563,10 +2606,10 @@ static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)
{
u32 pscr;
- pscr = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
+ pscr = rdlp(mp, PORT_SERIAL_CONTROL);
if (pscr & SERIAL_PORT_ENABLE) {
pscr &= ~SERIAL_PORT_ENABLE;
- wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
+ wrlp(mp, PORT_SERIAL_CONTROL, pscr);
}
pscr = MAX_RX_PACKET_9700BYTE | SERIAL_PORT_CONTROL_RESERVED;
@@ -2584,7 +2627,7 @@ static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)
pscr |= SET_FULL_DUPLEX_MODE;
}
- wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
+ wrlp(mp, PORT_SERIAL_CONTROL, pscr);
}
static int mv643xx_eth_probe(struct platform_device *pdev)
@@ -2593,7 +2636,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;
@@ -2617,6 +2659,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, mp);
mp->shared = platform_get_drvdata(pd->shared);
+ mp->base = mp->shared->base + 0x0400 + (pd->port_number << 10);
mp->port_num = pd->port_number;
mp->dev = dev;
@@ -2664,7 +2707,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
dev->hard_start_xmit = mv643xx_eth_xmit;
dev->open = mv643xx_eth_open;
dev->stop = mv643xx_eth_stop;
- dev->set_multicast_list = mv643xx_eth_set_rx_mode;
+ dev->set_rx_mode = mv643xx_eth_set_rx_mode;
dev->set_mac_address = mv643xx_eth_set_mac_address;
dev->do_ioctl = mv643xx_eth_ioctl;
dev->change_mtu = mv643xx_eth_change_mtu;
@@ -2687,8 +2730,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");
@@ -2721,8 +2764,8 @@ static void mv643xx_eth_shutdown(struct platform_device *pdev)
struct mv643xx_eth_private *mp = platform_get_drvdata(pdev);
/* Mask all interrupts on ethernet port */
- wrl(mp, INT_MASK(mp->port_num), 0);
- rdl(mp, INT_MASK(mp->port_num));
+ wrlp(mp, INT_MASK, 0);
+ rdlp(mp, INT_MASK);
if (netif_running(mp->dev))
port_reset(mp);
diff --git a/drivers/net/mvme147.c b/drivers/net/mvme147.c
index 06ca4252155..435e5a847c4 100644
--- a/drivers/net/mvme147.c
+++ b/drivers/net/mvme147.c
@@ -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);
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index b3786709730..c724d96fd1e 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -1309,7 +1309,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx,
skb = netdev_alloc_skb(dev, MYRI10GE_HLEN + 16);
if (unlikely(skb == NULL)) {
- mgp->stats.rx_dropped++;
+ ss->stats.rx_dropped++;
do {
i--;
put_page(rx_frags[i].page);
@@ -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;
}
@@ -2927,6 +2926,7 @@ static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev)
{
struct sk_buff *segs, *curr;
struct myri10ge_priv *mgp = netdev_priv(dev);
+ struct myri10ge_slice_state *ss;
int status;
segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO6);
@@ -2953,8 +2953,9 @@ static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev)
return 0;
drop:
+ ss = &mgp->ss[skb_get_queue_mapping(skb)];
dev_kfree_skb_any(skb);
- mgp->stats.tx_dropped += 1;
+ ss->stats.tx_dropped += 1;
return 0;
}
@@ -2985,7 +2986,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 +3032,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;
}
}
@@ -3740,6 +3739,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int i;
int status = -ENXIO;
int dac_enabled;
+ unsigned hdr_offset, ss_offset;
netdev = alloc_etherdev_mq(sizeof(*mgp), MYRI10GE_MAX_SLICES);
if (netdev == NULL) {
@@ -3807,14 +3807,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (mgp->mtrr >= 0)
mgp->wc_enabled = 1;
#endif
- /* Hack. need to get rid of these magic numbers */
- mgp->sram_size =
- 2 * 1024 * 1024 - (2 * (48 * 1024) + (32 * 1024)) - 0x100;
- if (mgp->sram_size > mgp->board_span) {
- dev_err(&pdev->dev, "board span %ld bytes too small\n",
- mgp->board_span);
- goto abort_with_mtrr;
- }
mgp->sram = ioremap_wc(mgp->iomem_base, mgp->board_span);
if (mgp->sram == NULL) {
dev_err(&pdev->dev, "ioremap failed for %ld bytes at 0x%lx\n",
@@ -3822,9 +3814,19 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
status = -ENXIO;
goto abort_with_mtrr;
}
+ hdr_offset =
+ ntohl(__raw_readl(mgp->sram + MCP_HEADER_PTR_OFFSET)) & 0xffffc;
+ ss_offset = hdr_offset + offsetof(struct mcp_gen_header, string_specs);
+ mgp->sram_size = ntohl(__raw_readl(mgp->sram + ss_offset));
+ if (mgp->sram_size > mgp->board_span ||
+ mgp->sram_size <= MYRI10GE_FW_OFFSET) {
+ dev_err(&pdev->dev,
+ "invalid sram_size %dB or board span %ldB\n",
+ mgp->sram_size, mgp->board_span);
+ goto abort_with_ioremap;
+ }
memcpy_fromio(mgp->eeprom_strings,
- mgp->sram + mgp->sram_size - MYRI10GE_EEPROM_STRINGS_SIZE,
- MYRI10GE_EEPROM_STRINGS_SIZE);
+ mgp->sram + mgp->sram_size, MYRI10GE_EEPROM_STRINGS_SIZE);
memset(mgp->eeprom_strings + MYRI10GE_EEPROM_STRINGS_SIZE - 2, 0, 2);
status = myri10ge_read_mac_addr(mgp);
if (status)
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index 3ad7589d6a1..6833f65f8ae 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -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;
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index f7fa3944659..9f81fcb9688 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -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;
}
diff --git a/drivers/net/ne-h8300.c b/drivers/net/ne-h8300.c
index fbc7531d3c7..aa99f5e09d3 100644
--- a/drivers/net/ne-h8300.c
+++ b/drivers/net/ne-h8300.c
@@ -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);
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index eb681c0d51b..f708712a374 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -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;
diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c
index 332df75a9ab..6f8f3260346 100644
--- a/drivers/net/ne2.c
+++ b/drivers/net/ne2.c
@@ -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);
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index de0de744a8f..ea22ae268a5 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -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);
diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c
index 425043a88db..6681ca748c7 100644
--- a/drivers/net/ne3210.c
+++ b/drivers/net/ne3210.c
@@ -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];
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 9681618c323..d304d38cd5d 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -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);
}
/*
diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c
index b9bed82e1d2..b418771f681 100644
--- a/drivers/net/netx-eth.c
+++ b/drivers/net/netx-eth.c
@@ -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++;
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 84978f80f39..86379fdd8b0 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -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;
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 5bba675d050..d924468e506 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -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;
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 6ef3f0d84bc..25bfb3acf5e 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -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;
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c
index 27f07f6a45b..c3b9c83b32f 100644
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ b/drivers/net/netxen/netxen_nic_niu.c
@@ -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;
}
diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c
index 8e0ca9f4e40..0cf6addbe40 100644
--- a/drivers/net/ni5010.c
+++ b/drivers/net/ni5010.c
@@ -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;
diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c
index b9a882d362d..10cfd0f91fc 100644
--- a/drivers/net/ni52.c
+++ b/drivers/net/ni52.c
@@ -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);
diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c
index 3edc971d0ec..1142c770eab 100644
--- a/drivers/net/ni65.c
+++ b/drivers/net/ni65.c
@@ -295,7 +295,7 @@ static void ni65_set_performance(struct priv *p)
*/
static int ni65_open(struct net_device *dev)
{
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
int irqval = request_irq(dev->irq, &ni65_interrupt,0,
cards[p->cardno].cardname,dev);
if (irqval) {
@@ -321,7 +321,7 @@ static int ni65_open(struct net_device *dev)
*/
static int ni65_close(struct net_device *dev)
{
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
netif_stop_queue(dev);
@@ -345,7 +345,7 @@ static int ni65_close(struct net_device *dev)
static void cleanup_card(struct net_device *dev)
{
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
disable_dma(dev->dma);
free_dma(dev->dma);
release_region(dev->base_addr, cards[p->cardno].total_size);
@@ -444,7 +444,7 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr)
release_region(ioaddr, cards[i].total_size);
return j;
}
- p = (struct priv *) dev->priv;
+ p = dev->ml_priv;
p->cmdr_addr = ioaddr + cards[i].cmd_offset;
p->cardno = i;
spin_lock_init(&p->ring_lock);
@@ -647,8 +647,8 @@ static int ni65_alloc_buffer(struct net_device *dev)
if(!ptr)
return -ENOMEM;
- p = dev->priv = (struct priv *) (((unsigned long) ptr + 7) & ~0x7);
- memset((char *) dev->priv,0,sizeof(struct priv));
+ p = dev->ml_priv = (struct priv *) (((unsigned long) ptr + 7) & ~0x7);
+ memset((char *)p, 0, sizeof(struct priv));
p->self = ptr;
for(i=0;i<TMDNUM;i++)
@@ -790,7 +790,7 @@ static void ni65_stop_start(struct net_device *dev,struct priv *p)
static int ni65_lance_reinit(struct net_device *dev)
{
int i;
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
unsigned long flags;
p->lock = 0;
@@ -876,7 +876,7 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
struct priv *p;
int bcnt = 32;
- p = (struct priv *) dev->priv;
+ p = dev->ml_priv;
spin_lock(&p->ring_lock);
@@ -899,7 +899,7 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
if(csr0 & CSR0_ERR)
{
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
if(debuglevel > 1)
printk(KERN_ERR "%s: general error: %04x.\n",dev->name,csr0);
if(csr0 & CSR0_BABL)
@@ -924,7 +924,7 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
int j;
for(j=0;j<RMDNUM;j++)
{
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
int i,k,num1,num2;
for(i=RMDNUM-1;i>0;i--) {
num2 = (p->rmdnum + i) & (RMDNUM-1);
@@ -982,7 +982,7 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
*/
static void ni65_xmit_intr(struct net_device *dev,int csr0)
{
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
while(p->xmit_queued)
{
@@ -1049,7 +1049,7 @@ static void ni65_recv_intr(struct net_device *dev,int csr0)
struct rmd *rmdp;
int rmdstat,len;
int cnt=0;
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
rmdp = p->rmdhead + p->rmdnum;
while(!( (rmdstat = rmdp->u.s.status) & RCV_OWN))
@@ -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
{
@@ -1140,7 +1139,7 @@ static void ni65_recv_intr(struct net_device *dev,int csr0)
static void ni65_timeout(struct net_device *dev)
{
int i;
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
printk(KERN_ERR "%s: xmitter timed out, try to restart!\n",dev->name);
for(i=0;i<TMDNUM;i++)
@@ -1157,7 +1156,7 @@ static void ni65_timeout(struct net_device *dev)
static int ni65_send_packet(struct sk_buff *skb, struct net_device *dev)
{
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
netif_stop_queue(dev);
@@ -1222,7 +1221,7 @@ static struct net_device_stats *ni65_get_stats(struct net_device *dev)
#if 0
int i;
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = dev->ml_priv;
for(i=0;i<RMDNUM;i++)
{
struct rmd *rmdp = p->rmdhead + ((p->rmdnum + i) & (RMDNUM-1));
@@ -1231,7 +1230,7 @@ static struct net_device_stats *ni65_get_stats(struct net_device *dev)
printk("\n");
#endif
- return &((struct priv *) dev->priv)->stats;
+ return &((struct priv *)dev->ml_priv)->stats;
}
static void set_multicast_list(struct net_device *dev)
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 1b6f548c441..318537efd58 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -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;
}
@@ -8891,28 +8889,31 @@ static struct net_device * __devinit niu_alloc_and_init(
return dev;
}
+static const struct net_device_ops niu_netdev_ops = {
+ .ndo_open = niu_open,
+ .ndo_stop = niu_close,
+ .ndo_get_stats = niu_get_stats,
+ .ndo_set_multicast_list = niu_set_rx_mode,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = niu_set_mac_addr,
+ .ndo_do_ioctl = niu_ioctl,
+ .ndo_tx_timeout = niu_tx_timeout,
+ .ndo_change_mtu = niu_change_mtu,
+};
+
static void __devinit niu_assign_netdev_ops(struct net_device *dev)
{
- dev->open = niu_open;
- dev->stop = niu_close;
- dev->get_stats = niu_get_stats;
- dev->set_multicast_list = niu_set_rx_mode;
- dev->set_mac_address = niu_set_mac_addr;
- dev->do_ioctl = niu_ioctl;
- dev->tx_timeout = niu_tx_timeout;
+ dev->netdev_ops = &niu_netdev_ops;
dev->hard_start_xmit = niu_start_xmit;
dev->ethtool_ops = &niu_ethtool_ops;
dev->watchdog_timeo = NIU_TX_TIMEOUT;
- dev->change_mtu = niu_change_mtu;
}
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",
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index ff449619f04..4bb64415437 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -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"
);
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index edc0fd58898..fcbf6ccd0a8 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -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;
diff --git a/drivers/net/pasemi_mac_ethtool.c b/drivers/net/pasemi_mac_ethtool.c
index 5e8df3afea6..064a4fe1dd9 100644
--- a/drivers/net/pasemi_mac_ethtool.c
+++ b/drivers/net/pasemi_mac_ethtool.c
@@ -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))
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
index 0a575fef29e..b23b5c397b1 100644
--- a/drivers/net/pci-skeleton.c
+++ b/drivers/net/pci-skeleton.c
@@ -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 {
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 08c4dd89607..e5cb6b1f0eb 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -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 {
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index c235cdba69c..73ecc657999 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -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 {
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index b37a498939a..2aca8df3497 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -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)
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index 831090c7562..7b5c77b7bd2 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -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;
}
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 69d916daa7b..69dcfbbabe8 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -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;
}
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 448cd40aeba..ec7c588c9ae 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -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 */
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index e40d6301aa7..69625373a8e 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -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:
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index c74d6656d26..fccd53ef3c6 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -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)
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index e1fd585e713..fef7e1861d6 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -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))
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index ca8c0e03740..f2b192c80e1 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -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) {
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index d55932acd88..c4c5a2f8ec7 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -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
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index eee329fa6f5..9ae5d30b5f4 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -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
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 4b4dc98ad16..fd4fc66b6d6 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -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 */
@@ -54,6 +56,21 @@
#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.
*/
@@ -88,6 +105,24 @@
#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
*/
#define BCM5482_SSD_1000BX_CTL 0x00 /* 1000BASE-X Control */
@@ -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
index 00000000000..a439ebeb431
--- /dev/null
+++ b/drivers/net/phy/mdio-gpio.c
@@ -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
index 2ff97754e57..00000000000
--- a/drivers/net/phy/mdio-ofgpio.c
+++ /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);
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 536bda1f428..868812ff6de 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -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;
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index df4e6257d4a..e4ede6080c9 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -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,
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 55bc24b234e..b344a0b55db 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -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;
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index 73baa7a3bb0..c05d38d4635 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -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);
diff --git a/drivers/net/plip.c b/drivers/net/plip.c
index 1e965427b0e..d544d4a086d 100644
--- a/drivers/net/plip.c
+++ b/drivers/net/plip.c
@@ -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;
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 7e857e938ad..bad99e8cac3 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -886,7 +886,7 @@ out_chrdev:
static int
ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct ppp *ppp = (struct ppp *) dev->priv;
+ struct ppp *ppp = netdev_priv(dev);
int npi, proto;
unsigned char *pp;
@@ -931,7 +931,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
static int
ppp_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
- struct ppp *ppp = dev->priv;
+ struct ppp *ppp = netdev_priv(dev);
int err = -EFAULT;
void __user *addr = (void __user *) ifr->ifr_ifru.ifru_data;
struct ppp_stats stats;
@@ -971,8 +971,13 @@ ppp_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return err;
}
+static const struct net_device_ops ppp_netdev_ops = {
+ .ndo_do_ioctl = ppp_net_ioctl,
+};
+
static void ppp_setup(struct net_device *dev)
{
+ dev->netdev_ops = &ppp_netdev_ops;
dev->hard_header_len = PPP_HDRLEN;
dev->mtu = PPP_MTU;
dev->addr_len = 0;
@@ -1684,7 +1689,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;
@@ -2414,13 +2418,12 @@ ppp_create_interface(int unit, int *retp)
int ret = -ENOMEM;
int i;
- ppp = kzalloc(sizeof(struct ppp), GFP_KERNEL);
- if (!ppp)
- goto out;
- dev = alloc_netdev(0, "", ppp_setup);
+ dev = alloc_netdev(sizeof(struct ppp), "", ppp_setup);
if (!dev)
goto out1;
+ ppp = netdev_priv(dev);
+ ppp->dev = dev;
ppp->mru = PPP_MRU;
init_ppp_file(&ppp->file, INTERFACE);
ppp->file.hdrlen = PPP_HDRLEN - 2; /* don't count proto bytes */
@@ -2433,11 +2436,8 @@ ppp_create_interface(int unit, int *retp)
ppp->minseq = -1;
skb_queue_head_init(&ppp->mrq);
#endif /* CONFIG_PPP_MULTILINK */
- ppp->dev = dev;
- dev->priv = ppp;
dev->hard_start_xmit = ppp_start_xmit;
- dev->do_ioctl = ppp_net_ioctl;
ret = -EEXIST;
mutex_lock(&all_ppp_mutex);
@@ -2473,8 +2473,6 @@ out2:
mutex_unlock(&all_ppp_mutex);
free_netdev(dev);
out1:
- kfree(ppp);
-out:
*retp = ret;
return NULL;
}
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index b646e92134d..c22b30533a1 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -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;
}
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 2eb54fd7bed..4b564eda5bd 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -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;
}
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index a834b52a6a2..ec231424668 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -30,10 +30,11 @@
#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;
diff --git a/drivers/net/ps3_gelic_wireless.h b/drivers/net/ps3_gelic_wireless.h
index 5339e0078d1..5b631c6c977 100644
--- a/drivers/net/ps3_gelic_wireless.h
+++ b/drivers/net/ps3_gelic_wireless.h
@@ -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;
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 508452c0215..f188736028d 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -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));
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index b83a9c9b6a9..3a6d3ac25f1 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -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)
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 34fe7ef8e5e..d9a6e920fd6 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -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;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 4b7cb389dc4..bac58ca628d 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -474,6 +474,7 @@ struct rtl8169_private {
void (*hw_start)(struct net_device *);
unsigned int (*phy_reset_pending)(void __iomem *);
unsigned int (*link_ok)(void __iomem *);
+ int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd);
int pcie_cap;
struct delayed_work task;
unsigned features;
@@ -1829,9 +1830,11 @@ static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
struct rtl8169_private *tp = netdev_priv(dev);
struct mii_ioctl_data *data = if_mii(ifr);
- if (!netif_running(dev))
- return -ENODEV;
+ return netif_running(dev) ? tp->do_ioctl(tp, data, cmd) : -ENODEV;
+}
+static int rtl_xmii_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd)
+{
switch (cmd) {
case SIOCGMIIPHY:
data->phy_id = 32; /* Internal PHY */
@@ -1850,6 +1853,11 @@ static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -EOPNOTSUPP;
}
+static int rtl_tbi_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd)
+{
+ return -EOPNOTSUPP;
+}
+
static const struct rtl_cfg_info {
void (*hw_start)(struct net_device *);
unsigned int region;
@@ -1915,6 +1923,25 @@ static void rtl_disable_msi(struct pci_dev *pdev, struct rtl8169_private *tp)
}
}
+static const struct net_device_ops rtl8169_netdev_ops = {
+ .ndo_open = rtl8169_open,
+ .ndo_stop = rtl8169_close,
+ .ndo_get_stats = rtl8169_get_stats,
+ .ndo_tx_timeout = rtl8169_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = rtl8169_change_mtu,
+ .ndo_set_mac_address = rtl_set_mac_address,
+ .ndo_do_ioctl = rtl8169_ioctl,
+ .ndo_set_multicast_list = rtl_set_rx_mode,
+#ifdef CONFIG_R8169_VLAN
+ .ndo_vlan_rx_register = rtl8169_vlan_rx_register,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = rtl8169_netpoll,
+#endif
+
+};
+
static int __devinit
rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@@ -1941,6 +1968,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
SET_NETDEV_DEV(dev, &pdev->dev);
+ dev->netdev_ops = &rtl8169_netdev_ops;
tp = netdev_priv(dev);
tp->dev = dev;
tp->pci_dev = pdev;
@@ -2076,6 +2104,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->phy_reset_enable = rtl8169_tbi_reset_enable;
tp->phy_reset_pending = rtl8169_tbi_reset_pending;
tp->link_ok = rtl8169_tbi_link_ok;
+ tp->do_ioctl = rtl_tbi_ioctl;
tp->phy_1000_ctrl_reg = ADVERTISE_1000FULL; /* Implied by TBI */
} else {
@@ -2084,8 +2113,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->phy_reset_enable = rtl8169_xmii_reset_enable;
tp->phy_reset_pending = rtl8169_xmii_reset_pending;
tp->link_ok = rtl8169_xmii_link_ok;
-
- dev->do_ioctl = rtl8169_ioctl;
+ tp->do_ioctl = rtl_xmii_ioctl;
}
spin_lock_init(&tp->lock);
@@ -2097,28 +2125,16 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->dev_addr[i] = RTL_R8(MAC0 + i);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
- dev->open = rtl8169_open;
dev->hard_start_xmit = rtl8169_start_xmit;
- dev->get_stats = rtl8169_get_stats;
SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
- dev->stop = rtl8169_close;
- dev->tx_timeout = rtl8169_tx_timeout;
- dev->set_multicast_list = rtl_set_rx_mode;
dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
dev->irq = pdev->irq;
dev->base_addr = (unsigned long) ioaddr;
- dev->change_mtu = rtl8169_change_mtu;
- dev->set_mac_address = rtl_set_mac_address;
netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
#ifdef CONFIG_R8169_VLAN
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- dev->vlan_rx_register = rtl8169_vlan_rx_register;
-#endif
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = rtl8169_netpoll;
#endif
tp->intr_mask = 0xffff;
@@ -3484,7 +3500,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++;
}
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 2b8fd68bc51..a6fd27a2cc3 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -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;
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
index 3dd8f1342f7..6e4131f9a93 100644
--- a/drivers/net/rrunner.c
+++ b/drivers/net/rrunner.c
@@ -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;
}
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 6a1375f9cbb..62369341cb2 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -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)) {
diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c
index 5986cec17f1..be3025310e9 100644
--- a/drivers/net/sb1000.c
+++ b/drivers/net/sb1000.c
@@ -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;
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 2615d46e6e5..480caec1e02 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -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);
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index 61955f8d801..590f2175e9e 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -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;
diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c
index 48c64fb20ee..2fbc8f1e8b4 100644
--- a/drivers/net/seeq8005.c
+++ b/drivers/net/seeq8005.c
@@ -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;
}
diff --git a/drivers/net/sfc/Kconfig b/drivers/net/sfc/Kconfig
index 3be13b592b4..c535408ad6b 100644
--- a/drivers/net/sfc/Kconfig
+++ b/drivers/net/sfc/Kconfig
@@ -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 && !(SFC=y && MTD=m)
+ 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.
diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile
index c8f5704c8fb..e507daa4f0e 100644
--- a/drivers/net/sfc/Makefile
+++ b/drivers/net/sfc/Makefile
@@ -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
diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c
index 99e60237326..edf026280be 100644
--- a/drivers/net/sfc/boards.c
+++ b/drivers/net/sfc/boards.c
@@ -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. */
@@ -52,9 +53,128 @@ 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;
}
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 06ea71c7e34..ac7bdbf3fd4 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -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:
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index d02937b70ee..dd0d45b9e71 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -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;
diff --git a/drivers/net/sfc/enum.h b/drivers/net/sfc/enum.h
index cec15dbb88e..41e758e8fdb 100644
--- a/drivers/net/sfc/enum.h
+++ b/drivers/net/sfc/enum.h
@@ -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,
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index cd0d0873d97..cd92c4d8dbc 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -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
/**************************************************************************
*
@@ -429,7 +426,7 @@ static void efx_ethtool_get_stats(struct net_device *net_dev,
EFX_BUG_ON_PARANOID(stats->n_stats != EFX_ETHTOOL_NUM_STATS);
/* Update MAC and NIC statistics */
- net_dev->get_stats(net_dev);
+ dev_get_stats(net_dev);
/* Fill detailed statistics buffer */
for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) {
@@ -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;
}
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 31ed1f49de0..71e0bed6061 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -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);
diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h
index 5d584b0dbb5..040e70ed4ec 100644
--- a/drivers/net/sfc/falcon_hwdefs.h
+++ b/drivers/net/sfc/falcon_hwdefs.h
@@ -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 {
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index 003e48dcb2f..19e25210b68 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -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
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 19c42eaf7fb..db9f358349c 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -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
index 00000000000..a1e6c2875fc
--- /dev/null
+++ b/drivers/net/sfc/mtd.c
@@ -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;
+}
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index cdb11fad605..e596c9a6a4c 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -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;
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index 0f805da4ce5..b8ba4bbad88 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -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)
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index fe4e3fd2233..aa576c559ec 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -21,6 +21,7 @@
#include "falcon_hwdefs.h"
#include "falcon_io.h"
#include "mac.h"
+#include "workarounds.h"
/**************************************************************************
*
@@ -65,48 +66,9 @@
#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;
}
diff --git a/drivers/net/sfc/spi.h b/drivers/net/sfc/spi.h
index feef6194237..c4aca132348 100644
--- a/drivers/net/sfc/spi.h
+++ b/drivers/net/sfc/spi.h
@@ -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
@@ -44,23 +46,51 @@
* 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 */
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index d507c93d666..8d41c29b9d7 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -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)
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index fa7b49d6928..ec50b90f428 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -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 */
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index 276151df3a7..91f02466210 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -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;
}
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index 6261201403c..97d68560067 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -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;
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 59f242a6771..7f8e514eb5e 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -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;
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index e6e3bf58a56..83cc3c5f794 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -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");
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index fa3a460f8e2..9a363dc0db4 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -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))
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index a2b092bb362..282bb47decc 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -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);
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 43f4c730be4..93c1b1d9296 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -104,6 +104,7 @@ static void yukon_get_stats(struct skge_port *skge, u64 *data);
static void yukon_init(struct skge_hw *hw, int port);
static void genesis_mac_init(struct skge_hw *hw, int port);
static void genesis_link_up(struct skge_port *skge);
+static void skge_set_multicast(struct net_device *dev);
/* Avoid conditionals by using array */
static const int txqaddr[] = { Q_XA1, Q_XA2 };
@@ -149,24 +150,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 +237,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;
}
@@ -2477,7 +2464,7 @@ static void skge_phy_reset(struct skge_port *skge)
}
spin_unlock_bh(&hw->phy_lock);
- dev->set_multicast_list(dev);
+ skge_set_multicast(dev);
}
/* Basic MII support */
@@ -3045,6 +3032,18 @@ static inline int bad_phy_status(const struct skge_hw *hw, u32 status)
(status & GMR_FS_RX_OK) == 0;
}
+static void skge_set_multicast(struct net_device *dev)
+{
+ struct skge_port *skge = netdev_priv(dev);
+ struct skge_hw *hw = skge->hw;
+
+ if (hw->chip_id == CHIP_ID_GENESIS)
+ genesis_set_multicast(dev);
+ else
+ yukon_set_multicast(dev);
+
+}
+
/* Get receive buffer from descriptor.
* Handles copy of small buffers and reallocation failures
@@ -3200,7 +3199,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;
@@ -3730,7 +3728,7 @@ static int skge_device_event(struct notifier_block *unused,
struct skge_port *skge;
struct dentry *d;
- if (dev->open != &skge_up || !skge_debug)
+ if (dev->netdev_ops->ndo_open != &skge_up || !skge_debug)
goto done;
skge = netdev_priv(dev);
@@ -3804,6 +3802,22 @@ static __exit void skge_debug_cleanup(void)
#define skge_debug_cleanup()
#endif
+static const struct net_device_ops skge_netdev_ops = {
+ .ndo_open = skge_up,
+ .ndo_stop = skge_down,
+ .ndo_do_ioctl = skge_ioctl,
+ .ndo_get_stats = skge_get_stats,
+ .ndo_tx_timeout = skge_tx_timeout,
+ .ndo_change_mtu = skge_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = skge_set_multicast,
+ .ndo_set_mac_address = skge_set_mac_address,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = skge_netpoll,
+#endif
+};
+
+
/* Initialize network device */
static struct net_device *skge_devinit(struct skge_hw *hw, int port,
int highmem)
@@ -3817,24 +3831,10 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
}
SET_NETDEV_DEV(dev, &hw->pdev->dev);
- dev->open = skge_up;
- dev->stop = skge_down;
- dev->do_ioctl = skge_ioctl;
dev->hard_start_xmit = skge_xmit_frame;
- dev->get_stats = skge_get_stats;
- if (hw->chip_id == CHIP_ID_GENESIS)
- dev->set_multicast_list = genesis_set_multicast;
- else
- dev->set_multicast_list = yukon_set_multicast;
-
- dev->set_mac_address = skge_set_mac_address;
- dev->change_mtu = skge_change_mtu;
- SET_ETHTOOL_OPS(dev, &skge_ethtool_ops);
- dev->tx_timeout = skge_tx_timeout;
+ dev->netdev_ops = &skge_netdev_ops;
+ dev->ethtool_ops = &skge_ethtool_ops;
dev->watchdog_timeo = TX_WATCHDOG;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = skge_netpoll;
-#endif
dev->irq = hw->pdev->irq;
if (highmem)
@@ -3856,7 +3856,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 +3885,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 +4081,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 +4095,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 +4103,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 +4143,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);
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 3813d15e2df..251505125cb 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -3979,7 +3979,7 @@ static int sky2_device_event(struct notifier_block *unused,
struct net_device *dev = ptr;
struct sky2_port *sky2 = netdev_priv(dev);
- if (dev->open != sky2_up || !sky2_debug)
+ if (dev->netdev_ops->ndo_open != sky2_up || !sky2_debug)
return NOTIFY_DONE;
switch(event) {
@@ -4041,6 +4041,39 @@ static __exit void sky2_debug_cleanup(void)
#define sky2_debug_cleanup()
#endif
+/* Two copies of network device operations to handle special case of
+ not allowing netpoll on second port */
+static const struct net_device_ops sky2_netdev_ops[2] = {
+ {
+ .ndo_open = sky2_up,
+ .ndo_stop = sky2_down,
+ .ndo_do_ioctl = sky2_ioctl,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = sky2_set_mac_address,
+ .ndo_set_multicast_list = sky2_set_multicast,
+ .ndo_change_mtu = sky2_change_mtu,
+ .ndo_tx_timeout = sky2_tx_timeout,
+#ifdef SKY2_VLAN_TAG_USED
+ .ndo_vlan_rx_register = sky2_vlan_rx_register,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = sky2_netpoll,
+#endif
+ },
+ {
+ .ndo_open = sky2_up,
+ .ndo_stop = sky2_down,
+ .ndo_do_ioctl = sky2_ioctl,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = sky2_set_mac_address,
+ .ndo_set_multicast_list = sky2_set_multicast,
+ .ndo_change_mtu = sky2_change_mtu,
+ .ndo_tx_timeout = sky2_tx_timeout,
+#ifdef SKY2_VLAN_TAG_USED
+ .ndo_vlan_rx_register = sky2_vlan_rx_register,
+#endif
+ },
+};
/* Initialize network device */
static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
@@ -4057,20 +4090,10 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
SET_NETDEV_DEV(dev, &hw->pdev->dev);
dev->irq = hw->pdev->irq;
- dev->open = sky2_up;
- dev->stop = sky2_down;
- dev->do_ioctl = sky2_ioctl;
dev->hard_start_xmit = sky2_xmit_frame;
- dev->set_multicast_list = sky2_set_multicast;
- dev->set_mac_address = sky2_set_mac_address;
- dev->change_mtu = sky2_change_mtu;
SET_ETHTOOL_OPS(dev, &sky2_ethtool_ops);
- dev->tx_timeout = sky2_tx_timeout;
dev->watchdog_timeo = TX_WATCHDOG;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- if (port == 0)
- dev->poll_controller = sky2_netpoll;
-#endif
+ dev->netdev_ops = &sky2_netdev_ops[port];
sky2 = netdev_priv(dev);
sky2->netdev = dev;
@@ -4104,7 +4127,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
if (!(sky2->hw->chip_id == CHIP_ID_YUKON_FE_P &&
sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0)) {
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- dev->vlan_rx_register = sky2_vlan_rx_register;
}
#endif
@@ -4118,11 +4140,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 */
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 1d58991d395..25cec06d6dc 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -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++;
}
diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c
index d6abb68e6e2..58a0e0a4a32 100644
--- a/drivers/net/smc-mca.c
+++ b/drivers/net/smc-mca.c
@@ -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.
diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
index 00d6cf1af48..0fe0251767b 100644
--- a/drivers/net/smc-ultra.c
+++ b/drivers/net/smc-ultra.c
@@ -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. */
diff --git a/drivers/net/smc-ultra32.c b/drivers/net/smc-ultra32.c
index a5a91ace28c..cb6c097a2e0 100644
--- a/drivers/net/smc-ultra32.c
+++ b/drivers/net/smc-ultra32.c
@@ -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. */
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index b185cd12269..84d1feb1c17 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -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;
diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c
index de67744c4a2..e7cc80f3256 100644
--- a/drivers/net/smc9194.c
+++ b/drivers/net/smc9194.c
@@ -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 {
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index fc80f250da3..5879c719b53 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -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/smc91x.h b/drivers/net/smc91x.h
index a07cc9351c6..f6d637968ed 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -87,49 +87,28 @@ static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg)
#define RPC_LSA_DEFAULT RPC_LED_100_10
#define RPC_LSB_DEFAULT RPC_LED_TX_RX
-# if defined (CONFIG_BFIN561_EZKIT)
#define SMC_CAN_USE_8BIT 0
#define SMC_CAN_USE_16BIT 1
+# if defined(CONFIG_BF561)
#define SMC_CAN_USE_32BIT 1
-#define SMC_IO_SHIFT 0
-#define SMC_NOWAIT 1
-#define SMC_USE_BFIN_DMA 0
-
-
-#define SMC_inw(a, r) readw((a) + (r))
-#define SMC_outw(v, a, r) writew(v, (a) + (r))
-#define SMC_inl(a, r) readl((a) + (r))
-#define SMC_outl(v, a, r) writel(v, (a) + (r))
-#define SMC_outsl(a, r, p, l) outsl((unsigned long *)((a) + (r)), p, l)
-#define SMC_insl(a, r, p, l) insl ((unsigned long *)((a) + (r)), p, l)
# else
-#define SMC_CAN_USE_8BIT 0
-#define SMC_CAN_USE_16BIT 1
#define SMC_CAN_USE_32BIT 0
+# endif
#define SMC_IO_SHIFT 0
#define SMC_NOWAIT 1
#define SMC_USE_BFIN_DMA 0
-
-#define SMC_inw(a, r) readw((a) + (r))
-#define SMC_outw(v, a, r) writew(v, (a) + (r))
-#define SMC_outsw(a, r, p, l) outsw((unsigned long *)((a) + (r)), p, l)
-#define SMC_insw(a, r, p, l) insw ((unsigned long *)((a) + (r)), p, l)
+#define SMC_inw(a, r) readw((a) + (r))
+#define SMC_outw(v, a, r) writew(v, (a) + (r))
+#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
+# if SMC_CAN_USE_32BIT
+#define SMC_inl(a, r) readl((a) + (r))
+#define SMC_outl(v, a, r) writel(v, (a) + (r))
+#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
+#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
# endif
-/* check if the mac in reg is valid */
-#define SMC_GET_MAC_ADDR(lp, addr) \
- do { \
- unsigned int __v; \
- __v = SMC_inw(ioaddr, ADDR0_REG(lp)); \
- addr[0] = __v; addr[1] = __v >> 8; \
- __v = SMC_inw(ioaddr, ADDR1_REG(lp)); \
- addr[2] = __v; addr[3] = __v >> 8; \
- __v = SMC_inw(ioaddr, ADDR2_REG(lp)); \
- addr[4] = __v; addr[5] = __v >> 8; \
- if (*(u32 *)(&addr[0]) == 0xFFFFFFFF) { \
- random_ether_addr(addr); \
- } \
- } while (0)
+
#elif defined(CONFIG_REDWOOD_5) || defined(CONFIG_REDWOOD_6)
/* We can only do 16-bit reads and writes in the static memory space. */
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
new file mode 100644
index 00000000000..fe517880fc9
--- /dev/null
+++ b/drivers/net/smsc911x.c
@@ -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
index 00000000000..feb36de274c
--- /dev/null
+++ b/drivers/net/smsc911x.h
@@ -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__ */
diff --git a/drivers/net/sonic.c b/drivers/net/sonic.c
index 8069f3e32d8..211e805c122 100644
--- a/drivers/net/sonic.c
+++ b/drivers/net/sonic.c
@@ -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;
diff --git a/drivers/net/sonic.h b/drivers/net/sonic.h
index 7db13e4a7ea..07091dd27e5 100644
--- a/drivers/net/sonic.h
+++ b/drivers/net/sonic.h
@@ -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);
}
diff --git a/drivers/net/spider_net_ethtool.c b/drivers/net/spider_net_ethtool.c
index 85691d2a0be..5bae728c382 100644
--- a/drivers/net/spider_net_ethtool.c
+++ b/drivers/net/spider_net_ethtool.c
@@ -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;
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 1d2ef8f4778..0358809f409 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -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:
diff --git a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c
index e531302d95f..e8f97d5c9c2 100644
--- a/drivers/net/sun3_82586.c
+++ b/drivers/net/sun3_82586.c
@@ -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;
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index 359452a06c6..4bb8f72c65c 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -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;
}
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index 018d0fca942..977b3e08bbf 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -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;
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index f860ea15039..698893b9200 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -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++;
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 4291458955e..44be8dfbcf1 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -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)
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index f1ebeb5f65b..b22d3355fb4 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -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;
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 704301a5a7f..28137328175 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -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;
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index f63644744ff..6e8f377355f 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -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;
diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c
index a720065553d..233f1cda36e 100644
--- a/drivers/net/sunvnet.c
+++ b/drivers/net/sunvnet.c
@@ -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);
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index df20cafff7d..44126c463fa 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -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);
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 91f9054a1d9..7e36a10423f 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -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) {
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index eb9f8f3638e..4b97cb60136 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -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;
- if (tp->mdio_bus->phy_map[PHY_ADDR]->interface !=
- PHY_INTERFACE_MODE_RGMII)
+ 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);
+
+ 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.
@@ -13241,18 +13343,34 @@ static void __devinit tg3_init_coal(struct tg3 *tp)
}
}
+static const struct net_device_ops tg3_netdev_ops = {
+ .ndo_open = tg3_open,
+ .ndo_stop = tg3_close,
+ .ndo_get_stats = tg3_get_stats,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = tg3_set_rx_mode,
+ .ndo_set_mac_address = tg3_set_mac_addr,
+ .ndo_do_ioctl = tg3_ioctl,
+ .ndo_tx_timeout = tg3_tx_timeout,
+ .ndo_change_mtu = tg3_change_mtu,
+#if TG3_VLAN_TAG_USED
+ .ndo_vlan_rx_register = tg3_vlan_rx_register,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = tg3_poll_controller,
+#endif
+};
+
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 +13382,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 +13407,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");
@@ -13303,7 +13418,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
#if TG3_VLAN_TAG_USED
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- dev->vlan_rx_register = tg3_vlan_rx_register;
#endif
tp = netdev_priv(dev);
@@ -13343,7 +13457,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");
@@ -13357,21 +13475,11 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
tp->tx_pending = TG3_DEF_TX_RING_PENDING;
- dev->open = tg3_open;
- dev->stop = tg3_close;
- dev->get_stats = tg3_get_stats;
- dev->set_multicast_list = tg3_set_rx_mode;
- dev->set_mac_address = tg3_set_mac_addr;
- dev->do_ioctl = tg3_ioctl;
- dev->tx_timeout = tg3_tx_timeout;
+ dev->netdev_ops = &tg3_netdev_ops;
netif_napi_add(dev, &tp->napi, tg3_poll, 64);
dev->ethtool_ops = &tg3_ethtool_ops;
dev->watchdog_timeo = TG3_TX_TIMEOUT;
- dev->change_mtu = tg3_change_mtu;
dev->irq = pdev->irq;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = tg3_poll_controller;
-#endif
err = tg3_get_invariants(tp);
if (err) {
@@ -13466,17 +13574,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 +13640,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,
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index be252abe898..599e490cf62 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -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
@@ -325,6 +327,7 @@
#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
@@ -414,6 +417,7 @@
#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
@@ -539,6 +543,100 @@
#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
@@ -1792,6 +1890,11 @@
#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;
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index c41d6876136..055d3429851 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -1649,8 +1649,6 @@ drop_and_reuse:
}
}
- dev->last_rx = jiffies;
-
return ack;
} /* TLan_HandleRxEOF */
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index bf621328b60..87509a65b3b 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -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) ;
diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c
index 7a7de0469ea..b566d6d79ec 100644
--- a/drivers/net/tokenring/abyss.c
+++ b/drivers/net/tokenring/abyss.c
@@ -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;
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index e494c63bfbd..9fd09938d45 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -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 */
/*****************************************************************************/
diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
index 59d1673f938..239c75217b1 100644
--- a/drivers/net/tokenring/lanstreamer.c
+++ b/drivers/net/tokenring/lanstreamer.c
@@ -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;
diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
index c9c5a2b1ed9..0ba6f0bc7c0 100644
--- a/drivers/net/tokenring/madgemc.c
+++ b/drivers/net/tokenring/madgemc.c
@@ -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");
diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
index 0ab51a0f35f..ecb5c7c9691 100644
--- a/drivers/net/tokenring/olympic.c
+++ b/drivers/net/tokenring/olympic.c
@@ -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),
diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c
index 00ea9451346..cd2d62f7607 100644
--- a/drivers/net/tokenring/proteon.c
+++ b/drivers/net/tokenring/proteon.c
@@ -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;
diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c
index 41b6999a0f3..b578744311b 100644
--- a/drivers/net/tokenring/skisa.c
+++ b/drivers/net/tokenring/skisa.c
@@ -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;
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
index ed50d288e49..a011666342f 100644
--- a/drivers/net/tokenring/smctr.c
+++ b/drivers/net/tokenring/smctr.c
@@ -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 {
}
}
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
index d07c4523c84..5be34c2fd48 100644
--- a/drivers/net/tokenring/tms380tr.c
+++ b/drivers/net/tokenring/tms380tr.c
@@ -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)
diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c
index 5f0ee880cff..5f601773c26 100644
--- a/drivers/net/tokenring/tmspci.c
+++ b/drivers/net/tokenring/tmspci.c
@@ -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) {
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index eb1da6f0b08..271bc230c8a 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -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);
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index 124d5d690dd..3aa60fad68c 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -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();
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index 6444cbec0bd..67bfd6f4336 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -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);
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index c91852f49a4..28a5c51b43a 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -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;
}
diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c
index 0dcced1263b..391acd32a6a 100644
--- a/drivers/net/tulip/eeprom.c
+++ b/drivers/net/tulip/eeprom.c
@@ -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);
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
index c6bad987d63..739d610d18c 100644
--- a/drivers/net/tulip/interrupt.c
+++ b/drivers/net/tulip/interrupt.c
@@ -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;
}
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index cafa89e6016..1c5ef230b77 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -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)
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index e9e62862163..00cbc5251dc 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -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);
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index 50068194c16..022d99af864 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -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;
}
diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c
index 6b93d016911..13c8703ecb9 100644
--- a/drivers/net/tulip/xircom_cb.c
+++ b/drivers/net/tulip/xircom_cb.c
@@ -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;
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 33b6d1b122f..b4c94144475 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -305,6 +305,22 @@ tun_net_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
+static const struct net_device_ops tun_netdev_ops = {
+ .ndo_open = tun_net_open,
+ .ndo_stop = tun_net_close,
+ .ndo_change_mtu = tun_net_change_mtu,
+
+};
+
+static const struct net_device_ops tap_netdev_ops = {
+ .ndo_open = tun_net_open,
+ .ndo_stop = tun_net_close,
+ .ndo_change_mtu = tun_net_change_mtu,
+ .ndo_set_multicast_list = tun_net_mclist,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/* Initialize net device. */
static void tun_net_init(struct net_device *dev)
{
@@ -312,11 +328,12 @@ static void tun_net_init(struct net_device *dev)
switch (tun->flags & TUN_TYPE_MASK) {
case TUN_TUN_DEV:
+ dev->netdev_ops = &tun_netdev_ops;
+
/* Point-to-Point TUN Device */
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->mtu = 1500;
- dev->change_mtu = tun_net_change_mtu;
/* Zero header length */
dev->type = ARPHRD_NONE;
@@ -325,10 +342,9 @@ static void tun_net_init(struct net_device *dev)
break;
case TUN_TAP_DEV:
+ dev->netdev_ops = &tun_netdev_ops;
/* Ethernet TAP Device */
ether_setup(dev);
- dev->change_mtu = tun_net_change_mtu;
- dev->set_multicast_list = tun_net_mclist;
random_ether_addr(dev->dev_addr);
@@ -529,7 +545,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;
@@ -676,9 +691,7 @@ static void tun_setup(struct net_device *dev)
tun->owner = -1;
tun->group = -1;
- dev->open = tun_net_open;
dev->hard_start_xmit = tun_net_xmit;
- dev->stop = tun_net_close;
dev->ethtool_ops = &tun_ethtool_ops;
dev->destructor = free_netdev;
dev->features |= NETIF_F_NETNS_LOCAL;
@@ -750,6 +763,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
return -ENOMEM;
dev_net_set(dev, net);
+
tun = netdev_priv(dev);
tun->dev = dev;
tun->flags = flags;
@@ -883,7 +897,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 +1024,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);
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 734ce0977f0..5386d9b73e6 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -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.
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index c87747bb24c..0a5b817fd7a 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -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))
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index 466a89e2444..d7621239059 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -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;
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index b5143509e8b..bbcc76ae3c9 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -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);
}
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 7914867110e..075e8e94225 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -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);
}
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 51e2f5d7d14..4638a7bb471 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -31,7 +31,7 @@
#include "smsc95xx.h"
#define SMSC_CHIPNAME "smsc95xx"
-#define SMSC_DRIVER_VERSION "1.0.3"
+#define SMSC_DRIVER_VERSION "1.0.4"
#define HS_USB_PKT_SIZE (512)
#define FS_USB_PKT_SIZE (64)
#define DEFAULT_HS_BURST_CAP_SIZE (16 * 1024 + 5 * HS_USB_PKT_SIZE)
@@ -40,15 +40,18 @@
#define MAX_SINGLE_PACKET_SIZE (2048)
#define LAN95XX_EEPROM_MAGIC (0x9500)
#define EEPROM_MAC_OFFSET (0x01)
+#define DEFAULT_TX_CSUM_ENABLE (true)
#define DEFAULT_RX_CSUM_ENABLE (true)
#define SMSC95XX_INTERNAL_PHY_ID (1)
#define SMSC95XX_TX_OVERHEAD (8)
+#define SMSC95XX_TX_OVERHEAD_CSUM (12)
#define FLOW_CTRL_TX (1)
#define FLOW_CTRL_RX (2)
struct smsc95xx_priv {
u32 mac_cr;
spinlock_t mac_cr_lock;
+ bool use_tx_csum;
bool use_rx_csum;
};
@@ -556,9 +559,10 @@ static void smsc95xx_status(struct usbnet *dev, struct urb *urb)
devwarn(dev, "unexpected interrupt, intdata=0x%08X", intdata);
}
-/* Enable or disable Rx checksum offload engine */
-static int smsc95xx_set_rx_csum(struct usbnet *dev, bool enable)
+/* Enable or disable Tx & Rx checksum offload engines */
+static int smsc95xx_set_csums(struct usbnet *dev)
{
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
u32 read_buf;
int ret = smsc95xx_read_reg(dev, COE_CR, &read_buf);
if (ret < 0) {
@@ -566,7 +570,12 @@ static int smsc95xx_set_rx_csum(struct usbnet *dev, bool enable)
return ret;
}
- if (enable)
+ if (pdata->use_tx_csum)
+ read_buf |= Tx_COE_EN_;
+ else
+ read_buf &= ~Tx_COE_EN_;
+
+ if (pdata->use_rx_csum)
read_buf |= Rx_COE_EN_;
else
read_buf &= ~Rx_COE_EN_;
@@ -626,7 +635,26 @@ static int smsc95xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val)
pdata->use_rx_csum = !!val;
- return smsc95xx_set_rx_csum(dev, pdata->use_rx_csum);
+ return smsc95xx_set_csums(dev);
+}
+
+static u32 smsc95xx_ethtool_get_tx_csum(struct net_device *netdev)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+
+ return pdata->use_tx_csum;
+}
+
+static int smsc95xx_ethtool_set_tx_csum(struct net_device *netdev, u32 val)
+{
+ struct usbnet *dev = netdev_priv(netdev);
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+
+ pdata->use_tx_csum = !!val;
+
+ ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum);
+ return smsc95xx_set_csums(dev);
}
static struct ethtool_ops smsc95xx_ethtool_ops = {
@@ -640,6 +668,8 @@ static struct ethtool_ops smsc95xx_ethtool_ops = {
.get_eeprom_len = smsc95xx_ethtool_get_eeprom_len,
.get_eeprom = smsc95xx_ethtool_get_eeprom,
.set_eeprom = smsc95xx_ethtool_set_eeprom,
+ .get_tx_csum = smsc95xx_ethtool_get_tx_csum,
+ .set_tx_csum = smsc95xx_ethtool_set_tx_csum,
.get_rx_csum = smsc95xx_ethtool_get_rx_csum,
.set_rx_csum = smsc95xx_ethtool_set_rx_csum,
};
@@ -757,9 +787,9 @@ static int smsc95xx_phy_initialize(struct usbnet *dev)
static int smsc95xx_reset(struct usbnet *dev)
{
struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ struct net_device *netdev = dev->net;
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 +848,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) {
@@ -970,10 +999,11 @@ static int smsc95xx_reset(struct usbnet *dev)
return ret;
}
- /* Enable or disable Rx checksum offload engine */
- ret = smsc95xx_set_rx_csum(dev, pdata->use_rx_csum);
+ /* Enable or disable checksum offload engines */
+ ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum);
+ ret = smsc95xx_set_csums(dev);
if (ret < 0) {
- devwarn(dev, "Failed to set Rx csum offload: %d", ret);
+ devwarn(dev, "Failed to set csum offload: %d", ret);
return ret;
}
@@ -1029,6 +1059,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
spin_lock_init(&pdata->mac_cr_lock);
+ pdata->use_tx_csum = DEFAULT_TX_CSUM_ENABLE;
pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE;
/* Init all registers */
@@ -1148,22 +1179,44 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
return 1;
}
+static u32 smsc95xx_calc_csum_preamble(struct sk_buff *skb)
+{
+ int len = skb->data - skb->head;
+ u16 high_16 = (u16)(skb->csum_offset + skb->csum_start - len);
+ u16 low_16 = (u16)(skb->csum_start - len);
+ return (high_16 << 16) | low_16;
+}
+
static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
struct sk_buff *skb, gfp_t flags)
{
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+ bool csum = pdata->use_tx_csum && (skb->ip_summed == CHECKSUM_PARTIAL);
+ int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD;
u32 tx_cmd_a, tx_cmd_b;
- if (skb_headroom(skb) < SMSC95XX_TX_OVERHEAD) {
+ /* We do not advertise SG, so skbs should be already linearized */
+ BUG_ON(skb_shinfo(skb)->nr_frags);
+
+ if (skb_headroom(skb) < overhead) {
struct sk_buff *skb2 = skb_copy_expand(skb,
- SMSC95XX_TX_OVERHEAD, 0, flags);
+ overhead, 0, flags);
dev_kfree_skb_any(skb);
skb = skb2;
if (!skb)
return NULL;
}
+ if (csum) {
+ u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
+ skb_push(skb, 4);
+ memcpy(skb->data, &csum_preamble, 4);
+ }
+
skb_push(skb, 4);
tx_cmd_b = (u32)(skb->len - 4);
+ if (csum)
+ tx_cmd_b |= TX_CMD_B_CSUM_ENABLE;
cpu_to_le32s(&tx_cmd_b);
memcpy(skb->data, &tx_cmd_b, 4);
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 02d25c74399..aa314907888 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -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);
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 31cd817f33f..4f93a55aaaa 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -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
*/
@@ -267,16 +262,20 @@ static void veth_dev_free(struct net_device *dev)
free_netdev(dev);
}
+static const struct net_device_ops veth_netdev_ops = {
+ .ndo_init = veth_dev_init,
+ .ndo_open = veth_open,
+ .ndo_get_stats = veth_get_stats,
+};
+
static void veth_setup(struct net_device *dev)
{
ether_setup(dev);
+ dev->netdev_ops = &veth_netdev_ops;
dev->hard_start_xmit = veth_xmit;
- dev->get_stats = veth_get_stats;
- dev->open = veth_open;
dev->ethtool_ops = &veth_ethtool_ops;
dev->features |= NETIF_F_LLTX;
- dev->init = veth_dev_init;
dev->destructor = veth_dev_free;
}
@@ -302,7 +301,7 @@ static int veth_device_event(struct notifier_block *unused,
{
struct net_device *dev = ptr;
- if (dev->open != veth_open)
+ if (dev->netdev_ops->ndo_open != veth_open)
goto out;
switch (event) {
@@ -420,14 +419,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 +444,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);
}
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 5b7870080c5..9a650d0a679 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -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++;
}
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 11cb3e504e1..033e63a6843 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -849,6 +849,19 @@ static int velocity_soft_reset(struct velocity_info *vptr)
return 0;
}
+static const struct net_device_ops velocity_netdev_ops = {
+ .ndo_open = velocity_open,
+ .ndo_stop = velocity_close,
+ .ndo_get_stats = velocity_get_stats,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = velocity_set_multi,
+ .ndo_change_mtu = velocity_change_mtu,
+ .ndo_do_ioctl = velocity_ioctl,
+ .ndo_vlan_rx_add_vid = velocity_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = velocity_vlan_rx_kill_vid,
+ .ndo_vlan_rx_register = velocity_vlan_rx_register,
+};
+
/**
* velocity_found1 - set up discovered velocity card
* @pdev: PCI device
@@ -958,18 +971,9 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
vptr->phy_id = MII_GET_PHY_ID(vptr->mac_regs);
dev->irq = pdev->irq;
- dev->open = velocity_open;
dev->hard_start_xmit = velocity_xmit;
- dev->stop = velocity_close;
- dev->get_stats = velocity_get_stats;
- dev->set_multicast_list = velocity_set_multi;
- dev->do_ioctl = velocity_ioctl;
+ dev->netdev_ops = &velocity_netdev_ops;
dev->ethtool_ops = &velocity_ethtool_ops;
- dev->change_mtu = velocity_change_mtu;
-
- dev->vlan_rx_add_vid = velocity_vlan_rx_add_vid;
- dev->vlan_rx_kill_vid = velocity_vlan_rx_kill_vid;
- dev->vlan_rx_register = velocity_vlan_rx_register;
#ifdef VELOCITY_ZERO_COPY_SUPPORT
dev->features |= NETIF_F_SG;
@@ -1412,8 +1416,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;
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 0196a0df902..e6b5d6ef9ea 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -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++) {
@@ -232,6 +311,55 @@ static void try_fill_recv(struct virtnet_info *vi)
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);
break;
}
@@ -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,
};
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 7f97f8d08c3..d80b72e22de 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -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;
}
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index 5a7303dc096..5fa52923efa 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -199,6 +199,8 @@ static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
static struct net_device *
cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte);
+static void cycx_x25_chan_setup(struct net_device *dev);
+
#ifdef CYCLOMX_X25_DEBUG
static void hex_dump(char *msg, unsigned char *p, int len);
static void cycx_x25_dump_config(struct cycx_x25_config *conf);
@@ -353,6 +355,12 @@ static int cycx_wan_update(struct wan_device *wandev)
return 0;
}
+/* callback to initialize device */
+static void cycx_x25_chan_setup(struct net_device *dev)
+{
+ dev->init = cycx_netdevice_init;
+}
+
/* Create new logical channel.
* This routine is called by the router when ROUTER_IFNEW IOCTL is being
* handled.
@@ -376,11 +384,12 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
return -EINVAL;
}
- /* allocate and initialize private data */
- chan = kzalloc(sizeof(struct cycx_x25_channel), GFP_KERNEL);
- if (!chan)
+ dev = alloc_netdev(sizeof(struct cycx_x25_channel), conf->name,
+ cycx_x25_chan_setup);
+ if (!dev)
return -ENOMEM;
+ chan = netdev_priv(dev);
strcpy(chan->name, conf->name);
chan->card = card;
chan->link = conf->port;
@@ -396,14 +405,14 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
if (len > WAN_ADDRESS_SZ) {
printk(KERN_ERR "%s: %s local addr too long!\n",
wandev->name, chan->name);
- kfree(chan);
- return -EINVAL;
+ err = -EINVAL;
+ goto error;
} else {
chan->local_addr = kmalloc(len + 1, GFP_KERNEL);
if (!chan->local_addr) {
- kfree(chan);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto error;
}
}
@@ -429,41 +438,31 @@ static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
"%s: PVC %u is out of range on interface %s!\n",
wandev->name, lcn, chan->name);
err = -EINVAL;
+ goto error;
}
} else {
printk(KERN_ERR "%s: invalid media address on interface %s!\n",
wandev->name, chan->name);
err = -EINVAL;
+ goto error;
}
- if (err) {
- kfree(chan->local_addr);
- kfree(chan);
- return err;
- }
-
- /* prepare network device data space for registration */
- strcpy(dev->name, chan->name);
- dev->init = cycx_netdevice_init;
- dev->priv = chan;
-
return 0;
+
+error:
+ free_netdev(dev);
+ return err;
}
/* Delete logical channel. */
static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev)
{
- if (dev->priv) {
- struct cycx_x25_channel *chan = dev->priv;
+ struct cycx_x25_channel *chan = netdev_priv(dev);
- if (chan->svc) {
- kfree(chan->local_addr);
- if (chan->state == WAN_CONNECTED)
- del_timer(&chan->timer);
- }
-
- kfree(chan);
- dev->priv = NULL;
+ if (chan->svc) {
+ kfree(chan->local_addr);
+ if (chan->state == WAN_CONNECTED)
+ del_timer(&chan->timer);
}
return 0;
@@ -484,7 +483,7 @@ static const struct header_ops cycx_header_ops = {
* registration. */
static int cycx_netdevice_init(struct net_device *dev)
{
- struct cycx_x25_channel *chan = dev->priv;
+ struct cycx_x25_channel *chan = netdev_priv(dev);
struct cycx_device *card = chan->card;
struct wan_device *wandev = &card->wandev;
@@ -542,7 +541,7 @@ static int cycx_netdevice_open(struct net_device *dev)
* o if there's no more open channels then disconnect physical link. */
static int cycx_netdevice_stop(struct net_device *dev)
{
- struct cycx_x25_channel *chan = dev->priv;
+ struct cycx_x25_channel *chan = netdev_priv(dev);
netif_stop_queue(dev);
@@ -596,7 +595,7 @@ static int cycx_netdevice_rebuild_header(struct sk_buff *skb)
static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
- struct cycx_x25_channel *chan = dev->priv;
+ struct cycx_x25_channel *chan = netdev_priv(dev);
struct cycx_device *card = chan->card;
if (!chan->svc)
@@ -670,7 +669,7 @@ free_packet:
* Return a pointer to struct net_device_stats */
static struct net_device_stats *cycx_netdevice_get_stats(struct net_device *dev)
{
- struct cycx_x25_channel *chan = dev->priv;
+ struct cycx_x25_channel *chan = netdev_priv(dev);
return chan ? &chan->ifstats : NULL;
}
@@ -783,7 +782,7 @@ static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
return;
}
- chan = dev->priv;
+ chan = netdev_priv(dev);
reset_timer(dev);
if (chan->drop_sequence) {
@@ -843,7 +842,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. */
@@ -884,7 +882,7 @@ static void cycx_x25_irq_connect(struct cycx_device *card,
return;
}
- chan = dev->priv;
+ chan = netdev_priv(dev);
chan->lcn = lcn;
cycx_x25_connect_response(card, chan);
cycx_x25_set_chan_state(dev, WAN_CONNECTED);
@@ -914,7 +912,7 @@ static void cycx_x25_irq_connect_confirm(struct cycx_device *card,
}
clear_bit(--key, (void*)&card->u.x.connection_keys);
- chan = dev->priv;
+ chan = netdev_priv(dev);
chan->lcn = lcn;
cycx_x25_set_chan_state(dev, WAN_CONNECTED);
}
@@ -954,7 +952,7 @@ static void cycx_x25_irq_disconnect(struct cycx_device *card,
dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
if (dev) {
- struct cycx_x25_channel *chan = dev->priv;
+ struct cycx_x25_channel *chan = netdev_priv(dev);
cycx_x25_disconnect_response(card, chan->link, lcn);
cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
@@ -1302,7 +1300,7 @@ static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
struct cycx_x25_channel *chan;
while (dev) {
- chan = (struct cycx_x25_channel*)dev->priv;
+ chan = netdev_priv(dev);
if (chan->lcn == lcn)
break;
@@ -1319,7 +1317,7 @@ static struct net_device *
struct cycx_x25_channel *chan;
while (dev) {
- chan = (struct cycx_x25_channel*)dev->priv;
+ chan = netdev_priv(dev);
if (!strcmp(chan->addr, dte))
break;
@@ -1337,7 +1335,7 @@ static struct net_device *
* <0 failure */
static int cycx_x25_chan_connect(struct net_device *dev)
{
- struct cycx_x25_channel *chan = dev->priv;
+ struct cycx_x25_channel *chan = netdev_priv(dev);
struct cycx_device *card = chan->card;
if (chan->svc) {
@@ -1362,7 +1360,7 @@ static int cycx_x25_chan_connect(struct net_device *dev)
* o if SVC then clear X.25 call */
static void cycx_x25_chan_disconnect(struct net_device *dev)
{
- struct cycx_x25_channel *chan = dev->priv;
+ struct cycx_x25_channel *chan = netdev_priv(dev);
if (chan->svc) {
x25_clear_call(chan->card, chan->link, chan->lcn, 0, 0);
@@ -1375,7 +1373,7 @@ static void cycx_x25_chan_disconnect(struct net_device *dev)
static void cycx_x25_chan_timer(unsigned long d)
{
struct net_device *dev = (struct net_device *)d;
- struct cycx_x25_channel *chan = dev->priv;
+ struct cycx_x25_channel *chan = netdev_priv(dev);
if (chan->state == WAN_CONNECTED)
cycx_x25_chan_disconnect(dev);
@@ -1387,7 +1385,7 @@ static void cycx_x25_chan_timer(unsigned long d)
/* Set logical channel state. */
static void cycx_x25_set_chan_state(struct net_device *dev, u8 state)
{
- struct cycx_x25_channel *chan = dev->priv;
+ struct cycx_x25_channel *chan = netdev_priv(dev);
struct cycx_device *card = chan->card;
unsigned long flags;
char *string_state = NULL;
@@ -1453,7 +1451,7 @@ static void cycx_x25_set_chan_state(struct net_device *dev, u8 state)
* to the router. */
static int cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb)
{
- struct cycx_x25_channel *chan = dev->priv;
+ struct cycx_x25_channel *chan = netdev_priv(dev);
struct cycx_device *card = chan->card;
int bitm = 0; /* final packet */
unsigned len = skb->len;
@@ -1494,7 +1492,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. */
@@ -1547,7 +1544,7 @@ static unsigned dec_to_uint(u8 *str, int len)
static void reset_timer(struct net_device *dev)
{
- struct cycx_x25_channel *chan = dev->priv;
+ struct cycx_x25_channel *chan = netdev_priv(dev);
if (chan->svc)
mod_timer(&chan->timer, jiffies+chan->idle_tmout*HZ);
@@ -1600,7 +1597,7 @@ static void cycx_x25_dump_devs(struct wan_device *wandev)
printk(KERN_INFO "---------------------------------------\n");
while(dev) {
- struct cycx_x25_channel *chan = dev->priv;
+ struct cycx_x25_channel *chan = netdev_priv(dev);
printk(KERN_INFO "%-5.5s %-15.15s %d ETH_P_%s\n",
chan->name, chan->addr, netif_queue_stopped(dev),
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c
index b14242768fa..a297e3efa05 100644
--- a/drivers/net/wan/dlci.c
+++ b/drivers/net/wan/dlci.c
@@ -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;
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 5f1ccb2b08b..888025db2f0 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -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),
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 9557ad078ab..48a2c9d2895 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -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;
diff --git a/drivers/net/wan/hd6457x.c b/drivers/net/wan/hd6457x.c
index 591fb45a7c6..434583a94b3 100644
--- a/drivers/net/wan/hd6457x.c
+++ b/drivers/net/wan/hd6457x.c
@@ -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);
}
diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
index e299313f828..af54f0cf1b3 100644
--- a/drivers/net/wan/hostess_sv11.c
+++ b/drivers/net/wan/hostess_sv11.c
@@ -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;
}
/*
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
index 24fd613466b..5b61b3eef45 100644
--- a/drivers/net/wan/lapbether.c
+++ b/drivers/net/wan/lapbether.c
@@ -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);
}
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index d7bb63e616b..feac3b99f8f 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -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;
diff --git a/drivers/net/wan/lmc/lmc_proto.c b/drivers/net/wan/lmc/lmc_proto.c
index be9877ff551..94b4c208b01 100644
--- a/drivers/net/wan/lmc/lmc_proto.c
+++ b/drivers/net/wan/lmc/lmc_proto.c
@@ -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:
diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c
index bf1b0159042..22267116522 100644
--- a/drivers/net/wan/pc300too.c
+++ b/drivers/net/wan/pc300too.c
@@ -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 ||
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c
index b595b64e753..bba111cdeeb 100644
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -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 ||
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index ee51b6a5e60..6db063e2d5b 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -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
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index 73e2f278093..6a07ba9371d 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -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) {
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
index c0235844a4d..0941a26f6e3 100644
--- a/drivers/net/wan/sealevel.c
+++ b/drivers/net/wan/sealevel.c
@@ -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;
}
/*
diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
index 6e92f7b44b1..58ae8a2223a 100644
--- a/drivers/net/wan/syncppp.c
+++ b/drivers/net/wan/syncppp.c
@@ -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
}
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
index a8a5ca0ee6c..88459490ecd 100644
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -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;
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 2a6c7a60756..85d78914730 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -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)
diff --git a/drivers/net/wd.c b/drivers/net/wd.c
index fa14255282a..6d96ed47211 100644
--- a/drivers/net/wd.c
+++ b/drivers/net/wd.c
@@ -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
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 45bdf0b339b..42afaedbb21 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -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.
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 59d2d805f60..78820840fe2 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -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
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index b2c050b6889..fc0897fb223 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -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;
diff --git a/drivers/net/wireless/adm8211.h b/drivers/net/wireless/adm8211.h
index 9b190ee26e9..4f6ab132218 100644
--- a/drivers/net/wireless/adm8211.h
+++ b/drivers/net/wireless/adm8211.h
@@ -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;
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 370133e492d..67d504e3229 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -47,10 +47,11 @@
#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/arlan-main.c b/drivers/net/wireless/arlan-main.c
index dec5e874a54..bfca15da6f0 100644
--- a/drivers/net/wireless/arlan-main.c
+++ b/drivers/net/wireless/arlan-main.c
@@ -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;
}
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index 53ea439aff4..a725bb94a52 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -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;
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index cfd4d052d66..c7ffcbb9062 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -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;
}
diff --git a/drivers/net/wireless/ath5k/dma.c b/drivers/net/wireless/ath5k/dma.c
index 7adceb2c7fa..7e2b1a67e5d 100644
--- a/drivers/net/wireless/ath5k/dma.c
+++ b/drivers/net/wireless/ath5k/dma.c
@@ -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;
}
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c
index ceaa6c475c0..450bd6e945f 100644
--- a/drivers/net/wireless/ath5k/initvals.c
+++ b/drivers/net/wireless/ath5k/initvals.c
@@ -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),
diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath5k/pcu.c
index a47df9a24aa..d7f0c1017bd 100644
--- a/drivers/net/wireless/ath5k/pcu.c
+++ b/drivers/net/wireless/ath5k/pcu.c
@@ -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);
}
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c
index e43f6563e61..69625bf4d11 100644
--- a/drivers/net/wireless/ath5k/phy.c
+++ b/drivers/net/wireless/ath5k/phy.c
@@ -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;
}
diff --git a/drivers/net/wireless/ath5k/qcu.c b/drivers/net/wireless/ath5k/qcu.c
index 01bf09176d2..1b7bc50ea8e 100644
--- a/drivers/net/wireless/ath5k/qcu.c
+++ b/drivers/net/wireless/ath5k/qcu.c
@@ -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;
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h
index e557fe178bb..69755fc2f9b 100644
--- a/drivers/net/wireless/ath5k/reg.h
+++ b/drivers/net/wireless/ath5k/reg.h
@@ -234,6 +234,7 @@
#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
@@ -350,7 +351,7 @@
#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
@@ -1113,14 +1114,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 */
@@ -1810,6 +1813,10 @@
#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
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c
index 1b6d45b6772..b51bc030da0 100644
--- a/drivers/net/wireless/ath5k/reset.c
+++ b/drivers/net/wireless/ath5k/reset.c
@@ -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)
diff --git a/drivers/net/wireless/ath9k/Makefile b/drivers/net/wireless/ath9k/Makefile
index a6411517e5f..c58cfdeb49c 100644
--- a/drivers/net/wireless/ath9k/Makefile
+++ b/drivers/net/wireless/ath9k/Makefile
@@ -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
index 00000000000..ada12e9aa7f
--- /dev/null
+++ b/drivers/net/wireless/ath9k/ani.c
@@ -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);
+ }
+}
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
index accace5f7ef..3a180ce1770 100644
--- a/drivers/net/wireless/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath9k/ath9k.h
@@ -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
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index 9e15c30bbc0..d186cd41c23 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -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
index 00000000000..1690759fe7b
--- /dev/null
+++ b/drivers/net/wireless/ath9k/calib.c
@@ -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
+};
diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c
index c5033f6f42a..5f5184acb27 100644
--- a/drivers/net/wireless/ath9k/core.c
+++ b/drivers/net/wireless/ath9k/core.c
@@ -14,13 +14,9 @@
* 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);
}
}
@@ -261,44 +277,6 @@ static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan)
}
/*
- * 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
*
* Set/change channels. If the channel is really being changed, it's done
@@ -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 */
/**************************/
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
index cb3e61e57c4..69e8d3e4113 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -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
index 00000000000..f5fd03c0edd
--- /dev/null
+++ b/drivers/net/wireless/ath9k/eeprom.c
@@ -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;
+}
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index 98bc25c9b3c..e05c9ef55e4 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -23,183 +23,68 @@
#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,596 +122,215 @@ 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;
-}
-
-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 void ath9k_hw_init_bb(struct ath_hal *ah,
- struct ath9k_channel *chan)
-{
- u32 synthDelay;
-
- 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;
-
- REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
-
- udelay(synthDelay + BASE_ACTIVATE_DELAY);
-}
-
-static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
- enum ath9k_opmode opmode)
-{
- 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 ((flags & CHANNEL_2GHZ)) {
+ *low = pCap->low_2ghz_chan;
+ *high = pCap->high_2ghz_chan;
+ return true;
}
+ return false;
}
-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);
-
- 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 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 u8 ath9k_hw_get_num_ant_config(struct ath_hal_5416 *ahp,
- enum ieee80211_band freq_band)
+u16 ath9k_hw_computetxtime(struct ath_hal *ah,
+ const struct ath9k_rate_table *rates,
+ u32 frameLen, u16 rateix,
+ bool shortPreamble)
{
- 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;
-}
+ u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
+ u32 kbps;
-static int
-ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal_5416 *ahp,
- struct ath9k_channel *chan,
- u8 index,
- u16 *config)
-{
- 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;
+ kbps = rates->info[rateix].rateKbps;
- switch (index) {
- case 0:
- *config = pModal->antCtrlCommon & 0xFFFF;
+ if (kbps == 0)
return 0;
- case 1:
- if (pBase->version >= 0x0E0D) {
- if (pModal->useAnt1) {
- *config =
- ((pModal->antCtrlCommon & 0xFFFF0000) >> 16);
- return 0;
- }
+
+ 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;
}
- return -EINVAL;
-}
-
-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);
+ return txTime;
}
-static bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
+u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
{
- 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;
+ 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;
}
- eep_data++;
+ } 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;
}
- 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)
+void ath9k_hw_get_channel_centers(struct ath_hal *ah,
+ struct ath9k_channel *chan,
+ struct chan_centers *centers)
{
- struct modal_eep_header *pModal;
- int i, regChainOffset;
+ int8_t extoff;
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)]);
+ if (!IS_CHAN_HT40(chan)) {
+ centers->ctl_center = centers->ext_center =
+ centers->synth_center = chan->channel;
+ return;
+ }
- txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
+ 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;
+ }
- ath9k_hw_get_eeprom_antenna_cfg(ahp, chan, 1, &ant_config);
- REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
+ 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));
- 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));
- }
- }
- }
+/******************/
+/* Chip Revisions */
+/******************/
- 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);
- }
+static void ath9k_hw_read_revisions(struct ath_hal *ah)
+{
+ u32 val;
- 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);
+ val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
- 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);
+ 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 {
- 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 (!AR_SREV_9100(ah))
+ ah->ah_macVersion = MS(val, AR_SREV_VERSION);
- 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);
- }
+ ah->ah_macRev = val & AR_SREV_REVISION;
- 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);
+ if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE)
+ ah->ah_isPciExpress = true;
}
-
- return true;
}
-static int ath9k_hw_check_eeprom(struct ath_hal *ah)
+static int ath9k_hw_get_radiorev(struct ath_hal *ah)
{
- u32 sum = 0, el;
- u16 *eepdata;
+ u32 val;
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;
+ REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
- word = swab16(eep->baseEepHeader.deviceCap);
- eep->baseEepHeader.deviceCap = word;
+ 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);
- for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
- struct modal_eep_header *pModal =
- &eep->modalHeader[j];
- integer = swab32(pModal->antCtrlCommon);
- pModal->antCtrlCommon = integer;
+ return ath9k_hw_reverse_bits(val, 8);
+}
- for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- integer = swab32(pModal->antCtrlChain[i]);
- pModal->antCtrlChain[i] = integer;
- }
+/************************************/
+/* HW Attach, Detach, Init Routines */
+/************************************/
- for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
- word = swab16(pModal->spurChans[i].spurChan);
- pModal->spurChans[i].spurChan = word;
- }
- }
- }
+static void ath9k_hw_disablepcie(struct ath_hal *ah)
+{
+ if (!AR_SREV_9100(ah))
+ return;
- 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;
- }
+ 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 0;
+ REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
}
static bool ath9k_hw_chip_test(struct ath_hal *ah)
@@ -905,9 +338,9 @@ 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 };
+ 0xaaaaaaaa,
+ 0x66666666,
+ 0x99999999 };
int i, j;
for (i = 0; i < 2; i++) {
@@ -921,9 +354,9 @@ static bool ath9k_hw_chip_test(struct ath_hal *ah)
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);
+ "%s: address test failed "
+ "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+ __func__, addr, wrData, rdData);
return false;
}
}
@@ -933,9 +366,9 @@ static bool ath9k_hw_chip_test(struct ath_hal *ah)
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);
+ "%s: address test failed "
+ "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+ __func__, addr, wrData, rdData);
return false;
}
}
@@ -945,213 +378,62 @@ static bool ath9k_hw_chip_test(struct ath_hal *ah)
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)
+static const char *ath9k_hw_devname(u16 devid)
{
- 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);
+ 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";
}
- 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));
+ return NULL;
}
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
- u32 *rxc_pcnt,
- u32 *rxf_pcnt,
- u32 *txf_pcnt)
+static void ath9k_hw_set_defaults(struct ath_hal *ah)
{
- static u32 cycles, rx_clear, rx_frame, tx_frame;
- u32 good = 1;
+ int i;
- 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,163 +487,6 @@ static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
return ahp;
}
-static 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;
-}
-
-u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
- enum eeprom_param param)
-{
- 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;
- }
-}
-
-static int ath9k_hw_get_radiorev(struct ath_hal *ah)
-{
- u32 val;
- int i;
-
- 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);
-}
-
-static int ath9k_hw_init_macaddr(struct ath_hal *ah)
-{
- u32 sum;
- 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));
- 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));
- 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)
-{
- 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;
-}
-
static int ath9k_hw_rfattach(struct ath_hal *ah)
{
bool rfStatus = false;
@@ -1375,8 +495,8 @@ static int ath9k_hw_rfattach(struct ath_hal *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);
+ "%s: RF setup failed, status %u\n", __func__,
+ ecode);
return ecode;
}
@@ -1401,9 +521,9 @@ static int ath9k_hw_rf_claim(struct ath_hal *ah)
break;
default:
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "%s: 5G Radio Chip Rev 0x%02X is not "
+ "%s: 5G Radio Chip Rev 0x%02X is not "
"supported by this driver\n",
- __func__, ah->ah_analog5GhzRev);
+ __func__, ah->ah_analog5GhzRev);
return -EOPNOTSUPP;
}
@@ -1412,1482 +532,37 @@ static int ath9k_hw_rf_claim(struct ath_hal *ah)
return 0;
}
-static void ath9k_hw_init_pll(struct ath_hal *ah,
- struct ath9k_channel *chan)
-{
- 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);
-
- if (chan && IS_CHAN_5GHZ(chan)) {
- pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
-
-
- 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);
- }
-
- } else if (AR_SREV_9160_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);
-
- 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;
-
- 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);
- }
- }
- 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);
-
- 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;
-
- if (ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
- phymode |= AR_PHY_FC_DYN2040_EXT_CH;
- }
- REG_WRITE(ah, AR_PHY_TURBO, phymode);
-
- ath9k_hw_set11nmac2040(ah, macmode);
-
- 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_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;
- }
-}
-
-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);
-
- REG_WRITE(ah, AR_PHY_MODE, rfMode);
-}
-
-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__);
- return false;
- }
-
- 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
-struct ath9k_channel *ath9k_hw_check_chan(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;
- }
-
- 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)
+static int ath9k_hw_init_macaddr(struct ath_hal *ah)
{
+ u32 sum;
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)
-{
+ u16 eeval;
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;
- }
+ sum = 0;
+ for (i = 0; i < 3; 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;
}
-
-#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;
- }
+ if (sum == 0 || sum == 0xffff * 3) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "%s: mac address read failed: %pM\n", __func__,
+ ahp->ah_macaddr);
+ return -EADDRNOTAVAIL;
}
- 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);
- 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;
-
- 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_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 (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__);
+ "%s: hardware self-test failed\n", __func__);
return -ENODEV;
}
@@ -2906,357 +581,12 @@ static int ath9k_hw_post_attach(struct ath_hal *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;
+ return 0;
}
-static struct ath_hal *ath9k_hw_do_attach(u16 devid,
- struct ath_softc *sc,
- void __iomem *mem,
- int *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;
@@ -3300,6 +630,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid,
SER_REG_MODE_OFF;
}
}
+
DPRINTF(ah->ah_sc, ATH_DBG_RESET,
"%s: serialize_regmode is %d\n",
__func__, ah->ah_config.serialize_regmode);
@@ -3309,9 +640,9 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid,
(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);
+ "%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;
}
@@ -3341,8 +672,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid,
ahp->ah_adcDcCalInitData.calData =
&adc_init_dc_cal;
}
- ahp->ah_suppCals =
- ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
+ ahp->ah_suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
}
if (AR_SREV_9160(ah)) {
@@ -3352,14 +682,13 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid,
} 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;
+ 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);
+ "%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,
@@ -3369,21 +698,16 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid,
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);
+ 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);
+ 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);
+ 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);
@@ -3469,7 +793,7 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid,
if (ah->ah_isPciExpress)
ath9k_hw_configpcipowersave(ah, 0);
else
- ar5416DisablePciePhy(ah);
+ ath9k_hw_disablepcie(ah);
ecode = ath9k_hw_post_attach(ah);
if (ecode != 0)
@@ -3490,10 +814,9 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid,
}
}
#endif
-
if (!ath9k_hw_fill_cap_info(ah)) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET,
- "%s:failed ath9k_hw_fill_cap_info\n", __func__);
+ "%s:failed ath9k_hw_fill_cap_info\n", __func__);
ecode = -EINVAL;
goto bad;
}
@@ -3501,8 +824,8 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid,
ecode = ath9k_hw_init_macaddr(ah);
if (ecode != 0) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET,
- "%s: failed initializing mac address\n",
- __func__);
+ "%s: failed initializing mac address\n",
+ __func__);
goto bad;
}
@@ -3511,1106 +834,553 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid,
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)
+static void ath9k_hw_init_bb(struct ath_hal *ah,
+ struct ath9k_channel *chan)
{
- if (!AR_SREV_9100(ah))
- ath9k_hw_ani_detach(ah);
- ath9k_hw_rfdetach(ah);
+ u32 synthDelay;
- ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
- kfree(ah);
+ 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;
+
+ REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+
+ udelay(synthDelay + BASE_ACTIVATE_DELAY);
}
-bool ath9k_get_channel_edges(struct ath_hal *ah,
- u16 flags, u16 *low,
- u16 *high)
+static void ath9k_hw_init_qos(struct ath_hal *ah)
{
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
+ REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
- 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;
+ 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));
- return true;
- }
- return false;
+ 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 inline bool ath9k_hw_fill_vpd_table(u8 pwrMin,
- u8 pwrMax,
- u8 *pPwrList,
- u8 *pVpdList,
- u16
- numIntercepts,
- u8 *pRetVpdList)
+static void ath9k_hw_init_pll(struct ath_hal *ah,
+ struct ath9k_channel *chan)
{
- 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;
- }
+ u32 pll;
- return true;
-}
+ 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);
-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;
+ 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);
- ath9k_hw_get_channel_centers(ah, chan, &centers);
+ if (chan && IS_CHAN_5GHZ(chan)) {
+ pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
- 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]));
+ 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);
}
- }
- }
- *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);
+ } else if (AR_SREV_9160_10_OR_LATER(ah)) {
- pPdGainBoundaries[i] =
- min((u16) AR5416_MAX_RATE_POWER,
- pPdGainBoundaries[i]);
+ pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
- if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
- minDelta = pPdGainBoundaries[0] - 23;
- pPdGainBoundaries[0] = 23;
- } else {
- minDelta = 0;
- }
+ 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 (i == 0) {
- if (AR_SREV_9280_10_OR_LATER(ah))
- ss = (int16_t) (0 - (minPwrT4[i] / 2));
+ if (chan && IS_CHAN_5GHZ(chan))
+ pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
else
- ss = 0;
+ pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
} 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;
+ pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
- while ((ss < maxIndex)
- && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
- pPDADCValues[k++] = vpdTableI[i][ss++];
- }
+ 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);
- 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++;
- }
+ 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);
- while (i < AR5416_PD_GAINS_IN_MASK) {
- pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
- i++;
- }
+ udelay(RTC_PLL_SETTLE_DELAY);
- while (k < AR5416_NUM_PDADC_VALUES) {
- pPDADCValues[k] = pPDADCValues[k - 1];
- k++;
- }
- return;
+ REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
}
-static bool
-ath9k_hw_set_power_cal_table(struct ath_hal *ah,
- struct ar5416_eeprom *pEepData,
- struct ath9k_channel *chan,
- int16_t *pTxPowerIndexOffset)
+static void ath9k_hw_init_chain_masks(struct ath_hal *ah)
{
- 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);
+ int rx_chainmask, tx_chainmask;
- 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;
+ rx_chainmask = ahp->ah_rxchainmask;
+ tx_chainmask = ahp->ah_txchainmask;
- 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++;
+ switch (rx_chainmask) {
+ case 0x5:
+ REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
+ AR_PHY_SWAP_ALT_CHAIN);
+ case 0x3:
+ if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
+ REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
+ REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
+ break;
}
+ case 0x1:
+ case 0x2:
+ if (!AR_SREV_9280(ah))
+ break;
+ case 0x7:
+ REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
+ REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
+ break;
+ default:
+ break;
}
- 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;
- }
- }
+ REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
+ if (tx_chainmask == 0x5) {
+ REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
+ AR_PHY_SWAP_ALT_CHAIN);
}
- *pTxPowerIndexOffset = 0;
-
- return true;
+ if (AR_SREV_9100(ah))
+ REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
+ REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
}
-void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
+static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah, enum ath9k_opmode opmode)
{
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);
+ ahp->ah_maskReg = AR_IMR_TXERR |
+ AR_IMR_TXURN |
+ AR_IMR_RXERR |
+ AR_IMR_RXORN |
+ AR_IMR_BCNMISC;
- REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
- REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
- REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
+ if (ahp->ah_intrMitigation)
+ ahp->ah_maskReg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
+ else
+ ahp->ah_maskReg |= AR_IMR_RXOK;
- if (ah->ah_config.pcie_clock_req)
- REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
- else
- REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
+ ahp->ah_maskReg |= AR_IMR_TXOK;
- REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
- REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
- REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
+ if (opmode == ATH9K_M_HOSTAP)
+ ahp->ah_maskReg |= AR_IMR_MIB;
- REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+ REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
+ REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
- 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);
+ 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);
}
+}
- REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
+static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
- if (ah->ah_config.pcie_waen) {
- REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
+ if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
+ DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad ack timeout %u\n",
+ __func__, us);
+ ahp->ah_acktimeout = (u32) -1;
+ return false;
} else {
- if (AR_SREV_9280(ah))
- REG_WRITE(ah, AR_WA, 0x0040073f);
- else
- REG_WRITE(ah, AR_WA, 0x0000073f);
+ REG_RMW_FIELD(ah, AR_TIME_OUT,
+ AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
+ ahp->ah_acktimeout = us;
+ return true;
}
}
-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)
+static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
{
- 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;
+ struct ath_hal_5416 *ahp = AH5416(ah);
- if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
- IS_CHAN_2GHZ(chan))) {
- matchIndex = 0;
+ if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
+ DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad cts timeout %u\n",
+ __func__, us);
+ ahp->ah_ctstimeout = (u32) -1;
+ return false;
} 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;
+ REG_RMW_FIELD(ah, AR_TIME_OUT,
+ AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
+ ahp->ah_ctstimeout = us;
+ return true;
}
+}
- if (matchIndex != -1) {
- *pNewPower = powInfo[matchIndex];
+static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah, u32 tu)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
+
+ if (tu > 0xFFFF) {
+ DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
+ "%s: bad global tx timeout %u\n", __func__, tu);
+ ahp->ah_globaltxtimeout = (u32) -1;
+ return false;
} 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]);
- }
+ REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
+ ahp->ah_globaltxtimeout = tu;
+ return true;
}
}
-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)
+static void ath9k_hw_init_user_settings(struct ath_hal *ah)
{
- u16 clo, chi;
- int i;
- int matchIndex = -1, lowIndex = -1;
- u16 freq;
- struct chan_centers centers;
+ struct ath_hal_5416 *ahp = AH5416(ah);
- ath9k_hw_get_channel_centers(ah, chan, &centers);
- freq = isHt40Target ? centers.synth_center : centers.ctl_center;
+ DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n",
+ __func__, ahp->ah_miscMode);
- 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 (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);
+}
- 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]);
- }
- }
+const char *ath9k_hw_probe(u16 vendorid, u16 devid)
+{
+ return vendorid == ATHEROS_VENDOR_ID ?
+ ath9k_hw_devname(devid) : NULL;
}
-static u16
-ath9k_hw_get_max_edge_power(u16 freq,
- struct cal_ctl_edges *pRdEdgesPower,
- bool is2GHz)
+void ath9k_hw_detach(struct ath_hal *ah)
{
- u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
- int i;
+ if (!AR_SREV_9100(ah))
+ ath9k_hw_ani_detach(ah);
- 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;
+ ath9k_hw_rfdetach(ah);
+ ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+ kfree(ah);
}
-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)
+struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
+ void __iomem *mem, int *error)
{
- u8 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
- static const u16 tpScaleReductionTable[5] =
- { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+ struct ath_hal *ah = NULL;
- 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);
+ 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;
+ }
- tx_chainmask = ahp->ah_txchainmask;
+ return ah;
+}
- ath9k_hw_get_channel_centers(ah, chan, &centers);
+/*******/
+/* 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;
- twiceLargestAntenna = max(
- pEepData->modalHeader
- [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
- pEepData->modalHeader
- [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
+ REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
+}
- twiceLargestAntenna = max((u8) twiceLargestAntenna,
- pEepData->modalHeader
- [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
+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);
- twiceLargestAntenna =
- (int8_t) min(AntennaReduction - twiceLargestAntenna, 0);
+ 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));
- maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+ 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");
+ }
- if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
- maxRegAllowedPower -=
- (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
+ DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+ "final ini VAL: %x\n", value);
+ }
+ break;
}
- scaledPower = min(powerLimit, maxRegAllowedPower);
+ return value;
+}
- switch (ar5416_get_ntxchains(tx_chainmask)) {
- case 1:
+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);
+ u32 modesIndex, freqIndex;
+ int status;
+
+ switch (chan->chanmode) {
+ case CHANNEL_A:
+ case CHANNEL_A_HT20:
+ modesIndex = 1;
+ freqIndex = 1;
break;
- case 2:
- scaledPower -=
- pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
- pwrDecreaseFor2Chain;
+ case CHANNEL_A_HT40PLUS:
+ case CHANNEL_A_HT40MINUS:
+ modesIndex = 2;
+ freqIndex = 1;
break;
- case 3:
- scaledPower -=
- pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
- pwrDecreaseFor3Chain;
+ case CHANNEL_G:
+ case CHANNEL_G_HT20:
+ case CHANNEL_B:
+ modesIndex = 4;
+ freqIndex = 2;
break;
+ case CHANNEL_G_HT40PLUS:
+ case CHANNEL_G_HT40MINUS:
+ modesIndex = 3;
+ freqIndex = 2;
+ break;
+
+ default:
+ return -EINVAL;
}
- 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);
+ REG_WRITE(ah, AR_PHY(0), 0x00000007);
- 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);
- }
+ REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
+
+ ath9k_hw_set_addac(ah, chan);
+
+ if (AR_SREV_5416_V22_OR_LATER(ah)) {
+ REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
} else {
+ struct ar5416IniArray temp;
+ u32 addacSize =
+ sizeof(u32) * ahp->ah_iniAddac.ia_rows *
+ ahp->ah_iniAddac.ia_columns;
- 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);
+ memcpy(ahp->ah_addac5416_21,
+ ahp->ah_iniAddac.ia_array, addacSize);
- 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);
- }
- }
+ (ahp->ah_addac5416_21)[31 * ahp->ah_iniAddac.ia_columns + 1] = 0;
- 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;
+ 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);
+ }
- if (ar5416_get_eep_ver(ahp) == 14
- && ar5416_get_eep_rev(ahp) <= 2)
- twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+ REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
- 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 < ahp->ah_iniModes.ia_rows; i++) {
+ u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
+ u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
- 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;
- }
- }
- }
+#ifdef CONFIG_SLOW_ANT_DIV
+ if (ah->ah_devid == AR9280_DEVID_PCI)
+ val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg, val);
+#endif
- minCtlPower = min(twiceMaxEdgePower, scaledPower);
+ REG_WRITE(ah, reg, val);
- 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;
+ if (reg >= 0x7800 && reg < 0x78a0
+ && ah->ah_config.analog_shiftreg) {
+ udelay(100);
}
- }
- 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];
- ;
+ DO_DELAY(regWrites);
}
- 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];
+
+ for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
+ u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
+ u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
+
+ REG_WRITE(ah, reg, val);
+
+ if (reg >= 0x7800 && reg < 0x78a0
+ && ah->ah_config.analog_shiftreg) {
+ udelay(100);
}
- }
- 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;
+ DO_DELAY(regWrites);
+ }
- memset(ratesArray, 0, sizeof(ratesArray));
+ ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
- if ((pEepData->baseEepHeader.
- version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_2) {
- ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+ if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
+ REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
+ regWrites);
}
- 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");
+ ath9k_hw_override_ini(ah, chan);
+ ath9k_hw_set_regs(ah, chan, macmode);
+ ath9k_hw_init_chain_masks(ah);
+
+ status = 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));
+ if (status != 0) {
+ DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ "%s: error init'ing transmit power\n", __func__);
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");
+ if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ "%s: ar5416SetRfRegs failed\n", __func__);
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;
- }
+ return 0;
+}
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- for (i = 0; i < Ar5416RateSize; i++)
- ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
- }
+/****************************************/
+/* Reset and Channel Switching Routines */
+/****************************************/
- 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)
- );
- }
+static void ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
+{
+ u32 rfMode = 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 (chan == NULL)
+ return;
- 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)
- );
- }
+ rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
+ ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
- REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
- ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
- | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)
- );
+ if (!AR_SREV_9280_10_OR_LATER(ah))
+ rfMode |= (IS_CHAN_5GHZ(chan)) ?
+ AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
- i = rate6mb;
- if (IS_CHAN_HT40(chan))
- i = rateHt40_0;
- else if (IS_CHAN_HT20(chan))
- i = rateHt20_0;
+ if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan))
+ rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
- if (AR_SREV_9280_10_OR_LATER(ah))
- ah->ah_maxPowerLevel =
- ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
- else
- ah->ah_maxPowerLevel = ratesArray[i];
+ REG_WRITE(ah, AR_PHY_MODE, rfMode);
+}
- return 0;
+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 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;
+ }
}
static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
@@ -4632,9 +1402,8 @@ static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
*coef_exponent = coef_exp - 16;
}
-static void
-ath9k_hw_set_delta_slope(struct ath_hal *ah,
- struct ath9k_channel *chan)
+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;
@@ -4667,8 +1436,242 @@ ath9k_hw_set_delta_slope(struct ath_hal *ah,
AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
}
-static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah,
- struct ath9k_channel *chan)
+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__);
+ return false;
+ }
+
+ 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_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
+ enum ath9k_ht_macmode macmode)
+{
+ u32 phymode;
+ struct ath_hal_5416 *ahp = AH5416(ah);
+
+ 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;
+
+ if (ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
+ phymode |= AR_PHY_FC_DYN2040_EXT_CH;
+ }
+ REG_WRITE(ah, AR_PHY_TURBO, phymode);
+
+ ath9k_hw_set11nmac2040(ah, macmode);
+
+ REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
+ REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
+}
+
+static bool ath9k_hw_chip_reset(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;
+
+ if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+ return false;
+
+ ahp->ah_chipFullSleep = false;
+
+ ath9k_hw_init_pll(ah, chan);
+
+ ath9k_hw_set_rfmode(ah, chan);
+
+ return true;
+}
+
+static struct ath9k_channel *ath9k_hw_check_chan(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;
+ }
+
+ 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 bool ath9k_hw_channel_change(struct ath_hal *ah,
+ struct ath9k_channel *chan,
+ enum ath9k_ht_macmode macmode)
+{
+ u32 synthDelay, qnum;
+
+ 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);
+ return false;
+ }
+ }
+
+ REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
+ 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__);
+ return false;
+ }
+
+ ath9k_hw_set_regs(ah, chan, macmode);
+
+ 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__);
+ return false;
+ }
+ } else {
+ if (!(ath9k_hw_set_channel(ah, chan))) {
+ DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
+ "%s: failed to set channel\n", __func__);
+ return false;
+ }
+ }
+
+ 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__);
+ 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;
+
+ udelay(synthDelay + BASE_ACTIVATE_DELAY);
+
+ 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 (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;
@@ -4918,8 +1921,7 @@ static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah,
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)
+static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan)
{
int bb_spur = AR_NO_SPUR;
int bin, cur_bin;
@@ -5120,752 +2122,11 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
}
-static void ath9k_hw_init_chain_masks(struct ath_hal *ah)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
- int rx_chainmask, tx_chainmask;
-
- rx_chainmask = ahp->ah_rxchainmask;
- tx_chainmask = ahp->ah_txchainmask;
-
- switch (rx_chainmask) {
- case 0x5:
- REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
- AR_PHY_SWAP_ALT_CHAIN);
- case 0x3:
- if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
- REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
- REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
- break;
- }
- case 0x1:
- case 0x2:
- if (!AR_SREV_9280(ah))
- break;
- case 0x7:
- REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
- REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
- break;
- default:
- break;
- }
-
- REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
- if (tx_chainmask == 0x5) {
- REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
- AR_PHY_SWAP_ALT_CHAIN);
- }
- if (AR_SREV_9100(ah))
- REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
- REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
-}
-
-static 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;
- }
-}
-
-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 u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
-{
- struct ath9k_channel *chan = ah->ah_curchan;
-
- if (chan && IS_CHAN_HT40(chan))
- return ath9k_hw_mac_usec(ah, clks) / 2;
- else
- return ath9k_hw_mac_usec(ah, clks);
-}
-
-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 bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad ack timeout %u\n",
- __func__, us);
- ahp->ah_acktimeout = (u32) -1;
- return false;
- } else {
- REG_RMW_FIELD(ah, AR_TIME_OUT,
- AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
- ahp->ah_acktimeout = us;
- return true;
- }
-}
-
-static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad cts timeout %u\n",
- __func__, us);
- ahp->ah_ctstimeout = (u32) -1;
- return false;
- } else {
- REG_RMW_FIELD(ah, AR_TIME_OUT,
- AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
- ahp->ah_ctstimeout = us;
- return true;
- }
-}
-static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah,
- u32 tu)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- if (tu > 0xFFFF) {
- DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
- "%s: bad global tx timeout %u\n", __func__, tu);
- ahp->ah_globaltxtimeout = (u32) -1;
- return false;
- } else {
- REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
- ahp->ah_globaltxtimeout = tu;
- return true;
- }
-}
-
-bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
-{
- 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;
- }
-}
-
-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);
-}
-
-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);
- u32 modesIndex, freqIndex;
- int status;
-
- switch (chan->chanmode) {
- case CHANNEL_A:
- case CHANNEL_A_HT20:
- modesIndex = 1;
- freqIndex = 1;
- break;
- case CHANNEL_A_HT40PLUS:
- case CHANNEL_A_HT40MINUS:
- modesIndex = 2;
- freqIndex = 1;
- break;
- case CHANNEL_G:
- case CHANNEL_G_HT20:
- case CHANNEL_B:
- modesIndex = 4;
- freqIndex = 2;
- break;
- case CHANNEL_G_HT40PLUS:
- case CHANNEL_G_HT40MINUS:
- modesIndex = 3;
- freqIndex = 2;
- break;
-
- default:
- return -EINVAL;
- }
-
- REG_WRITE(ah, AR_PHY(0), 0x00000007);
-
- REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
-
- ath9k_hw_set_addac(ah, chan);
-
- if (AR_SREV_5416_V22_OR_LATER(ah)) {
- REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
- } else {
- struct ar5416IniArray temp;
- u32 addacSize =
- sizeof(u32) * ahp->ah_iniAddac.ia_rows *
- ahp->ah_iniAddac.ia_columns;
-
- memcpy(ahp->ah_addac5416_21,
- ahp->ah_iniAddac.ia_array, addacSize);
-
- (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++) {
- u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
- u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
-
-#ifdef CONFIG_SLOW_ANT_DIV
- if (ah->ah_devid == AR9280_DEVID_PCI)
- val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg,
- val);
-#endif
-
- REG_WRITE(ah, reg, val);
-
- if (reg >= 0x7800 && reg < 0x78a0
- && ah->ah_config.analog_shiftreg) {
- udelay(100);
- }
-
- DO_DELAY(regWrites);
- }
-
- for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
- u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
- u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
-
- REG_WRITE(ah, reg, val);
-
- if (reg >= 0x7800 && reg < 0x78a0
- && ah->ah_config.analog_shiftreg) {
- udelay(100);
- }
-
- DO_DELAY(regWrites);
- }
-
- ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
-
- if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
- REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
- regWrites);
- }
-
- ath9k_hw_override_ini(ah, chan);
- ath9k_hw_set_regs(ah, chan, macmode);
- ath9k_hw_init_chain_masks(ah);
-
- status = 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));
- if (status != 0) {
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
- "%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__);
- return -EIO;
- }
-
- return 0;
-}
-
-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 inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
- int init_cal_count)
-{
- 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;
- }
-
- 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;
- }
- }
-
- ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
- return true;
-}
-
-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);
- return false;
- }
- }
-
- REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
- 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__);
- return false;
- }
-
- ath9k_hw_set_regs(ah, chan, macmode);
-
- 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__);
- return false;
- }
- } else {
- if (!(ath9k_hw_set_channel(ah, chan))) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "%s: failed to set channel\n", __func__);
- return false;
- }
- }
-
- 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) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "%s: error init'ing transmit power\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;
-
- udelay(synthDelay + BASE_ACTIVATE_DELAY);
-
- 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 (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 bool ath9k_hw_chip_reset(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;
-
- if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
- return false;
-
- ahp->ah_chipFullSleep = false;
-
- ath9k_hw_init_pll(ah, chan);
-
- ath9k_hw_set_rfmode(ah, chan);
-
- return true;
-}
-
-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);
- }
-}
-
-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;
- }
-}
-
-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);
-}
-
-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 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;
-}
-
-
-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,692 +2339,403 @@ 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;
-
- return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
-}
+/************************/
+/* Key Cache Management */
+/************************/
-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);
- }
- }
- }
+ keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
- if (longcal) {
- ath9k_hw_getnf(ah, ichan);
- ath9k_hw_loadnf(ah, ah->ah_curchan);
- ath9k_hw_start_nfcal(ah);
+ 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 ((ichan->channelFlags & CHANNEL_CW_INT) != 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);
- chan->channelFlags |= CHANNEL_CW_INT;
- ichan->channelFlags &= ~CHANNEL_CW_INT;
- }
}
+ if (ah->ah_curchan == NULL)
+ return true;
+
return true;
}
-static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
+bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- int i;
+ u32 macHi, macLo;
- 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]);
+ 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;
}
-}
-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]);
+ 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;
}
-static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
+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);
- 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]);
+ if (entry >= pCap->keycache_size) {
+ DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
+ "%s: entry %u out of range\n", __func__, entry);
+ return false;
}
-}
-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;
+ 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;
+ }
- for (i = 0; i < numChains; i++) {
- powerMeasI = ahp->ah_totalPowerMeasI[i];
- powerMeasQ = ahp->ah_totalPowerMeasQ[i];
- iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
+ 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;
- DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "Starting IQ Cal and Correction for Chain %d\n",
- i);
+ if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
+ u16 micentry = entry + 64;
- DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "Orignal: Chn %diq_corr_meas = 0x%08x\n",
- i, ahp->ah_totalIqCorrMeas[i]);
+ 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);
- iqCorrNeg = 0;
+ if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
+ u32 mic0, mic1, mic2, mic3, mic4;
+ 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);
- if (iqCorrMeas > 0x80000000) {
- iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
- iqCorrNeg = 1;
- }
+ } else {
+ u32 mic0, mic2;
- 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);
+ 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_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
- AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
-}
+ 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);
-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);
- }
+ (void) ath9k_hw_keysetmac(ah, entry, mac);
}
- 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);
+ if (ah->ah_curchan == NULL)
+ return true;
+
+ return true;
}
-static void
-ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
+bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
{
- 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);
+ if (entry < ah->ah_caps.keycache_size) {
+ u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
+ if (val & AR_KEYTABLE_VALID)
+ return true;
}
-
- 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);
+ return false;
}
-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;
+/******************************/
+/* Power Management (Chipset) */
+/******************************/
- 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;
-
- return true;
-}
-
-void
-ath9k_hw_get_channel_centers(struct ath_hal *ah,
- struct ath9k_channel *chan,
- struct chan_centers *centers)
+static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
{
- int8_t extoff;
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- if (!IS_CHAN_HT40(chan)) {
- centers->ctl_center = centers->ext_center =
- centers->synth_center = chan->channel;
- return;
- }
+ 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);
- 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_CLR_BIT(ah, (u16) (AR_RTC_RESET),
+ AR_RTC_RESET_EN);
}
-
- 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));
-
}
-void
-ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
- bool *isCalDone)
+static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
{
- 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;
- }
-
+ REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+ if (setChip) {
+ struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
- if (currCal->calState != CAL_DONE) {
- DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "%s: Calibration state incorrect, %d\n",
- __func__, currCal->calState);
- return;
+ 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);
+ }
}
-
-
- 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)
+static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
+ int setChip)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ u32 val;
+ int i;
- memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
-}
+ 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);
-bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
+ AR_RTC_FORCE_WAKE_EN);
+ udelay(50);
- memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
- return true;
-}
+ 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;
+ }
+ }
-void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
- memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
+ return true;
}
-bool
-ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
+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;
- memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
+ DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__,
+ modes[ahp->ah_powerMode], modes[mode],
+ setChip ? "set chip " : "");
- REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
- REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
+ 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 true;
+ return status;
}
-void
-ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
- u16 assocId)
+void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
{
struct ath_hal_5416 *ahp = AH5416(ah);
+ u8 i;
- 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));
-}
-
-u64 ath9k_hw_gettsf64(struct ath_hal *ah)
-{
- u64 tsf;
+ if (ah->ah_isPciExpress != true)
+ return;
- tsf = REG_READ(ah, AR_TSF_U32);
- tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
- return tsf;
-}
+ if (ah->ah_config.pcie_powersave_enable == 2)
+ return;
-void ath9k_hw_reset_tsf(struct ath_hal *ah)
-{
- int count;
+ if (restore)
+ return;
- 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 (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(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;
-}
+ 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);
-void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
-{
- REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
-}
+ REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
+ REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
+ REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
-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 (ah->ah_config.pcie_clock_req)
+ REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
+ else
+ REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
- if (AR_SREV_9280(ah)) {
- if (!tx_chainmask_cfg) {
+ REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+ REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+ REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
- tx_chainmask_cfg = *tx_chainmask;
- rx_chainmask_cfg = *rx_chainmask;
- }
+ REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
- 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;
- }
+ udelay(1000);
} else {
- ahp->ah_diversityControl = settings;
+ 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 true;
-}
-
-void ath9k_hw_setopmode(struct ath_hal *ah)
-{
- ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
-}
-
-bool
-ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
- u32 capability, u32 *result)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
- const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
- 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;
+ 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);
}
}
-int
-ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
-{
- 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;
-
- halNumAntConfig =
- IS_CHAN_2GHZ(chan) ? pCap->num_antcfg_2ghz : pCap->
- num_antcfg_5ghz;
-
- 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;
- }
- }
-
- return -EINVAL;
-}
+/**********************/
+/* Interrupt Handling */
+/**********************/
bool ath9k_hw_intrpend(struct ath_hal *ah)
{
@@ -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;
@@ -7154,1424 +3127,869 @@ ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
}
-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;
-}
+/***************/
+/* Rate tables */
+/***************/
-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));
+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}
+ },
+};
- 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 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}
+ },
+};
- if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
- u16 micentry = entry + 64;
+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},
- 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);
+ {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 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},
- if (ah->ah_curchan == NULL)
- return true;
+ {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},
+ },
+};
- return true;
-}
+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_keysetmac(struct ath_hal *ah, u16 entry,
- const u8 *mac)
+static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
+ struct ath9k_rate_table *rt)
{
- u32 macHi, macLo;
+ int i;
- 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 (rt->rateCodeToIndex[0] != 0)
+ return;
- 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);
+ for (i = 0; i < 256; i++)
+ rt->rateCodeToIndex[i] = (u8) -1;
- return true;
+ 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);
+ }
}
-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_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
+ u32 mode)
{
- 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_rate_table *rt;
- 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;
+ switch (mode) {
+ case ATH9K_MODE_11A:
+ rt = &ar5416_11a_table;
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;
+ case ATH9K_MODE_11B:
+ rt = &ar5416_11b_table;
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;
- }
+ case ATH9K_MODE_11G:
+ rt = &ar5416_11g_table;
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;
+ case ATH9K_MODE_11NG_HT20:
+ case ATH9K_MODE_11NG_HT40PLUS:
+ case ATH9K_MODE_11NG_HT40MINUS:
+ rt = &ar5416_11ng_table;
break;
- case ATH9K_CIPHER_CLR:
- keyType = AR_KEYTABLE_TYPE_CLR;
+ 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_KEYCACHE,
- "%s: cipher %u not supported\n", __func__,
- k->kv_type);
- return false;
+ DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n",
+ __func__, mode);
+ return NULL;
}
- 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;
+ ath9k_hw_setup_rate_table(ah, rt);
- if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
- u16 micentry = entry + 64;
+ return rt;
+}
- 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);
+/*******************/
+/* HW Capabilities */
+/*******************/
- if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
- u32 mic0, mic1, mic2, mic3, mic4;
+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;
- 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);
+ eeval = ath9k_hw_get_eeprom(ah, EEP_REG_0);
- } else {
- u32 mic0, mic2;
+ ah->ah_currentRD = eeval;
- 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);
+ eeval = ath9k_hw_get_eeprom(ah, EEP_REG_1);
+ ah->ah_currentRDExt = eeval;
- (void) ath9k_hw_keysetmac(ah, entry, mac);
- }
+ capField = ath9k_hw_get_eeprom(ah, EEP_OP_CAP);
- if (ah->ah_curchan == NULL)
- return true;
+ 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);
+ }
- return true;
-}
+ eeval = ath9k_hw_get_eeprom(ah, EEP_OP_MODE);
+ bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
-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 (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 (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
- return false;
+ 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);
+ }
+ }
+ }
- omask = ath9k_hw_set_interrupts(ah,
- ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
+ 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 {
+ pCap->rx_chainmask =
+ (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
+ }
- 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));
+ if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0)))
+ ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA;
- ath9k_hw_set_interrupts(ah, omask);
+ pCap->low_2ghz_chan = 2312;
+ pCap->high_2ghz_chan = 2732;
- ah->ah_txTrigLevel = newLevel;
+ pCap->low_5ghz_chan = 4920;
+ pCap->high_5ghz_chan = 6100;
- return newLevel != curLevel;
-}
+ pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP;
+ pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP;
+ pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM;
-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;
+ pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP;
+ pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
+ pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
- if (q >= pCap->total_queues) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
- __func__, q);
- return false;
- }
+ pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
- 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;
- }
+ if (ah->ah_config.ht_enable)
+ pCap->hw_caps |= ATH9K_HW_CAP_HT;
+ else
+ pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
+ 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;
- 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);
+ if (capField & AR_EEPROM_EEPCAP_MAXQCU)
+ pCap->total_queues =
+ MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
else
- qi->tqi_shretry = INIT_SH_RETRY;
- if (qinfo->tqi_lgretry != 0)
- qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
+ 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
- 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;
-}
+ pCap->keycache_size = AR_KEYTABLE_SIZE;
-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;
+ pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
+ pCap->num_mr_retries = 4;
+ pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
- if (q >= pCap->total_queues) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
- __func__, q);
- return false;
- }
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ pCap->num_gpio_pins = AR928X_NUM_GPIO;
+ else
+ pCap->num_gpio_pins = AR_NUM_GPIO;
- 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;
+ 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;
}
- 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;
+ 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);
+ }
- return true;
-}
+ pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
-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;
+#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);
- 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;
+ pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
}
+#endif
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, 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
+ pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
- 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;
+ 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 {
- qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
- (void) ath9k_hw_set_txq_props(ah, q, qinfo);
+ pCap->reg_cap =
+ AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
+ AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
}
- return q;
-}
+ pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
-static void
-ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
- struct ath9k_tx_queue_info *qi)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ 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);
- 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);
+ return true;
}
-bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
+bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
+ u32 capability, u32 *result)
{
struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
- struct ath9k_tx_queue_info *qi;
+ const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
- if (q >= pCap->total_queues) {
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
- __func__, q);
+ 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;
- }
- 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);
+ 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;
}
-
- 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)
+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);
- 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;
+ u32 v;
- 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);
+ 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;
- }
-
- 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;
+ 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
- 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;
+ 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:
- 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);
+ return false;
}
-
- 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;
}
-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);
-}
+/****************************/
+/* GPIO / RFKILL / Antennae */
+/****************************/
-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)
+static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
+ u32 gpio, u32 type)
{
- struct ar5416_desc *ads = AR5416DESC(ds);
+ int addr;
+ u32 gpio_shift, tmp;
- 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;
-}
+ if (gpio > 11)
+ addr = AR_GPIO_OUTPUT_MUX3;
+ else if (gpio > 5)
+ addr = AR_GPIO_OUTPUT_MUX2;
+ else
+ addr = AR_GPIO_OUTPUT_MUX1;
-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;
- }
+ gpio_shift = (gpio % 6) * 5;
- 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;
+ 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);
}
-
- 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)
+void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio)
{
- 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);
+ u32 gpio_shift;
- ads->ds_ctl6 = SM(keyType, AR_EncrType);
+ ASSERT(gpio < ah->ah_caps.num_gpio_pins);
- if (AR_SREV_9285(ah)) {
+ gpio_shift = gpio << 1;
- ads->ds_ctl8 = 0;
- ads->ds_ctl9 = 0;
- ads->ds_ctl10 = 0;
- ads->ds_ctl11 = 0;
- }
+ 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_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)
+u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
{
- 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;
- }
+ if (gpio >= ah->ah_caps.num_gpio_pins)
+ return 0xffffffff;
- ads->ds_ctl0 = ds_ctl0;
+ 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 {
- ads->ds_ctl0 =
- (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
+ return (MS(REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL) &
+ AR_GPIO_BIT(gpio)) != 0;
}
-
- 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_output(struct ath_hal *ah, u32 gpio,
+ u32 ah_signal_type)
{
- 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;
+ ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
- ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
+ gpio_shift = 2 * gpio;
- 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_ALL << gpio_shift),
+ (AR_GPIO_OE_OUT_DRV << gpio_shift));
}
-void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
+void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val)
{
- struct ar5416_desc *ads = AR5416DESC(ds);
-
- ads->ds_ctl1 |= AR_IsAggr;
- ads->ds_ctl1 &= ~AR_MoreAggr;
- ads->ds_ctl6 &= ~AR_PadDelim;
+ REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
+ AR_GPIO_BIT(gpio));
}
-void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
+#ifdef CONFIG_RFKILL
+void ath9k_enable_rfkill(struct ath_hal *ah)
{
- struct ar5416_desc *ads = AR5416DESC(ds);
+ REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+ AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
- ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
+ 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
-void
-ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
- u32 burstDuration)
+int ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
{
- struct ar5416_desc *ads = AR5416DESC(ds);
+ struct ath9k_channel *chan = ah->ah_curchan;
+ const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ u16 ant_config;
+ u32 halNumAntConfig;
- ads->ds_ctl2 &= ~AR_BurstDur;
- ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
-}
+ halNumAntConfig = IS_CHAN_2GHZ(chan) ?
+ pCap->num_antcfg_2ghz : pCap->num_antcfg_5ghz;
-void
-ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
- u32 vmf)
-{
- struct ar5416_desc *ads = AR5416DESC(ds);
+ 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;
+ }
+ }
- if (vmf)
- ads->ds_ctl0 |= AR_VirtMoreFrag;
- else
- ads->ds_ctl0 &= ~AR_VirtMoreFrag;
+ return -EINVAL;
}
-void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
+u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
{
- REG_WRITE(ah, AR_RXDP, rxdp);
+ return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
}
-void ath9k_hw_rxena(struct ath_hal *ah)
+void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
{
- REG_WRITE(ah, AR_CR, AR_CR_RXE);
+ REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
}
-bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
+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)
{
- 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;
+ struct ath_hal_5416 *ahp = AH5416(ah);
+ static u8 tx_chainmask_cfg, rx_chainmask_cfg;
- REG_CLR_BIT(ah, AR_DIAG_SW,
- (AR_DIAG_RX_DIS |
- AR_DIAG_RX_ABORT));
+ if (AR_SREV_9280(ah)) {
+ if (!tx_chainmask_cfg) {
- 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);
+ tx_chainmask_cfg = *tx_chainmask;
+ rx_chainmask_cfg = *rx_chainmask;
+ }
- return false;
+ 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 {
- REG_CLR_BIT(ah, AR_DIAG_SW,
- (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+ ahp->ah_diversityControl = settings;
}
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);
-}
+/*********************/
+/* General Operation */
+/*********************/
-bool
-ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
- u32 size, u32 flags)
+u32 ath9k_hw_getrxfilter(struct ath_hal *ah)
{
- struct ar5416_desc *ads = AR5416DESC(ds);
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ u32 bits = REG_READ(ah, AR_RX_FILTER);
+ u32 phybits = REG_READ(ah, AR_PHY_ERR);
- ads->ds_ctl1 = size & AR_BufLen;
- if (flags & ATH9K_RXDESC_INTREQ)
- ads->ds_ctl1 |= AR_RxIntrReq;
+ 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;
- ads->ds_rxstatus8 &= ~AR_RxDone;
- if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
- memset(&(ads->u), 0, sizeof(ads->u));
- return true;
+ return bits;
}
-int
-ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
- u32 pa, struct ath_desc *nds, u64 tsf)
+void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits)
{
- 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;
+ u32 phybits;
- ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
- ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
+ 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);
- 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);
+ if (phybits)
+ REG_WRITE(ah, AR_RXCFG,
+ REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
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_RXCFG,
+ REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
}
-static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
- struct ath9k_rate_table *rt)
+bool ath9k_hw_phy_disable(struct ath_hal *ah)
{
- 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;
-
- 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);
- }
+ return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
}
-const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
- u32 mode)
+bool ath9k_hw_disable(struct ath_hal *ah)
{
- 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;
-}
+ if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+ return false;
-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";
- }
- return NULL;
+ return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
}
-const char *ath9k_hw_probe(u16 vendorid, u16 devid)
+bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
{
- return vendorid == ATHEROS_VENDOR_ID ?
- ath9k_hw_devname(devid) : NULL;
-}
+ struct ath9k_channel *chan = ah->ah_curchan;
-struct ath_hal *ath9k_hw_attach(u16 devid,
- struct ath_softc *sc,
- void __iomem *mem,
- int *error)
-{
- struct ath_hal *ah = NULL;
+ ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
- 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 (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 ah;
+ return true;
}
-u16
-ath9k_hw_computetxtime(struct ath_hal *ah,
- const struct ath9k_rate_table *rates,
- u32 frameLen, u16 rateix,
- bool shortPreamble)
+void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
{
- u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
- u32 kbps;
-
- kbps = rates->info[rateix].rateKbps;
-
- if (kbps == 0)
- return 0;
- 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;
+ struct ath_hal_5416 *ahp = AH5416(ah);
- 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;
+ memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
}
-u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
+bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
{
- 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 ath_hal_5416 *ahp = AH5416(ah);
-/* We can tune this as we go by monitoring really low values */
-#define ATH9K_NF_TOO_LOW -60
+ memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
-/* 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;
}
-s16
-ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
+void ath9k_hw_setopmode(struct ath_hal *ah)
{
- 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;
+ ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
}
-bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
+void ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0, u32 filter1)
{
- 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;
- return true;
+ REG_WRITE(ah, AR_MCAST_FIL0, filter0);
+ REG_WRITE(ah, AR_MCAST_FIL1, filter1);
}
-bool ath9k_hw_phycounters(struct ath_hal *ah)
+void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
{
struct ath_hal_5416 *ahp = AH5416(ah);
- return ahp->ah_hasHwPhyCounters ? true : false;
+ memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
}
-u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
+bool ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
{
- return REG_READ(ah, AR_QTXDP(q));
-}
+ struct ath_hal_5416 *ahp = AH5416(ah);
-bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
- u32 txdp)
-{
- REG_WRITE(ah, AR_QTXDP(q), txdp);
+ memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
+
+ 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;
}
-bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
+void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, u16 assocId)
{
- DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
+ struct ath_hal_5416 *ahp = AH5416(ah);
- REG_WRITE(ah, AR_Q_TXE, 1 << q);
+ memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
+ ahp->ah_assocId = assocId;
- return true;
+ 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));
}
-u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
+u64 ath9k_hw_gettsf64(struct ath_hal *ah)
{
- u32 npend;
+ u64 tsf;
- npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
- if (npend == 0) {
+ tsf = REG_READ(ah, AR_TSF_U32);
+ tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
- if (REG_READ(ah, AR_Q_TXE) & (1 << q))
- npend = 1;
- }
- return npend;
+ return tsf;
}
-bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
+void ath9k_hw_reset_tsf(struct ath_hal *ah)
{
- u32 wait;
-
- REG_WRITE(ah, AR_Q_TXD, 1 << q);
+ int count;
- for (wait = 1000; wait != 0; wait--) {
- if (ath9k_hw_numtxpending(ah, q) == 0)
+ 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(100);
+ }
+ udelay(10);
}
+ REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
+}
- if (ath9k_hw_numtxpending(ah, q)) {
- u32 tsfLow, j;
-
- 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);
+bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
- 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);
- }
+ if (setting)
+ ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
+ else
+ ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
- REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+ return true;
+}
- udelay(200);
- REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
+bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
+{
+ struct ath_hal_5416 *ahp = AH5416(ah);
- wait = 1000;
+ 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;
+ }
+}
- 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);
- }
+void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode)
+{
+ u32 macmode;
- REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
- }
+ 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);
}
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h
index 2113818ee93..6a29f2d43c2 100644
--- a/drivers/net/wireless/ath9k/hw.h
+++ b/drivers/net/wireless/ath9k/hw.h
@@ -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
index 00000000000..c344a81e738
--- /dev/null
+++ b/drivers/net/wireless/ath9k/mac.c
@@ -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;
+ }
+}
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index f05f584ab7b..f830fe1e4ad 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -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);
diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath9k/phy.c
index eb9121fdfd3..4f1c8bf8342 100644
--- a/drivers/net/wireless/ath9k/phy.c
+++ b/drivers/net/wireless/ath9k/phy.c
@@ -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,
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
index cca2fc5b076..aa6bfd717c2 100644
--- a/drivers/net/wireless/ath9k/rc.c
+++ b/drivers/net/wireless/ath9k/rc.c
@@ -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,
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h
index b95b41508b9..6671097fad7 100644
--- a/drivers/net/wireless/ath9k/rc.h
+++ b/drivers/net/wireless/ath9k/rc.h
@@ -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,
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index 4983402af55..2ecb0a010ce 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -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);
-}
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index 3a4757942b3..8937728b030 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -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);
+}
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index ecb02bdaab5..3962b553fbf 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -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:
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 427b8203e3f..a53c378e748 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -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 */
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 098f886976f..6d65a02b705 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -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++;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 14c44df584d..ba7a5ab7fe1 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -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);
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 40159126759..1036bef8c4c 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -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);
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 2fabcf8f047..adba89b816d 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -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;
}
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index 0215faf4754..4fb2a190f7a 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -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);
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index fb6819e40f3..3649fc36709 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -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;
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index c66d57560e7..6c8eb4d2519 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -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);
diff --git a/drivers/net/wireless/b43legacy/pio.c b/drivers/net/wireless/b43legacy/pio.c
index a86c7647fa2..746d5361bba 100644
--- a/drivers/net/wireless/b43legacy/pio.c
+++ b/drivers/net/wireless/b43legacy/pio.c
@@ -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;
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index 65e83378160..12fca99f757 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -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,
diff --git a/drivers/net/wireless/b43legacy/xmit.h b/drivers/net/wireless/b43legacy/xmit.h
index e56777e0fea..62e09d02788 100644
--- a/drivers/net/wireless/b43legacy/xmit.h
+++ b/drivers/net/wireless/b43legacy/xmit.h
@@ -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/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index f106bc1585a..5f64461aa54 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -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;
}
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 921c984416f..075247188e6 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -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;
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index af3d4ef2a80..dec3dbe1bf8 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -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;
diff --git a/drivers/net/wireless/hostap/hostap_common.h b/drivers/net/wireless/hostap/hostap_common.h
index b470c743c2d..90b64b09200 100644
--- a/drivers/net/wireless/hostap/hostap_common.h
+++ b/drivers/net/wireless/hostap/hostap_common.h
@@ -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
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 3153fe9d7ce..fd7f7ceeac4 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -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);
}
diff --git a/drivers/net/wireless/hostap/hostap_info.c b/drivers/net/wireless/hostap/hostap_info.c
index 7cd3fb79230..99b4cf41edf 100644
--- a/drivers/net/wireless/hostap/hostap_info.c
+++ b/drivers/net/wireless/hostap/hostap_info.c
@@ -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);
}
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 3f8b1d7036e..2318c5df7a0 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -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;
}
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index 756ab56c1f4..4c36eb2fafd 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -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));
}
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index 3a874fc621d..8fdd41f4b4f 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -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;
diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c
index b03536008ad..ae7d3caf3da 100644
--- a/drivers/net/wireless/hostap/hostap_proc.c
+++ b/drivers/net/wireless/hostap/hostap_proc.c
@@ -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;
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
index a68f97c3935..d2c7a56b8b5 100644
--- a/drivers/net/wireless/hostap/hostap_wlan.h
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -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 */
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index bca74811bc7..062c9f28030 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -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 */
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index dcce3542d5a..051ae92d8b6 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -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)");
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 0bad1ec3e7e..0a84d52147b 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -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>
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index b0ac0ce3fb9..47bee0ee0a7 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -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
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
index 817ece77364..8772d9d7d6e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
@@ -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;
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-io.h b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
index b3fe48de3ae..1daa3f05a77 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
@@ -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.
*
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 6fc5e7361f2..bfeef701b1f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -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)
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 7ca5627cc07..af77ea70d73 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -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);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index bdd32475b99..7187925bd0d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -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"
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index f4793a60944..9da7c7bea75 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -71,7 +71,7 @@
#include "iwl-fh.h"
-/* EERPROM */
+/* EEPROM */
#define IWL4965_EEPROM_IMG_SIZE 1024
/*
@@ -111,7 +111,6 @@
#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; */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 9838de5f436..157cad4e9da 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -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,
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index c479ee211c5..12c74048a39 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -73,33 +73,34 @@
#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__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 5155b8a760a..31e62a838ad 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -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,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index e2a58e47703..0332805cc63 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -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,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index d148d73635e..adcbf538ed5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -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.
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 444c5cc05f0..35cfa1524c3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -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);
- 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));
+ 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);
+
+ 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
@@ -2343,7 +2336,7 @@ static void iwl_bg_alive_start(struct work_struct *data)
mutex_unlock(&priv->mutex);
}
-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);
@@ -2377,7 +2370,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);
@@ -2387,13 +2380,12 @@ 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);
@@ -2422,7 +2414,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);
@@ -2430,23 +2422,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);
@@ -2461,11 +2453,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) {
@@ -2473,9 +2464,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))
@@ -2491,10 +2481,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)
@@ -2527,7 +2516,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:
@@ -2539,7 +2528,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;
@@ -2576,7 +2565,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;
@@ -2598,7 +2587,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);
@@ -2613,7 +2602,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);
@@ -2621,7 +2610,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
}
}
- ret = __iwl4965_up(priv);
+ ret = __iwl_up(priv);
mutex_unlock(&priv->mutex);
@@ -2667,7 +2656,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;
@@ -2689,7 +2678,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);
@@ -2700,7 +2689,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;
@@ -2716,12 +2705,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);
@@ -2732,17 +2720,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);
@@ -2753,16 +2742,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;
@@ -2770,6 +2760,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;
@@ -2827,13 +2819,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
@@ -2861,11 +2853,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");
@@ -2876,7 +2868,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;
@@ -2885,15 +2877,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)
@@ -2926,13 +2917,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,
@@ -2940,15 +2931,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)
@@ -2964,26 +2953,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:
@@ -2996,8 +2977,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);
@@ -3028,9 +3009,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);
@@ -3039,26 +3020,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)
@@ -3077,7 +3049,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;
@@ -3089,13 +3061,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);
@@ -3104,7 +3074,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)
@@ -3131,8 +3101,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);
}
@@ -3155,7 +3124,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;
@@ -3231,7 +3200,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)
{
@@ -3240,14 +3209,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;
}
@@ -3283,12 +3251,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;
@@ -3306,8 +3273,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;
}
@@ -3355,7 +3322,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;
@@ -3403,15 +3370,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;
@@ -3436,7 +3402,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;
@@ -3471,7 +3437,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;
@@ -3483,7 +3449,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;
@@ -3527,7 +3493,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);
@@ -3550,14 +3516,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;
@@ -3594,7 +3560,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);
@@ -3748,7 +3714,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);
@@ -3789,7 +3755,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);
@@ -3864,7 +3830,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;
}
@@ -4084,12 +4050,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);
@@ -4102,10 +4068,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)
@@ -4121,7 +4087,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,
@@ -4142,39 +4108,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
@@ -4186,10 +4151,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;
@@ -4283,7 +4248,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);
/************************
@@ -4317,10 +4282,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;
@@ -4356,7 +4321,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:
@@ -4374,7 +4339,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;
@@ -4385,10 +4350,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);
@@ -4396,20 +4361,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);
@@ -4422,7 +4387,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);
@@ -4443,13 +4408,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;
}
@@ -4458,14 +4423,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;
@@ -4508,15 +4473,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;
@@ -4542,11 +4507,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);
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 72fbf47229d..25f4658f1a7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -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;
@@ -80,14 +80,16 @@
.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:
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 8d04e966ad4..8aade00e165 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -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__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 4c312c55f90..8eb02031e79 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -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,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 288b6a800e0..10f07f6e173 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -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 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 662edf4f8d2..84f56a21770 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -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)
@@ -286,4 +288,4 @@
#define HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED (0x00000004)
-
+#endif /* !__iwl_csr_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index e548d67f87f..84b7772809e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -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)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 20db0eb636a..c3df5aa8df9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -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",
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 9966d4e384c..d509aed5567 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -113,11 +113,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];
};
/**
@@ -135,12 +133,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)
@@ -253,7 +252,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
@@ -269,24 +269,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;
@@ -413,9 +405,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;
@@ -528,8 +519,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;
@@ -549,8 +540,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)
@@ -585,9 +576,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);
@@ -700,6 +691,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;
@@ -766,7 +771,6 @@ enum {
#define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */
-#define IWL_CALIB_MAX 3
struct iwl_priv {
@@ -818,12 +822,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 */
@@ -850,7 +855,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
@@ -882,7 +887,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;
@@ -908,7 +912,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 */
@@ -923,8 +927,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;
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 37155755efc..792a3c15f17 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -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);
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index d3a2a5b4ac5..997f23c8db2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -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);
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index a72efdf6d1d..97e2cf41258 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -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 */
@@ -316,34 +318,40 @@
#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)
@@ -360,7 +368,7 @@
#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)
@@ -391,3 +399,9 @@
/* 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__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 41eed679332..4f0fa215d32 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -32,108 +32,6 @@
#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
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 9740fcc1805..40e0050b753 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -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.
*
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 4eee1b163cd..ffb428a7dd6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -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",
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 60a03d2d2d0..07a5f60e922 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -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.
*/
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index ee5afd48d3a..b0ffb8919d3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -158,9 +158,9 @@
*
* 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.
*
@@ -244,7 +244,7 @@
/**
* 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
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
index 5d642298f04..618841a53b9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
@@ -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)
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 0509c16dbe7..b3c35c64d04 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -415,7 +415,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
@@ -1157,7 +1157,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",
@@ -1168,12 +1168,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.
*/
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index c89365e2ca5..c4b90301e9a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -25,8 +25,10 @@
* 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"
@@ -64,54 +66,6 @@
#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) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 61797f3f8d5..0c5f1221b8f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -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;
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 907a53ebc6e..7d8b4e2d509 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -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);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 45a6b0c3569..a3ec4d0467a 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -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;
}
@@ -6101,6 +6037,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);
@@ -6111,7 +6048,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;
@@ -6201,21 +6138,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");
@@ -6223,7 +6152,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;
@@ -6333,7 +6262,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__);
@@ -6341,9 +6269,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;
@@ -6439,7 +6366,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)
{
@@ -6452,7 +6379,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);
@@ -6604,7 +6531,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);
@@ -6615,13 +6541,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);
}
@@ -6641,10 +6568,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;
@@ -6790,8 +6718,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)
@@ -6813,23 +6739,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:
@@ -6842,8 +6758,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);
@@ -6889,15 +6805,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);
@@ -6940,8 +6847,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);
@@ -7010,6 +6915,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");
@@ -7043,7 +6949,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)
@@ -7084,10 +6990,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;
}
@@ -7219,14 +7123,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;
@@ -7792,7 +7688,7 @@ static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log);
/*****************************************************************************
*
- * driver setup and teardown
+ * driver setup and tear down
*
*****************************************************************************/
@@ -7869,7 +7765,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
@@ -7882,7 +7777,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. */
@@ -8057,7 +7951,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);
@@ -8222,7 +8116,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) {
@@ -8237,7 +8131,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:
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index 92be60415d0..a0e440cd896 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -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:
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 8265c7d25ed..957fd5a10a8 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -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);
}
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 0aa0ce3b2c4..ec4efd7ff3c 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -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++;
}
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index 1a8888ccead..0b84bdca072 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -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
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index 076a636e8f6..2d4666f2680 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -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)
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index f6f3753da30..dd682c4cfde 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -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;
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 688d60de55c..156f471217b 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -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)
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 73dc8c72402..241af7fe44b 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -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);
diff --git a/drivers/net/wireless/libertas/persistcfg.c b/drivers/net/wireless/libertas/persistcfg.c
index 3309a9c3cfe..d42b7a5a1b3 100644
--- a/drivers/net/wireless/libertas/persistcfg.c
+++ b/drivers/net/wireless/libertas/persistcfg.c
@@ -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;
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 22c4c611052..57f6c12cda2 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -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));
diff --git a/drivers/net/wireless/libertas/scan.h b/drivers/net/wireless/libertas/scan.h
index 9e07b0464a8..fab7d5d097f 100644
--- a/drivers/net/wireless/libertas/scan.h
+++ b/drivers/net/wireless/libertas/scan.h
@@ -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
*/
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index a4972fed294..dac46264117 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -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;
diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h
index e0c2599da92..fb7a2d1a252 100644
--- a/drivers/net/wireless/libertas/types.h
+++ b/drivers/net/wireless/libertas/types.h
@@ -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));
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 82c3e5a50ea..c6102e08179 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -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);
diff --git a/drivers/net/wireless/libertas_tf/cmd.c b/drivers/net/wireless/libertas_tf/cmd.c
index fdbcf8ba3e8..3d3914c83b1 100644
--- a/drivers/net/wireless/libertas_tf/cmd.c
+++ b/drivers/net/wireless/libertas_tf/cmd.c
@@ -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,
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index feff945ad85..d1fc305de5f 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -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));
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 1a019e98dac..b9230da925e 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -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);
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index a670f36b5f3..24caec6caf1 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -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/Makefile b/drivers/net/wireless/orinoco/Makefile
new file mode 100644
index 00000000000..791366e08c5
--- /dev/null
+++ b/drivers/net/wireless/orinoco/Makefile
@@ -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/airport.c b/drivers/net/wireless/orinoco/airport.c
index ce03a2e865f..ce03a2e865f 100644
--- a/drivers/net/wireless/airport.c
+++ b/drivers/net/wireless/orinoco/airport.c
diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/orinoco/hermes.c
index bfa375369df..bfa375369df 100644
--- a/drivers/net/wireless/hermes.c
+++ b/drivers/net/wireless/orinoco/hermes.c
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/orinoco/hermes.h
index 8b13c8fef3d..8b13c8fef3d 100644
--- a/drivers/net/wireless/hermes.h
+++ b/drivers/net/wireless/orinoco/hermes.h
diff --git a/drivers/net/wireless/hermes_dld.c b/drivers/net/wireless/orinoco/hermes_dld.c
index d8c626e61a3..d8c626e61a3 100644
--- a/drivers/net/wireless/hermes_dld.c
+++ b/drivers/net/wireless/orinoco/hermes_dld.c
diff --git a/drivers/net/wireless/hermes_dld.h b/drivers/net/wireless/orinoco/hermes_dld.h
index 6fcb2627799..6fcb2627799 100644
--- a/drivers/net/wireless/hermes_dld.h
+++ b/drivers/net/wireless/orinoco/hermes_dld.h
diff --git a/drivers/net/wireless/hermes_rid.h b/drivers/net/wireless/orinoco/hermes_rid.h
index 42eb67dea1d..42eb67dea1d 100644
--- a/drivers/net/wireless/hermes_rid.h
+++ b/drivers/net/wireless/orinoco/hermes_rid.h
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c
index e0512e49d6d..072be44b37d 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco/orinoco.c
@@ -86,8 +86,8 @@
#include <linux/firmware.h>
#include <linux/if_arp.h>
#include <linux/wireless.h>
+#include <linux/ieee80211.h>
#include <net/iw_handler.h>
-#include <net/ieee80211.h>
#include <linux/scatterlist.h>
#include <linux/crypto.h>
@@ -143,7 +143,7 @@ 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 ORINOCO_MAX_MTU (IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD)
#define SYMBOL_MAX_VER_LEN (14)
#define USER_BAP 0
@@ -392,7 +392,7 @@ static void orinoco_bss_data_init(struct orinoco_private *priv)
}
static inline u8 *orinoco_get_ie(u8 *data, size_t len,
- enum ieee80211_mfie eid)
+ enum ieee80211_eid eid)
{
u8 *p = data;
while ((p + 2) < (data + len)) {
@@ -409,7 +409,7 @@ 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) &&
+ if ((p[0] == WLAN_EID_GENERIC) &&
(memcmp(&p[2], WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0))
return p;
p += p[1] + 2;
@@ -487,12 +487,17 @@ orinoco_dl_firmware(struct orinoco_private *priv,
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;
+ 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;
@@ -535,7 +540,11 @@ orinoco_dl_firmware(struct orinoco_private *priv,
dev->name, hermes_present(hw));
abort:
- release_firmware(fw_entry);
+ /* In case of error, assume firmware was bogus and release it */
+ if (err) {
+ priv->cached_fw = NULL;
+ release_firmware(fw_entry);
+ }
free:
kfree(pda);
@@ -830,7 +839,8 @@ static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
return -EINVAL;
- if ( (new_mtu + ENCAPS_OVERHEAD + IEEE80211_HLEN) >
+ /* MTU + encapsulation + header length */
+ if ( (new_mtu + ENCAPS_OVERHEAD + sizeof(struct ieee80211_hdr)) >
(priv->nicbuf_size - ETH_HLEN) )
return -EINVAL;
@@ -1245,7 +1255,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
}
/* sanity check the length */
- if (datalen > IEEE80211_DATA_LEN + 12) {
+ 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++;
@@ -1280,7 +1290,6 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
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;
@@ -1374,7 +1383,7 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
data. */
goto out;
}
- if (length > IEEE80211_DATA_LEN) {
+ if (length > IEEE80211_MAX_DATA_LEN) {
printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
dev->name, length);
stats->rx_length_errors++;
@@ -1477,12 +1486,11 @@ static void orinoco_rx(struct net_device *dev,
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, "
+ "Invalid Michael MIC in data frame from %pM, "
"using key %i\n",
- dev->name, print_mac(mac, src), key_id);
+ dev->name, src, key_id);
/* TODO: update stats */
@@ -1530,7 +1538,6 @@ static void orinoco_rx(struct net_device *dev,
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)
@@ -2301,6 +2308,11 @@ int orinoco_reinit_firmware(struct net_device *dev)
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);
@@ -2926,12 +2938,6 @@ static void orinoco_reset(struct work_struct *work)
}
}
- 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",
@@ -3277,11 +3283,10 @@ static int orinoco_init(struct net_device *dev)
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;
+ priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN;
/* Initialize the firmware */
err = hermes_init(hw);
@@ -3348,8 +3353,8 @@ static int orinoco_init(struct net_device *dev)
goto out;
}
- printk(KERN_DEBUG "%s: MAC address %s\n",
- dev->name, print_mac(mac, dev->dev_addr));
+ 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,
@@ -3535,6 +3540,8 @@ struct net_device
netif_carrier_off(dev);
priv->last_linkstatus = 0xffff;
+ priv->cached_fw = NULL;
+
return dev;
}
@@ -3546,6 +3553,9 @@ void free_orinocodev(struct net_device *dev)
* 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);
@@ -4672,7 +4682,7 @@ static int orinoco_ioctl_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))
goto out;
idx--;
} else
@@ -4777,7 +4787,7 @@ static int orinoco_ioctl_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))
goto out;
idx--;
} else
@@ -4940,7 +4950,8 @@ static int orinoco_ioctl_set_genie(struct net_device *dev,
unsigned long flags;
int err = 0;
- if ((wrqu->data.length > MAX_WPA_IE_LEN) ||
+ /* cut off at IEEE80211_MAX_DATA_LEN */
+ if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) ||
(wrqu->data.length && (extra == NULL)))
return -EINVAL;
@@ -5623,7 +5634,7 @@ static inline char *orinoco_translate_ext_scan(struct net_device *dev,
&iwe, IW_EV_UINT_LEN);
}
- ie = orinoco_get_ie(bss->data, sizeof(bss->data), MFIE_TYPE_DS_SET);
+ 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 */
@@ -5673,7 +5684,7 @@ static inline char *orinoco_translate_ext_scan(struct net_device *dev,
}
/* RSN IE */
- ie = orinoco_get_ie(bss->data, sizeof(bss->data), MFIE_TYPE_RSN);
+ ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_RSN);
if (ie) {
iwe.cmd = IWEVGENIE;
iwe.u.data.length = ie[1] + 2;
@@ -5681,7 +5692,7 @@ static inline char *orinoco_translate_ext_scan(struct net_device *dev,
&iwe, ie);
}
- ie = orinoco_get_ie(bss->data, sizeof(bss->data), MFIE_TYPE_RATES);
+ 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;
@@ -5976,7 +5987,7 @@ static void orinoco_get_drvinfo(struct net_device *dev,
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,
+ strncpy(info->bus_info, dev_name(dev->dev.parent),
sizeof(info->bus_info) - 1);
else
snprintf(info->bus_info, sizeof(info->bus_info) - 1,
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index 981570bd3b9..8c295383492 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -66,6 +66,8 @@ struct orinoco_rx_data {
struct list_head list;
};
+struct firmware;
+
struct orinoco_private {
void *card; /* Pointer to card dependent structure */
struct device *dev;
@@ -164,6 +166,9 @@ struct orinoco_private {
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
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index 6fcf2bda7cd..bf6a51da3b2 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -308,7 +308,7 @@ orinoco_cs_config(struct pcmcia_device *link)
/* 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,
+ "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;
diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco/orinoco_nortel.c
index 2fc86596302..2fc86596302 100644
--- a/drivers/net/wireless/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco/orinoco_nortel.c
diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco/orinoco_pci.c
index 4ebd638a073..4ebd638a073 100644
--- a/drivers/net/wireless/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco/orinoco_pci.c
diff --git a/drivers/net/wireless/orinoco_pci.h b/drivers/net/wireless/orinoco/orinoco_pci.h
index f4e5e06760c..f4e5e06760c 100644
--- a/drivers/net/wireless/orinoco_pci.h
+++ b/drivers/net/wireless/orinoco/orinoco_pci.h
diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco/orinoco_plx.c
index ef761857bb3..ef761857bb3 100644
--- a/drivers/net/wireless/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco/orinoco_plx.c
diff --git a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco/orinoco_tmd.c
index ede24ec309c..ede24ec309c 100644
--- a/drivers/net/wireless/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco/orinoco_tmd.c
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index 852789ad34b..0bae3dcf9d5 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -383,7 +383,7 @@ spectrum_cs_config(struct pcmcia_device *link)
/* 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,
+ "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);
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index 1d0704fe146..b585ff65e0e 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -14,17 +14,17 @@
* 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);
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 827ca0384a4..1796b8c6c5b 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -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);
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
index 2fa994cfcfe..8c8793cb2d7 100644
--- a/drivers/net/wireless/p54/p54common.h
+++ b/drivers/net/wireless/p54/p54common.h
@@ -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 */
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index 88b3cad8b65..c4a868ae6d6 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -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) {
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 75d749bccb0..21ba526a45b 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -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) {
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 16e68f4b654..57a150a22de 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -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;
}
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 1404a571752..81b71f07f5a 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -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);
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 2b414899dfa..607ce9f61b5 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -37,11 +37,11 @@
#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))
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 08cb9eec16a..42bd38ac7a1 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -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,
};
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index bbff381ce39..9aefda4ab3c 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -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
/*
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index ef42cc04a2d..928452f30c2 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -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,
};
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index 8c26bef6cf4..e135247f7f8 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -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
/*
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index d3bf7bba611..639d5a2f84e 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -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,
};
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index 89e5ed24e4f..dbb5d689e23 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -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
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 1359a376840..f85eedbbad6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -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"
/*
@@ -348,13 +348,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.
*/
u8 mac[ETH_ALEN];
@@ -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);
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 4d5e87b015a..3e4eee3ab7d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -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;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 5cf4c859e39..54dd10060bf 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -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);
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.h b/drivers/net/wireless/rt2x00/rt2x00debug.h
index c4ce895aa1c..a92104dfee9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.h
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.h
@@ -28,6 +28,16 @@
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
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 86840e3585e..477a944167c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -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;
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 797eb619aa0..9f214f89ba6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -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
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 2c6cc5c374f..8fc2315c596 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -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);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index adf2876ed8a..62449da577e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -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;
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 80bf97c03e2..a83f45f784f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -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);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 451d410ecda..e9f4261054b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -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);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 9dbf04f0f04..4d3c7246f9a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -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;
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index a461620b489..3f272793412 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -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,
};
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 8ec1451308c..65fe3332364 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -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
/*
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 934f8e03c5a..767e3c98184 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -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,
};
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 868386c457f..46e1405eb0e 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -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
/*
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index df7e78ee8a8..6c226c024dd 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -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;
diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h
index e82bb4d289e..33725d0978b 100644
--- a/drivers/net/wireless/rtl8187.h
+++ b/drivers/net/wireless/rtl8187.h
@@ -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 {
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index 69eb0132593..e1399d0b55d 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -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;
diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c
index 1bae8990341..69030be62b3 100644
--- a/drivers/net/wireless/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl8187_rtl8225.c
@@ -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/strip.c b/drivers/net/wireless/strip.c
index 417e9e675fa..cf0d070ced1 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -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;
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index e939a73ff79..832679396b6 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -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;
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index e124b1d6267..de717f8ffd6 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -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 */
diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h
index 65ceb088f70..59bb3a55ab4 100644
--- a/drivers/net/wireless/wl3501.h
+++ b/drivers/net/wireless/wl3501.h
@@ -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));
/*
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 68789c6e1ce..c99a1b6b948 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -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
*/
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index b16ec6e5f0e..1134e2fb189 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -17,11 +17,11 @@
#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);
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index e0ac58b8ff1..f1519143f8a 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -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");
}
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index fe1867b25ff..07513e48b8f 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -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;
}
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index a3ccd8c1c71..04c13966696 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -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);
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index c6948d8f53f..4b21bcf4af9 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -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;
diff --git a/drivers/net/xtsonic.c b/drivers/net/xtsonic.c
index da42aa06a3b..03a3f34e903 100644
--- a/drivers/net/xtsonic.c
+++ b/drivers/net/xtsonic.c
@@ -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;
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index 57e1f495b9f..d8dbc57f3e5 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -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;
}
diff --git a/drivers/net/znet.c b/drivers/net/znet.c
index a86c022d6a9..f0b15c9347d 100644
--- a/drivers/net/znet.c
+++ b/drivers/net/znet.c
@@ -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);
diff --git a/drivers/net/zorro8390.c b/drivers/net/zorro8390.c
index 3926b2aa9cc..9c73df4a0d3 100644
--- a/drivers/net/zorro8390.c
+++ b/drivers/net/zorro8390.c
@@ -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;
}